00001 #ifndef LIBSHERPA_ENUMSET_HXX
00002 #define LIBSHERPA_ENUMSET_HXX
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <boost/utility/enable_if.hpp>
00042 #include <boost/type_traits/is_enum.hpp>
00043
00044 namespace sherpa {
00045
00067
00068 template <class T>
00069 class EnumSet {
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 typename boost::enable_if_c<boost::is_enum<T>::value, unsigned long>::type repr;
00086
00087 struct BoolConversionSupport {
00088 int dummy;
00089 };
00090
00091 public:
00092 EnumSet()
00093 :repr((T)0)
00094 {
00095 }
00096
00097 EnumSet(const EnumSet<T>& that)
00098 {
00099 repr = that.repr;
00100 }
00101
00102
00103 EnumSet(const T& that)
00104 {
00105 repr = that;
00106 }
00107
00108
00109 bool
00110 operator==(const EnumSet<T>& that) const
00111 {
00112 return (repr == that.repr);
00113 }
00114
00115 bool
00116 operator!=(const EnumSet<T>& that) const
00117 {
00118 return (repr != that.repr);
00119 }
00120
00121
00122 EnumSet<T>&
00123 operator=(const EnumSet<T>& that)
00124 {
00125 repr = that.repr;
00126 return *this;
00127 }
00128
00129 EnumSet<T>&
00130 operator |=(const EnumSet<T>& that)
00131 {
00132 repr |= that.repr;
00133 return *this;
00134 }
00135
00136 EnumSet<T>&
00137 operator &=(const EnumSet<T>& that)
00138 {
00139 repr &= that.repr;
00140 return *this;
00141 }
00142
00143 EnumSet<T>&
00144 operator ^=(const EnumSet<T>& that)
00145 {
00146 repr ^= that.repr;
00147 return *this;
00148 }
00149
00150
00151
00152
00153 EnumSet
00154 operator |(const EnumSet<T>& that) const
00155 {
00156 EnumSet b(*this);
00157 b |= that;
00158 return b;
00159 }
00160
00161 EnumSet
00162 operator &(const EnumSet<T>& that) const
00163 {
00164 EnumSet b(*this);
00165 b &= that;
00166 return b;
00167 }
00168
00169 EnumSet
00170 operator ^(const EnumSet<T>& that) const
00171 {
00172 EnumSet b(*this);
00173 b ^= that;
00174 return b;
00175 }
00176
00177
00178 EnumSet
00179 operator ~() const
00180 {
00181 EnumSet b(*this);
00182 b.repr = ~b.repr;
00183 return b;
00184 }
00185
00186 bool
00187 lacks(const EnumSet<T>& that) const
00188 {
00189 if (repr & that.repr)
00190 return false;
00191 return true;
00192 }
00193
00194 #if 0
00195
00196 EnumSet
00197 operator +(const EnumSet<T>& that) const
00198 {
00199 EnumSet b(b.repr | that.repr);
00200 return b;
00201 }
00202
00203
00204 EnumSet
00205 operator -(const EnumSet<T>& that) const
00206 {
00207 EnumSet b(b.repr & ~that.repr);
00208 return b;
00209 }
00210 #endif
00211
00212 #if 0
00213
00214 EnumSet<T>&
00215 operator +=(const EnumSet<T>& that)
00216 {
00217 *this = (repr | that.repr);
00218 return *this;
00219 }
00220
00221
00222 EnumSet<T>&
00223 operator -=(const EnumSet<T>& that)
00224 {
00225 *this = (repr & ~that.repr);
00226 return *this;
00227 }
00228 #endif
00229
00230
00231 inline operator int BoolConversionSupport::*() const
00232 {
00233 return (repr == 0) ? 0 : &BoolConversionSupport::dummy;
00234 }
00235 };
00236
00237
00238
00239 template <class T>
00240 inline EnumSet<T> operator | (const T& lhs, const EnumSet<T>& rhs)
00241 {
00242 return (rhs | EnumSet<T>(lhs));
00243 }
00244
00245 template <class T>
00246 inline EnumSet<T> operator & (const T& lhs, const EnumSet<T>& rhs)
00247 {
00248 return (rhs & EnumSet<T>(lhs));
00249 }
00250
00251 template <class T>
00252 inline EnumSet<T> operator ^ (const T& lhs, const EnumSet<T>& rhs)
00253 {
00254 return (rhs ^ EnumSet<T>(lhs));
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264 template <class T>
00265 inline
00266 typename boost::enable_if_c<boost::is_enum<T>::value, EnumSet<T> >::type
00267 operator | (const T& lhs, const T& rhs)
00268 {
00269 return (EnumSet<T>(lhs) | EnumSet<T>(rhs));
00270 }
00271
00272 template <class T>
00273 inline
00274 typename boost::enable_if_c<boost::is_enum<T>::value, EnumSet<T> >::type
00275 operator & (const T& lhs, const T& rhs)
00276 {
00277 return (EnumSet<T>(lhs) & EnumSet<T>(rhs));
00278 }
00279
00280 template <class T>
00281 inline
00282 typename boost::enable_if_c<boost::is_enum<T>::value, EnumSet<T> >::type
00283 operator ^ (const T& lhs, const T& rhs)
00284 {
00285 return (EnumSet<T>(lhs) ^ EnumSet<T>(rhs));
00286 }
00287
00288
00289 template <class T>
00290 inline
00291 typename boost::enable_if_c<boost::is_enum<T>::value, EnumSet<T> >::type
00292 operator ~(const T& lhs)
00293 {
00294 return ~EnumSet<T>(lhs);
00295 }
00296
00297 }
00298
00299 #endif