/src/contrib/boost/spirit/home/qi/auto/meta_create.hpp

http://pythonocc.googlecode.com/ · C++ Header · 260 lines · 194 code · 33 blank · 33 comment · 0 complexity · 71c5c2041cbc4bfbf5d99dd277296dfc MD5 · raw file

  1. // Copyright (c) 2001-2010 Hartmut Kaiser
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #if !defined(BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM)
  6. #define BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM
  7. #if defined(_MSC_VER)
  8. #pragma once
  9. #endif
  10. #include <boost/spirit/home/qi/domain.hpp>
  11. #include <boost/spirit/home/support/common_terminals.hpp>
  12. #include <boost/spirit/home/support/auto/meta_create.hpp>
  13. #include <boost/utility/enable_if.hpp>
  14. #include <boost/variant.hpp>
  15. #include <boost/optional.hpp>
  16. #include <boost/config.hpp>
  17. #include <boost/mpl/and.hpp>
  18. #include <boost/mpl/not.hpp>
  19. #include <boost/mpl/fold.hpp>
  20. #include <boost/mpl/vector.hpp>
  21. #include <boost/mpl/push_back.hpp>
  22. #include <boost/type_traits/is_same.hpp>
  23. #include <boost/fusion/include/as_vector.hpp>
  24. ///////////////////////////////////////////////////////////////////////////////
  25. namespace boost { namespace spirit { namespace qi
  26. {
  27. ///////////////////////////////////////////////////////////////////////////
  28. // compatible STL containers
  29. template <typename Container>
  30. struct meta_create_container
  31. {
  32. typedef make_unary_proto_expr<
  33. typename Container::value_type
  34. , proto::tag::dereference, qi::domain
  35. > make_proto_expr;
  36. typedef typename make_proto_expr::type type;
  37. static type call()
  38. {
  39. return make_proto_expr::call();
  40. }
  41. };
  42. ///////////////////////////////////////////////////////////////////////////
  43. // Fusion sequences
  44. template <typename Sequence>
  45. struct meta_create_sequence
  46. {
  47. // create a mpl sequence from the given fusion sequence
  48. typedef typename mpl::fold<
  49. typename fusion::result_of::as_vector<Sequence>::type
  50. , mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
  51. >::type sequence_type;
  52. typedef make_nary_proto_expr<
  53. sequence_type, proto::tag::shift_right, qi::domain
  54. > make_proto_expr;
  55. typedef typename make_proto_expr::type type;
  56. static type call()
  57. {
  58. return make_proto_expr::call();
  59. }
  60. };
  61. ///////////////////////////////////////////////////////////////////////////
  62. // the default is to use the standard streaming operator unless it's a
  63. // STL container or a fusion sequence
  64. // The default implementation will be chosen if no predefined mapping of
  65. // the data type T to a Qi component is defined.
  66. struct no_auto_mapping_exists {};
  67. template <typename T, typename Enable = void>
  68. struct meta_create_impl : mpl::identity<no_auto_mapping_exists> {};
  69. template <typename T>
  70. struct meta_create_impl<T
  71. , typename enable_if<mpl::and_<
  72. traits::is_container<T>, mpl::not_<traits::is_string<T> > >
  73. >::type>
  74. : meta_create_container<T> {};
  75. template <typename T>
  76. struct meta_create_impl<T
  77. , typename enable_if<fusion::traits::is_sequence<T> >::type>
  78. : meta_create_sequence<T> {};
  79. template <typename T, typename Enable = void>
  80. struct meta_create : meta_create_impl<T> {};
  81. ///////////////////////////////////////////////////////////////////////////
  82. // optional
  83. template <typename T>
  84. struct meta_create<boost::optional<T> >
  85. {
  86. typedef make_unary_proto_expr<
  87. T, proto::tag::negate, qi::domain
  88. > make_proto_expr;
  89. typedef typename make_proto_expr::type type;
  90. static type call()
  91. {
  92. return make_proto_expr::call();
  93. }
  94. };
  95. ///////////////////////////////////////////////////////////////////////////
  96. // alternatives
  97. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  98. struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  99. {
  100. typedef make_nary_proto_expr<
  101. typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
  102. , proto::tag::bitwise_or, qi::domain
  103. > make_proto_expr;
  104. typedef typename make_proto_expr::type type;
  105. static type call()
  106. {
  107. return make_proto_expr::call();
  108. }
  109. };
  110. ///////////////////////////////////////////////////////////////////////////
  111. // predefined specializations for primitive components
  112. // character generator
  113. template <>
  114. struct meta_create<char>
  115. {
  116. typedef spirit::standard::char_type type;
  117. static type const& call() { return spirit::standard::char_; }
  118. };
  119. template <>
  120. struct meta_create<wchar_t>
  121. {
  122. typedef spirit::standard_wide::char_type type;
  123. static type const& call() { return spirit::standard_wide::char_; }
  124. };
  125. // boolean generator
  126. template <>
  127. struct meta_create<bool>
  128. {
  129. typedef spirit::bool__type type;
  130. static type const& call() { return spirit::bool_; }
  131. };
  132. // integral generators
  133. template <>
  134. struct meta_create<int>
  135. {
  136. typedef spirit::int__type type;
  137. static type const& call() { return spirit::int_; }
  138. };
  139. template <>
  140. struct meta_create<short>
  141. {
  142. typedef spirit::short__type type;
  143. static type const& call() { return spirit::short_; }
  144. };
  145. template <>
  146. struct meta_create<long>
  147. {
  148. typedef spirit::long__type type;
  149. static type const& call() { return spirit::long_; }
  150. };
  151. template <>
  152. struct meta_create<unsigned int>
  153. {
  154. typedef spirit::uint__type type;
  155. static type const& call() { return spirit::uint_; }
  156. };
  157. #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
  158. template <>
  159. struct meta_create<unsigned short>
  160. {
  161. typedef spirit::ushort__type type;
  162. static type const& call() { return spirit::ushort_; }
  163. };
  164. #endif
  165. template <>
  166. struct meta_create<unsigned long>
  167. {
  168. typedef spirit::ulong__type type;
  169. static type const& call() { return spirit::ulong_; }
  170. };
  171. #ifdef BOOST_HAS_LONG_LONG
  172. template <>
  173. struct meta_create<boost::long_long_type>
  174. {
  175. typedef spirit::long_long_type type;
  176. static type const& call() { return spirit::long_long; }
  177. };
  178. template <>
  179. struct meta_create<boost::ulong_long_type>
  180. {
  181. typedef spirit::ulong_long_type type;
  182. static type const& call() { return spirit::ulong_long; }
  183. };
  184. #endif
  185. // floating point generators
  186. template <>
  187. struct meta_create<float>
  188. {
  189. typedef spirit::float__type type;
  190. static type const& call() { return spirit::float_; }
  191. };
  192. template <>
  193. struct meta_create<double>
  194. {
  195. typedef spirit::double__type type;
  196. static type const& call() { return spirit::double_; }
  197. };
  198. template <>
  199. struct meta_create<long double>
  200. {
  201. typedef spirit::long_double_type type;
  202. static type const& call() { return spirit::long_double; }
  203. };
  204. }}}
  205. ///////////////////////////////////////////////////////////////////////////////
  206. namespace boost { namespace spirit { namespace traits
  207. {
  208. ///////////////////////////////////////////////////////////////////////////
  209. // main customization point for create_parser
  210. template <typename T, typename Enable = void>
  211. struct create_parser : qi::meta_create<T> {};
  212. ///////////////////////////////////////////////////////////////////////////
  213. // dispatch this to the qi related specializations
  214. template <typename T>
  215. struct meta_create<qi::domain, T>
  216. : create_parser<typename spirit::detail::remove_const_ref<T>::type> {};
  217. ///////////////////////////////////////////////////////////////////////////
  218. // Check whether a valid mapping exits for the given data type to a Karma
  219. // component
  220. template <typename T>
  221. struct meta_create_exists<qi::domain, T>
  222. : mpl::not_<is_same<
  223. qi::no_auto_mapping_exists
  224. , typename meta_create<qi::domain, T>::type
  225. > > {};
  226. }}}
  227. #endif