builder.hpp 1.8 KB

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