metaSMT git
|
00001 #pragma once 00002 00003 #include <boost/mpl/vector.hpp> 00004 #include <boost/variant.hpp> 00005 #include <boost/concept_check.hpp> 00006 #include <boost/logic/tribool.hpp> 00007 #include <boost/dynamic_bitset.hpp> 00008 #include <boost/type_traits/is_same.hpp> 00009 #include <boost/type_traits/is_signed.hpp> 00010 #include <boost/optional.hpp> 00011 #include <boost/function.hpp> 00012 00013 00014 #include <vector> 00015 00016 namespace metaSMT { 00021 class result_wrapper { 00022 00023 // converter types 00024 struct as_vector_tribool 00025 { 00026 typedef std::vector<boost::logic::tribool > result_type; 00027 00028 result_type operator() ( result_type const & v ) const { 00029 return v; 00030 } 00031 result_type operator() ( boost::logic::tribool const & t ) const { 00032 result_type ret (1, t); 00033 return ret; 00034 } 00035 00036 result_type operator() (bool b ) const { 00037 result_type ret (1); 00038 ret[0]=b; 00039 return ret; 00040 } 00041 00042 result_type operator() ( std::vector<bool> const & vb) const { 00043 result_type ret (vb.size()); 00044 for (unsigned i = 0; i < vb.size(); ++i) { 00045 ret[i] = vb[i]; 00046 } 00047 return ret; 00048 } 00049 00050 result_type operator() ( std::string const & s ) const { 00051 unsigned size = s.size(); 00052 result_type ret(size); 00053 for (unsigned i = 0; i < size; ++i) { 00054 switch(s[size-i-1]){ 00055 case '0': 00056 ret[i] = false; break; 00057 case '1': 00058 ret[i] = true; break; 00059 default: 00060 ret[i] = boost::logic::indeterminate; 00061 } 00062 } 00063 return ret; 00064 } 00065 00066 template<typename T, typename T2> 00067 result_type operator() ( boost::dynamic_bitset<T, T2> const & t ) const { 00068 result_type ret (t.size()); 00069 for (unsigned i = 0; i < t.size(); ++i) { 00070 ret[i] = t[i]; 00071 } 00072 return ret; 00073 } 00074 00075 }; 00076 00077 struct as_tribool 00078 { 00079 typedef boost::logic::tribool result_type; 00080 00081 result_type operator() ( result_type const & v ) const { 00082 return v; 00083 } 00084 result_type operator() ( std::vector<boost::logic::tribool> const & t ) const { 00085 return t.front(); 00086 } 00087 00088 template<typename T, typename T2> 00089 result_type operator() ( boost::dynamic_bitset<T, T2> const & t ) const { 00090 return t[0]; 00091 } 00092 00093 result_type operator() (bool b ) const { 00094 return b; 00095 } 00096 00097 result_type operator() ( std::vector<bool> const & vb) const { 00098 return vb.front(); 00099 } 00100 00101 result_type operator() ( std::string const & s ) const { 00102 switch(s[0]){ 00103 case '0': 00104 return false; 00105 case '1': 00106 return true; 00107 default: 00108 return boost::logic::indeterminate; 00109 } 00110 } 00111 }; 00112 00113 00114 struct as_vector_bool 00115 { 00116 typedef std::vector<bool> result_type; 00117 00118 result_type operator() ( result_type const & v ) const 00119 { return v; } 00120 00121 result_type operator() ( boost::logic::tribool t) { 00122 result_type ret(1); 00123 ret[0] = t; 00124 return ret; 00125 } 00126 00127 result_type operator() ( bool b ) const { 00128 result_type ret(1); 00129 ret[0] = b; 00130 return ret; 00131 } 00132 00133 result_type operator() ( std::vector< boost::logic::tribool > vt ) const { 00134 result_type ret(vt.size()); 00135 for (unsigned i = 0; i < vt.size(); ++i) 00136 ret[i] = vt[i]; 00137 return ret; 00138 } 00139 00140 result_type operator() ( std::string s) const { 00141 result_type ret(s.size()); 00142 for (unsigned i = 0; i < s.size(); ++i) 00143 ret[i] = (s[s.size() - i -1] == '1'); 00144 return ret; 00145 } 00146 00147 template<typename T, typename T2> 00148 result_type operator() ( boost::dynamic_bitset<T, T2> const & t ) const { 00149 result_type ret (t.size()); 00150 for (unsigned i = 0; i < t.size(); ++i) { 00151 ret[i] = t[i]; 00152 } 00153 return ret; 00154 } 00155 }; 00156 00157 struct as_string 00158 { 00159 typedef std::string result_type; 00160 00161 result_type operator() ( result_type const & v ) const { 00162 return v; 00163 } 00164 00165 result_type operator() ( bool b ) const { 00166 return b ? "1" : "0"; 00167 } 00168 00169 result_type operator() ( boost::logic::tribool val ) const { 00170 if( boost::logic::indeterminate(val) ) { 00171 return "X"; 00172 } else { 00173 return val ? "1" : "0"; 00174 } 00175 } 00176 00177 result_type operator() ( std::vector< boost::logic::tribool > val ) const { 00178 unsigned size = val.size(); 00179 std::string s(size,'\0'); 00180 for (unsigned i = 0; i < size; ++i) { 00181 if( boost::logic::indeterminate(val[i]) ) { 00182 s[size-i-1] = 'X'; 00183 } else { 00184 s[size-i-1] = val[i] ? '1' : '0'; 00185 } 00186 } 00187 return s; 00188 } 00189 00190 result_type operator() ( std::vector< bool > val ) const { 00191 unsigned size = val.size(); 00192 std::string s(size,'\0'); 00193 for (unsigned i = 0; i < size; ++i) { 00194 s[size-i-1] = val[i] ? '1' : '0'; 00195 } 00196 return s; 00197 } 00198 00199 result_type operator() ( boost::dynamic_bitset<> const & val ) const 00200 { 00201 std::string s(val.size(), '\0'); 00202 boost::to_string(val, s); 00203 s.begin(), s.end(); 00204 return s; 00205 } 00206 00207 }; 00208 00209 template<typename Integer> 00210 struct as_integer { 00211 00212 typedef Integer result_type; 00213 typedef boost::optional< boost::function0<bool> > Rng; 00214 00215 as_integer ( Rng rng ) : _rng(rng) {} 00216 00217 result_type operator() ( bool b ) const { 00218 return b; 00219 } 00220 00221 result_type operator() ( boost::logic::tribool const & b ) const { 00222 if(_rng && boost::logic::indeterminate(b)) 00223 return random_bit(); 00224 else 00225 return b ? 1 : 0; 00226 } 00227 00228 result_type operator() ( std::vector< boost::logic::tribool > const & val ) const 00229 { 00230 Integer ret = 0; 00231 bool isSigned = boost::is_signed<Integer>::value && val.back(); 00232 if( isSigned ) ret = -1 ; 00233 for (unsigned i = 0; i < val.size(); ++i) { 00234 ret ^= Integer( ((bool)(*this)(val[i]))^isSigned ? 1 : 0) << i; 00235 } 00236 return ret; 00237 } 00238 00239 result_type operator() ( std::vector< bool > const & val ) const 00240 { 00241 Integer ret = 0; 00242 bool isSigned = boost::is_signed<Integer>::value && val.back(); 00243 if( isSigned ) ret = -1 ; 00244 for (unsigned i = 0; i < val.size(); ++i) { 00245 ret ^= Integer( val[i]^isSigned ? 1 : 0) << i; 00246 } 00247 return ret; 00248 } 00249 00250 result_type operator() ( std::string const & val ) const 00251 { 00252 Integer ret = 0; 00253 if( boost::is_signed<Integer>::value && val[0] == '1' ) ret = -1; 00254 for (std::string::const_iterator ite = val.begin(); ite != val.end(); ++ite) 00255 { 00256 ret <<=1; 00257 switch ( *ite ) { 00258 case '0': 00259 break; 00260 case '1': 00261 ret |= Integer(1); 00262 break; 00263 default: 00264 ret |= Integer( _rng && random_bit()); 00265 } 00266 } 00267 return ret; 00268 } 00269 00270 result_type operator() ( boost::dynamic_bitset<> const & val ) const 00271 { 00272 const bool issigned = boost::is_signed<Integer>::value; 00273 if( !issigned && sizeof(Integer) <= sizeof(unsigned long) ) { 00274 return static_cast<result_type>( val.to_ulong() ); 00275 } else { 00276 Integer ret = 0; 00277 bool isSigned = boost::is_signed<Integer>::value && val[val.size()-1]; 00278 if( isSigned ) ret = -1 ; 00279 for (unsigned i = 0; i < val.size(); ++i) { 00280 ret ^= Integer( val[i]^isSigned ? 1 : 0) << i; 00281 } 00282 return ret; 00283 } 00284 } 00285 00286 bool random_bit() const { 00287 return (*_rng)(); 00288 } 00289 Rng _rng; 00290 }; 00291 00292 struct check_if_X 00293 { 00294 typedef bool result_type; 00295 00296 template<typename T> 00297 result_type operator() ( T const & v ) const { 00298 return false; 00299 } 00300 00301 result_type operator() ( boost::logic::tribool val ) const { 00302 return boost::logic::indeterminate(val); 00303 } 00304 00305 result_type operator() ( std::vector< boost::logic::tribool > val ) const { 00306 unsigned size = val.size(); 00307 for (unsigned i = 0; i < size; ++i) { 00308 if( boost::logic::indeterminate(val[i]) ) 00309 return true; 00310 } 00311 return false; 00312 } 00313 00314 result_type operator() ( std::string val ) const { 00315 unsigned size = val.size(); 00316 for (unsigned i = 0; i < size; ++i) { 00317 if( val[i] == 'x' || val[i] == 'X' ) 00318 return true; 00319 } 00320 return false; 00321 } 00322 }; 00323 00324 public: 00325 typedef boost::mpl::vector< 00326 bool 00327 , std::vector<boost::logic::tribool> 00328 , std::vector<bool> 00329 , std::string 00330 , boost::logic::tribool 00331 , boost::dynamic_bitset<> 00332 > result_types_list; 00333 typedef boost::make_variant_over<result_types_list>::type result_type; 00334 00335 public: 00336 result_wrapper() : r ("x") { } 00337 result_wrapper( result_type r ) : r (r) { } 00338 result_wrapper( boost::logic::tribool t ) : r (t) { } 00339 result_wrapper( bool b ) : r (boost::logic::tribool(b)) { } 00340 result_wrapper( const char* s ) : r (std::string(s)) { } 00341 result_wrapper( const char c ) 00342 : r (c=='1' ? boost::logic::tribool(true) 00343 : (c=='0' ? boost::logic::tribool(false) 00344 : boost::logic::tribool(boost::logic::indeterminate)) 00345 ) 00346 { } 00347 result_wrapper( unsigned value, unsigned width ) 00348 : r( boost::dynamic_bitset<>(width, value) ) 00349 { } 00350 00351 operator std::vector<bool> () const { 00352 return boost::apply_visitor(as_vector_bool(), r); 00353 } 00354 00355 operator std::vector<boost::logic::tribool> () const { 00356 return boost::apply_visitor(as_vector_tribool(), r); 00357 } 00358 00359 operator std::string () const { 00360 return boost::apply_visitor(as_string(), r); 00361 } 00362 00363 operator boost::dynamic_bitset<> () const { 00364 std::vector<boost::logic::tribool> val = *this; 00365 boost::dynamic_bitset<> ret(val.size()); 00366 for (unsigned i = 0; i < val.size(); ++i) { 00367 ret[i]=val[i]; 00368 } 00369 return ret; 00370 } 00371 00372 result_wrapper & throw_if_X() { 00373 if ( boost::apply_visitor( check_if_X(), r) ) { 00374 throw std::string("contains X"); 00375 } 00376 return *this; 00377 } 00378 00379 typedef boost::optional< boost::function0<bool> > Rng; 00380 00381 result_wrapper & randX( Rng rng = Rng() ) { 00382 _rng=rng; 00383 return *this; 00384 } 00385 00386 template< typename Integer> 00387 operator Integer () const { 00388 //BOOST_CONCEPT_ASSERT(( boost::Integer<Integer> )); 00389 return boost::apply_visitor(as_integer<Integer>(_rng), r); 00390 } 00391 00392 operator boost::logic::tribool () const { 00393 return boost::apply_visitor(as_tribool(), r); 00394 } 00395 00396 friend std::ostream & 00397 operator<< (std::ostream & out, result_wrapper const & rw) { 00398 std::string o = rw; 00399 out << o ; 00400 return out; 00401 } 00402 00403 00404 protected: 00405 result_type r; 00406 Rng _rng; 00407 }; 00408 00409 } // namespace metaSMT 00410 00411 // vim: ft=cpp:ts=2:sw=2:expandtab