metaSMT 2
metaSMT/API/Stack.hpp
Go to the documentation of this file.
00001 #pragma once
00002 
00003 #include "../impl/_var_id.hpp"
00004 #include "../tags/Logic.hpp"
00005 #include "../Features.hpp"
00006 
00007 #include <cstdio>
00008 #include <vector>
00009 #include <list>
00010 
00011 #include <boost/any.hpp>
00012 #include <boost/foreach.hpp>
00013 #include <boost/tr1/unordered_map.hpp>
00014 #include <boost/mpl/assert.hpp>
00015 
00016 namespace metaSMT {
00017 
00018   namespace features {
00019     struct stack_api {};
00020   } /* features */
00021 
00022   struct stack_push { typedef void result_type; };
00023   struct stack_pop { typedef void result_type; };
00024 
00052   template<typename Context>
00053   struct Stack_emulation : public Context
00054   {
00055     typedef typename Context::result_type result_type;
00056 
00057     void assertion ( result_type const& e )
00058     {
00059       if ( stack_.empty() ) {
00060         Context::assertion( e );
00061       } else {
00062         stack_.back().push_back( e );
00063       }
00064     }
00065 
00066     bool solve ( )
00067     {
00068       BOOST_FOREACH ( stack_level const & se, stack_)
00069       {
00070         BOOST_FOREACH( result_type const & r, se)
00071         {
00072           Context::assumption ( r );
00073         }
00074       }
00075       return Context::solve () ;
00076     }
00077 
00078     void command ( stack_push const &, unsigned howmany) {
00079       while (howmany > 0) {
00080         stack_.push_back( stack_level() );
00081         --howmany;
00082       }
00083     }
00084 
00085     void command ( stack_pop const &, unsigned howmany) {
00086       while (howmany > 0) {
00087         stack_.pop_back();
00088         --howmany;
00089       }
00090     }
00091 
00092     using Context::command;
00093 
00094 
00095     private:
00096       typedef std::list<result_type> stack_level;
00097       std::vector< stack_level> stack_;
00098 
00099   };
00100 
00101 
00102   template< typename Context >
00103   struct Stack
00104   : boost::mpl::if_< features::supports< Context, features::stack_api>
00105     , Context
00106     , Stack_emulation< Context >
00107   >::type {};
00108 
00109   namespace features {
00110     /* Stack supports stack api */
00111     template<typename Context>
00112     struct supports< Stack<Context>, features::stack_api>
00113     : boost::mpl::true_ {};
00114 
00115     /* Forward all other supported operations */
00116     template<typename Context, typename Feature>
00117     struct supports< Stack<Context>, Feature>
00118     : supports<Context, Feature>::type {};
00119   }
00120 
00128   template <typename Context >
00129   typename boost::enable_if< features::supports<Context, features::stack_api> >::type
00130   push( Context & ctx, unsigned howmany=1) {
00131     ctx.command(stack_push(), howmany);
00132   }
00133 
00141   template <typename Context >
00142   typename boost::enable_if< features::supports<Context, features::stack_api> >::type
00143   pop( Context & ctx, unsigned howmany=1) {
00144     ctx.command(stack_pop(), howmany);
00145   }
00146 
00148   /* error if unsupported **/
00149   template <typename Context >
00150   typename boost::disable_if< features::supports<Context, features::stack_api> >::type
00151   push( Context & ctx, unsigned howmany=1) {
00152     BOOST_MPL_ASSERT_MSG(( features::supports<Context, features::stack_api>::value ),
00153         context_does_not_support_push_stack_api, );
00154   }
00155 
00156   template <typename Context >
00157   typename boost::disable_if< features::supports<Context, features::stack_api> >::type
00158   pop( Context & ctx, unsigned howmany=1 ) {
00159     BOOST_MPL_ASSERT_MSG(( features::supports<Context, features::stack_api>::value ),
00160         context_does_not_support_pop_stack_api, (Context) );
00161   }
00166 } /* metaSMT */
00167 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines