• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef META_HS_EXCEPT_BUILDER_HPP
2 #define META_HS_EXCEPT_BUILDER_HPP
3 
4 // Copyright Abel Sinkovics (abel@sinkovics.hu)  2012.
5 // Distributed under the Boost Software License, Version 1.0.
6 //    (See accompanying file LICENSE_1_0.txt or copy at
7 //          http://www.boost.org/LICENSE_1_0.txt)
8 
9 #include <grammar.hpp>
10 #include <ast.hpp>
11 #include <bind.hpp>
12 #include <curry.hpp>
13 
14 #include <boost/mpl/map.hpp>
15 #include <boost/mpl/insert.hpp>
16 #include <boost/mpl/at.hpp>
17 #include <boost/mpl/pair.hpp>
18 #include <boost/mpl/apply_wrap.hpp>
19 
20 #include <boost/preprocessor/repetition/enum.hpp>
21 #include <boost/preprocessor/cat.hpp>
22 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
23 #include <boost/preprocessor/tuple/eat.hpp>
24 
25 typedef boost::mpl::map<> empty_environment;
26 
27 template <class Env = empty_environment>
28 struct builder
29 {
30   typedef builder type;
31 
32   template <class Name, class Value>
33   struct import :
34     builder<
35       typename boost::mpl::insert<
36         Env,
37         boost::mpl::pair<Name, ast::value<Value> >
38       >::type
39     >
40   {};
41 
42 #ifdef IMPORT
43 #  error IMPORT already defined
44 #endif
45 #define IMPORT(z, n, unused) \
46   template < \
47     class Name, \
48     template <BOOST_PP_ENUM(n, class BOOST_PP_TUPLE_EAT(3), ~)> class F \
49   > \
50   struct BOOST_PP_CAT(import, n) : \
51     builder< \
52       typename boost::mpl::insert< \
53         Env, \
54         boost::mpl::pair<Name, ast::value<BOOST_PP_CAT(curry, n)<F> > > \
55       >::type \
56     > \
57   {};
58 
59 BOOST_PP_REPEAT_FROM_TO(1, CURRY_MAX_ARGUMENT, IMPORT, ~)
60 
61 #undef IMPORT
62 
63   template <class S>
64   struct define :
65     builder<
66       typename boost::mpl::insert<
67         Env,
68         typename boost::mpl::apply_wrap1<grammar::def_parser, S>::type
69       >::type
70     >
71   {};
72 
73   template <class S>
74   struct get :
75     bind<typename boost::mpl::at<Env, S>::type, Env, Env>::type::type
76   {};
77 };
78 
79 #endif
80 
81