metaSMT 2
metaSMT/result_wrapper.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines