1 // flags.hpp 2 // 3 // Copyright (c) 2004 Eugene Gladyshev 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 11 #ifndef __ttl_flg_flags__hpp 12 #define __ttl_flg_flags__hpp 13 14 #include <algorithm> 15 16 namespace ttl 17 { 18 namespace flg 19 { 20 namespace impl 21 { 22 template< 23 int Bits, 24 int type = Bits <= sizeof(char)*8?1:(Bits <= sizeof(short)*8?2:(Bits <= sizeof(int)*8?3:4)) 25 > struct bestfit; 26 27 template< int Bits > 28 struct bestfit<Bits, 1> 29 { 30 typedef unsigned char type; 31 }; 32 33 template< int Bits > 34 struct bestfit<Bits, 2> 35 { 36 typedef unsigned short type; 37 }; 38 39 template< int Bits > 40 struct bestfit<Bits, 3> 41 { 42 typedef unsigned int type; 43 }; 44 45 template< int Bits > 46 struct bestfit<Bits, 4> 47 { 48 typedef unsigned int type; 49 }; 50 }; 51 52 template< typename T, int Bits = sizeof(int)*8, typename Holder = typename impl::bestfit<Bits>::type > 53 struct flags 54 { 55 typedef flags this_t; 56 typedef T value_type; 57 58 Holder f_; 59 flagsttl::flg::flags60 flags() : f_(0) {} flagsttl::flg::flags61 flags( T f1 ) : f_(f1) {} flagsttl::flg::flags62 flags( T f1, T f2 ) : f_(f1|f2) {} flagsttl::flg::flags63 flags( T f1, T f2, T f3 ) : f_(f1|f2|f3) {} flagsttl::flg::flags64 flags( T f1, T f2, T f3, T f4 ) : f_(f1|f2|f3|f4) {} flagsttl::flg::flags65 flags( T f1, T f2, T f3, T f4, T f5 ) : f_(f1|f2|f3|f4|f5) {} flagsttl::flg::flags66 flags( T f1, T f2, T f3, T f4, T f5, T f6 ) : f_(f1|f2|f3|f4|f5|f6) {} flagsttl::flg::flags67 flags( T f1, T f2, T f3, T f4, T f5, T f6, T f7 ) : f_(f1|f2|f3|f4|f5|f6|f7) {} flagsttl::flg::flags68 flags( T f1, T f2, T f3, T f4, T f5, T f6, T f7, T f8 ) : f_(f1|f2|f3|f4|f5|f6|f7|f8) {} flagsttl::flg::flags69 flags( T f1, T f2, T f3, T f4, T f5, T f6, T f7, T f8, T f9 ) : f_(f1|f2|f3|f4|f5|f6|f7|f8|f9) {} flagsttl::flg::flags70 flags( T f1, T f2, T f3, T f4, T f5, T f6, T f7, T f8, T f9, T f10 ) : f_(f1|f2|f3|f4|f5|f6|f7|f8|f9|f10) {} 71 operator |=ttl::flg::flags72 this_t& operator |=( const this_t& f ) { f_ |= f.f_; return *this; } operator &=ttl::flg::flags73 this_t& operator &=( const this_t& f ) { f_ &= f.f_; return *this; } 74 operator ==ttl::flg::flags75 bool operator ==( const this_t& l ) const { return f_ == l.f_; } operator !=ttl::flg::flags76 bool operator !=( const this_t& l ) const { return f_ != l.f_; } 77 operator !ttl::flg::flags78 bool operator !() { return f_ == 0; } 79 get_holderttl::flg::flags80 Holder get_holder() const { return f_; } 81 testttl::flg::flags82 bool test( const this_t l ) const { return (f_ & l.f_)?true:false; } testttl::flg::flags83 bool test() const { return f_!=0; } 84 }; 85 86 template< typename T, int Bits, typename Holder > operator ~(const flags<T,Bits,Holder> & l)87 flags<T, Bits, Holder> operator ~(const flags<T, Bits, Holder>& l) 88 { 89 flags<T, Bits, Holder> tmp; 90 tmp.f_ = ~l.f_; 91 return tmp; 92 } 93 94 template< typename T, int Bits, typename Holder > operator |(const flags<T,Bits,Holder> & l,const T & r)95 flags<T, Bits, Holder> operator |(const flags<T, Bits, Holder>& l, const T& r) 96 { 97 flags<T, Bits, Holder> tmp( r ); 98 return l|tmp; 99 } 100 101 template< typename T, int Bits, typename Holder > operator |(const flags<T,Bits,Holder> & l,const flags<T,Bits,Holder> & r)102 flags<T, Bits, Holder> operator |(const flags<T, Bits, Holder>& l, const flags<T, Bits, Holder>& r) 103 { 104 flags<T, Bits, Holder> tmp( l ); 105 tmp|=r; 106 return tmp; 107 } 108 109 template< typename T, int Bits, typename Holder > operator &(const flags<T,Bits,Holder> & l,const T & r)110 flags<T, Bits, Holder> operator &(const flags<T, Bits, Holder>& l, const T& r) 111 { 112 flags<T, Bits, Holder> tmp( r ); 113 return l&tmp; 114 } 115 116 template< typename T, int Bits, typename Holder > operator &(const flags<T,Bits,Holder> & l,const flags<T,Bits,Holder> & r)117 flags<T, Bits, Holder> operator &(const flags<T, Bits, Holder>& l, const flags<T, Bits, Holder>& r) 118 { 119 flags<T, Bits, Holder> tmp( l ); 120 tmp&=r; 121 return tmp; 122 } 123 124 struct map_first2second {}; 125 struct map_second2first {}; 126 127 template < typename Pair, typename MapDirection = map_first2second > 128 struct flag_mapper; 129 130 template< typename Pair > 131 struct flag_mapper<Pair, map_first2second> 132 { 133 typedef typename Pair::first_type type; 134 typedef typename Pair::second_type result_type; 135 136 const type& d_; 137 result_type& r_; 138 flag_mapperttl::flg::flag_mapper139 flag_mapper( const type& d, result_type& r ) : d_(d), r_(r) {} 140 operator ()ttl::flg::flag_mapper141 void operator()( const Pair& p ) const 142 { 143 if( (p.first&d_) == true ) r_ |= p.second; 144 } 145 }; 146 147 template< typename Pair > 148 struct flag_mapper<Pair, map_second2first> 149 { 150 typedef typename Pair::second_type type; 151 typedef typename Pair::first_type result_type; 152 153 const type& d_; 154 result_type r_; 155 flag_mapperttl::flg::flag_mapper156 flag_mapper( const type& d ) : d_(d), r_() {} 157 operator ()ttl::flg::flag_mapper158 void operator()( const Pair& p ) const 159 { 160 if( (p.second&d_) == true ) r_ |= p.first; 161 } 162 }; 163 164 //It is a an iterator of elements like std::pair 165 template< typename It > map(const typename It::value_type::first_type f,It first,It end)166 typename It::value_type::second_type map( 167 const typename It::value_type::first_type f, 168 It first, It end ) 169 { 170 typename It::value_type::second_type r; 171 flag_mapper<typename It::value_type> m(f, r); 172 std::for_each( first, end, m ); 173 return r; 174 } 175 176 }; //flg 177 }; 178 179 #endif //__flags__hpp 180 181