00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00028 #ifndef __EnumBitArray
00029 #define __EnumBitArray
00030
00031 #ifdef __GNUC__
00032 #pragma interface
00033 #endif
00034
00035 #ifdef NON_ANSI
00036 #include <iostream.h>
00037 #else
00038 #include <iostream>
00039 using namespace std;
00040 #endif
00041 #ifndef ANSI_HDRS
00042 #include <math.h>
00043 #else
00044 #include <cmath>
00045 #endif
00046 #include "BitArrayBase.h"
00047
00048
00049 #define BYTESIZE 8
00050
00063 #if !defined(EnumBitArraySanityChecking)
00064 #define EnumBitArraySanityChecking 1
00065 #endif
00066
00067
00068 template <class T>
00069 class UTILIB_API EnumBitArray : public BitArrayBase {
00070
00071 public:
00072
00074 EnumBitArray() : BitArrayBase() {}
00076 EnumBitArray(const size_type len, const size_type nbytes=0, char* d=(char*)0,
00077 const EnumDataOwned o=DataNotOwned)
00078 {construct(len,
00079 (nbytes==0 ? (len+BYTESIZE-1)/(BYTESIZE/element_size())
00080 : nbytes),
00081 d,o); }
00083 EnumBitArray(const EnumBitArray& array)
00084 : BitArrayBase(array) {}
00085
00087 T operator()(const size_type idx) const;
00089 void put(const size_type idx, const T val);
00091 EnumBitArray<T>& operator=(const T value);
00092
00094 int write(ostream& input) const;
00096 int read(istream& input);
00097
00098 protected:
00099
00101 int operator[](const size_type idx) const;
00103 void put(const size_type , const int ) {}
00105 int element_size() const
00106 {return enum_count;}
00107
00109 static int enum_count;
00111 static char enum_labels[];
00113 static T enum_vals[];
00114
00115 };
00116
00117
00118 template <class T>
00119 inline int EnumBitArray<T>::operator[](const size_type idx) const
00120 {
00121 #if (EnumBitArraySanityChecking==1)
00122 if (idx >= array_len)
00123 ErrAbort(errmsg("EnumBitArray<T>::operator() : iterator out of range. idx=%d len=%d",idx,array_len));
00124 #endif
00125
00126 unsigned char X = Data[(2*idx)/BYTESIZE];
00127 size_type i = 2*idx;
00128 unsigned char val = (X & (char)(3 << (i & (BYTESIZE - 1))));
00129 val = val >> (i & (BYTESIZE - 1));
00130
00131 return (int)val;
00132 }
00133
00134
00135 template <class T>
00136 inline T EnumBitArray<T>::operator()(const size_type idx) const
00137 { return (T) operator[](idx); }
00138
00139
00140 template <class T>
00141 inline void EnumBitArray<T>::put(const size_type idx, const T val)
00142 {
00143 #if (EnumBitArraySanityChecking==1)
00144 if (idx >= array_len)
00145 ErrAbort(errmsg("EnumBitArray<T>::put : iterator out of range. idx=%d len=%d",idx,array_len));
00146 #endif
00147
00148 int tval = (int)val;
00149 unsigned char X = Data[(2*idx)/BYTESIZE];
00150 size_type i = 2*idx;
00151 unsigned char qwerty = (3 << (i & (BYTESIZE - 1)));
00152 unsigned char qwertydata = X & qwerty;
00153 X ^= qwertydata;
00154 X |= ((tval & 3) << (i & (BYTESIZE - 1)));
00155 Data[(2*idx)/BYTESIZE] = X;
00156 }
00157
00158
00159
00160
00161
00162 template <class T>
00163 int EnumBitArray<T>::read(istream& s)
00164 {
00165 size_type i;
00166 char c;
00167
00168 if (Data) {
00169 for (i=0; i<array_len; i++) {
00170 s.get(c);
00171 while (s && ((c == ' ') || (c == '\t') || (c == '\n')))
00172 s.get(c);
00173 int j;
00174 for (j=0; j<element_size(); j++)
00175 if (c == enum_labels[j]) break;
00176 if (j<element_size())
00177 put(i,enum_vals[j]);
00178 else {
00179 ErrAbort(errmsg("TwoBitArray::read : Bad input value: %c.",c));
00180 break;
00181 }
00182 }
00183 }
00184
00185 else
00186 ErrAbort( "TwoBitArray::read: size and sparseity not known" );
00187
00188 return OK ;
00189 }
00190
00191
00192
00193 template <class T>
00194 int EnumBitArray<T>::write(ostream& s) const
00195 {
00196 s << array_len << ": ";
00197 if (Data) {
00198 for (size_type i=0; i<array_len; i++)
00199 s << enum_labels[(int)(operator()(i))];
00200 }
00201
00202 return OK ;
00203 }
00204
00205
00206 template <class T>
00207 EnumBitArray<T>& EnumBitArray<T>::operator=(const T val)
00208 {
00209 BitArrayBase::operator=((int)val);
00210 return *this;
00211 }
00212
00213 #endif