attributes.hpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2012 Hartmut Kaiser
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #if !defined(BOOST_SPIRIT_ATTRIBUTES_JANUARY_29_2007_0954AM)
  8. #define BOOST_SPIRIT_ATTRIBUTES_JANUARY_29_2007_0954AM
  9. #if defined(_MSC_VER)
  10. #pragma once
  11. #endif
  12. #include <boost/spirit/home/support/unused.hpp>
  13. #include <boost/spirit/home/support/has_semantic_action.hpp>
  14. #include <boost/spirit/home/support/attributes_fwd.hpp>
  15. #include <boost/spirit/home/support/container.hpp>
  16. #include <boost/spirit/home/support/detail/hold_any.hpp>
  17. #include <boost/spirit/home/support/detail/as_variant.hpp>
  18. #include <boost/optional/optional.hpp>
  19. #include <boost/fusion/include/transform.hpp>
  20. #include <boost/fusion/include/filter_if.hpp>
  21. #include <boost/fusion/include/as_vector.hpp>
  22. #include <boost/fusion/include/push_front.hpp>
  23. #include <boost/fusion/include/pop_front.hpp>
  24. #include <boost/fusion/include/is_sequence.hpp>
  25. #include <boost/fusion/include/for_each.hpp>
  26. #include <boost/fusion/include/is_view.hpp>
  27. #include <boost/fusion/include/mpl.hpp>
  28. #include <boost/utility/value_init.hpp>
  29. #include <boost/type_traits/is_same.hpp>
  30. #include <boost/type_traits/is_convertible.hpp>
  31. #include <boost/mpl/eval_if.hpp>
  32. #include <boost/mpl/end.hpp>
  33. #include <boost/mpl/find_if.hpp>
  34. #include <boost/mpl/identity.hpp>
  35. #include <boost/mpl/deref.hpp>
  36. #include <boost/mpl/distance.hpp>
  37. #include <boost/mpl/or.hpp>
  38. #include <boost/mpl/has_xxx.hpp>
  39. #include <boost/mpl/equal.hpp>
  40. #include <boost/proto/proto_fwd.hpp>
  41. #include <boost/utility/enable_if.hpp>
  42. #include <boost/variant.hpp>
  43. #include <boost/range/iterator_range.hpp>
  44. #include <boost/config.hpp>
  45. #include <vector>
  46. #include <utility>
  47. #include <ios>
  48. ///////////////////////////////////////////////////////////////////////////////
  49. namespace boost { namespace spirit { namespace traits
  50. {
  51. ///////////////////////////////////////////////////////////////////////////
  52. // This file deals with attribute related functions and meta-functions
  53. // including generalized attribute transformation utilities for Spirit
  54. // components.
  55. ///////////////////////////////////////////////////////////////////////////
  56. ///////////////////////////////////////////////////////////////////////////
  57. // Find out if T can be a (strong) substitute for Expected attribute
  58. namespace detail
  59. {
  60. template <typename T, typename Expected>
  61. struct value_type_is_substitute
  62. : is_substitute<
  63. typename container_value<T>::type
  64. , typename container_value<Expected>::type>
  65. {};
  66. template <typename T, typename Expected, typename Enable = void>
  67. struct is_substitute_impl : is_same<T, Expected> {};
  68. template <typename T, typename Expected>
  69. struct is_substitute_impl<T, Expected,
  70. typename enable_if<
  71. mpl::and_<
  72. fusion::traits::is_sequence<T>,
  73. fusion::traits::is_sequence<Expected>,
  74. mpl::equal<T, Expected, is_substitute<mpl::_1, mpl::_2> >
  75. >
  76. >::type>
  77. : mpl::true_ {};
  78. template <typename T, typename Expected>
  79. struct is_substitute_impl<T, Expected,
  80. typename enable_if<
  81. mpl::and_<
  82. is_container<T>,
  83. is_container<Expected>,
  84. detail::value_type_is_substitute<T, Expected>
  85. >
  86. >::type>
  87. : mpl::true_ {};
  88. }
  89. template <typename T, typename Expected, typename Enable /*= void*/>
  90. struct is_substitute
  91. : detail::is_substitute_impl<T, Expected> {};
  92. template <typename T, typename Expected>
  93. struct is_substitute<optional<T>, optional<Expected> >
  94. : is_substitute<T, Expected> {};
  95. template <typename T>
  96. struct is_substitute<T, T
  97. , typename enable_if<not_is_optional<T> >::type>
  98. : mpl::true_ {};
  99. ///////////////////////////////////////////////////////////////////////////
  100. // Find out if T can be a weak substitute for Expected attribute
  101. namespace detail
  102. {
  103. // A type, which is convertible to the attribute is at the same time
  104. // usable as its weak substitute.
  105. template <typename T, typename Expected, typename Enable = void>
  106. struct is_weak_substitute_impl : is_convertible<T, Expected> {};
  107. // // An exposed attribute is a weak substitute for a supplied container
  108. // // attribute if it is a weak substitute for its value_type. This is
  109. // // true as all character parsers are compatible with a container
  110. // // attribute having the corresponding character type as its value_type.
  111. // template <typename T, typename Expected>
  112. // struct is_weak_substitute_for_value_type
  113. // : is_weak_substitute<T, typename container_value<Expected>::type>
  114. // {};
  115. //
  116. // template <typename T, typename Expected>
  117. // struct is_weak_substitute_impl<T, Expected,
  118. // typename enable_if<
  119. // mpl::and_<
  120. // mpl::not_<is_string<T> >
  121. // , is_string<Expected>
  122. // , is_weak_substitute_for_value_type<T, Expected> >
  123. // >::type>
  124. // : mpl::true_
  125. // {};
  126. // An exposed container attribute is a weak substitute for a supplied
  127. // container attribute if and only if their value_types are weak
  128. // substitutes.
  129. template <typename T, typename Expected>
  130. struct value_type_is_weak_substitute
  131. : is_weak_substitute<
  132. typename container_value<T>::type
  133. , typename container_value<Expected>::type>
  134. {};
  135. template <typename T, typename Expected>
  136. struct is_weak_substitute_impl<T, Expected,
  137. typename enable_if<
  138. mpl::and_<
  139. is_container<T>
  140. , is_container<Expected>
  141. , value_type_is_weak_substitute<T, Expected> >
  142. >::type>
  143. : mpl::true_ {};
  144. // Two fusion sequences are weak substitutes if and only if their
  145. // elements are pairwise weak substitutes.
  146. template <typename T, typename Expected>
  147. struct is_weak_substitute_impl<T, Expected,
  148. typename enable_if<
  149. mpl::and_<
  150. fusion::traits::is_sequence<T>
  151. , fusion::traits::is_sequence<Expected>
  152. , mpl::equal<T, Expected, is_weak_substitute<mpl::_1, mpl::_2> > >
  153. >::type>
  154. : mpl::true_ {};
  155. // If this is not defined, the main template definition above will return
  156. // true if T is convertible to the first type in a fusion::vector. We
  157. // globally declare any non-Fusion sequence T as not compatible with any
  158. // Fusion sequence 'Expected'.
  159. template <typename T, typename Expected>
  160. struct is_weak_substitute_impl<T, Expected,
  161. typename enable_if<
  162. mpl::and_<
  163. mpl::not_<fusion::traits::is_sequence<T> >
  164. , fusion::traits::is_sequence<Expected> >
  165. >::type>
  166. : mpl::false_ {};
  167. }
  168. // main template forwards to detail namespace, this helps older compilers
  169. // to disambiguate things
  170. template <typename T, typename Expected, typename Enable /*= void*/>
  171. struct is_weak_substitute
  172. : detail::is_weak_substitute_impl<T, Expected> {};
  173. template <typename T, typename Expected>
  174. struct is_weak_substitute<optional<T>, optional<Expected> >
  175. : is_weak_substitute<T, Expected> {};
  176. template <typename T, typename Expected>
  177. struct is_weak_substitute<optional<T>, Expected>
  178. : is_weak_substitute<T, Expected> {};
  179. template <typename T, typename Expected>
  180. struct is_weak_substitute<T, optional<Expected> >
  181. : is_weak_substitute<T, Expected> {};
  182. #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
  183. template <typename T, typename Expected>
  184. struct is_weak_substitute<boost::variant<T>, Expected>
  185. : is_weak_substitute<T, Expected>
  186. {};
  187. template <typename T0, typename T1, typename ...TN, typename Expected>
  188. struct is_weak_substitute<boost::variant<T0, T1, TN...>,
  189. Expected>
  190. : mpl::bool_<is_weak_substitute<T0, Expected>::type::value &&
  191. is_weak_substitute<boost::variant<T1, TN...>, Expected>::type::value>
  192. {};
  193. #else
  194. #define BOOST_SPIRIT_IS_WEAK_SUBSTITUTE(z, N, _) \
  195. is_weak_substitute<BOOST_PP_CAT(T, N), Expected>::type::value && \
  196. /***/
  197. // make sure unused variant parameters do not affect the outcome
  198. template <typename Expected>
  199. struct is_weak_substitute<boost::detail::variant::void_, Expected>
  200. : mpl::true_
  201. {};
  202. template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Expected>
  203. struct is_weak_substitute<
  204. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Expected>
  205. : mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
  206. , BOOST_SPIRIT_IS_WEAK_SUBSTITUTE, _) true>
  207. {};
  208. #undef BOOST_SPIRIT_IS_WEAK_SUBSTITUTE
  209. #endif
  210. template <typename T>
  211. struct is_weak_substitute<T, T
  212. , typename enable_if<
  213. mpl::and_<not_is_optional<T>, not_is_variant<T> >
  214. >::type>
  215. : mpl::true_ {};
  216. ///////////////////////////////////////////////////////////////////////////
  217. template <typename T, typename Enable/* = void*/>
  218. struct is_proxy : mpl::false_ {};
  219. template <typename T>
  220. struct is_proxy<T,
  221. typename enable_if<
  222. mpl::and_<
  223. fusion::traits::is_sequence<T>,
  224. fusion::traits::is_view<T>
  225. >
  226. >::type>
  227. : mpl::true_ {};
  228. namespace detail
  229. {
  230. // By declaring a nested struct in your class/struct, you tell
  231. // spirit that it is regarded as a variant type. The minimum
  232. // required interface for such a variant is that it has constructors
  233. // for various types supported by your variant and a typedef 'types'
  234. // which is an mpl sequence of the contained types.
  235. //
  236. // This is an intrusive interface. For a non-intrusive interface,
  237. // use the not_is_variant trait.
  238. BOOST_MPL_HAS_XXX_TRAIT_DEF(adapted_variant_tag)
  239. }
  240. template <typename T, typename Domain, typename Enable/* = void*/>
  241. struct not_is_variant
  242. : mpl::not_<detail::has_adapted_variant_tag<T> >
  243. {};
  244. template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Domain>
  245. struct not_is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Domain>
  246. : mpl::false_
  247. {};
  248. // we treat every type as if it where the variant (as this meta function is
  249. // invoked for variant types only)
  250. template <typename T>
  251. struct variant_type
  252. : mpl::identity<T>
  253. {};
  254. template <typename T>
  255. struct variant_type<boost::optional<T> >
  256. : variant_type<T>
  257. {};
  258. template <typename T, typename Domain>
  259. struct not_is_variant_or_variant_in_optional
  260. : not_is_variant<typename variant_type<T>::type, Domain>
  261. {};
  262. ///////////////////////////////////////////////////////////////////////////
  263. // The compute_compatible_component_variant
  264. ///////////////////////////////////////////////////////////////////////////
  265. namespace detail
  266. {
  267. // A component is compatible to a given Attribute type if the
  268. // Attribute is the same as the expected type of the component or if
  269. // it is convertible to the expected type.
  270. template <typename Expected, typename Attribute>
  271. struct attribute_is_compatible
  272. : is_convertible<Attribute, Expected>
  273. {};
  274. template <typename Expected, typename Attribute>
  275. struct attribute_is_compatible<Expected, boost::optional<Attribute> >
  276. : is_convertible<Attribute, Expected>
  277. {};
  278. template <typename Container>
  279. struct is_hold_any_container
  280. : traits::is_hold_any<typename traits::container_value<Container>::type>
  281. {};
  282. }
  283. template <typename Attribute, typename Expected
  284. , typename IsNotVariant = mpl::false_, typename Enable = void>
  285. struct compute_compatible_component_variant
  286. : mpl::or_<
  287. traits::detail::attribute_is_compatible<Expected, Attribute>
  288. , traits::is_hold_any<Expected>
  289. , mpl::eval_if<
  290. is_container<Expected>
  291. , traits::detail::is_hold_any_container<Expected>
  292. , mpl::false_> >
  293. {};
  294. namespace detail
  295. {
  296. BOOST_MPL_HAS_XXX_TRAIT_DEF(types)
  297. }
  298. template <typename Variant, typename Expected>
  299. struct compute_compatible_component_variant<Variant, Expected, mpl::false_
  300. , typename enable_if<detail::has_types<typename variant_type<Variant>::type> >::type>
  301. {
  302. typedef typename traits::variant_type<Variant>::type variant_type;
  303. typedef typename variant_type::types types;
  304. typedef typename mpl::end<types>::type end;
  305. typedef typename
  306. mpl::find_if<types, is_same<Expected, mpl::_1> >::type
  307. iter;
  308. typedef typename mpl::distance<
  309. typename mpl::begin<types>::type, iter
  310. >::type distance;
  311. // true_ if the attribute matches one of the types in the variant
  312. typedef typename mpl::not_<is_same<iter, end> >::type type;
  313. enum { value = type::value };
  314. // return the type in the variant the attribute is compatible with
  315. typedef typename
  316. mpl::eval_if<type, mpl::deref<iter>, mpl::identity<unused_type> >::type
  317. compatible_type;
  318. // return whether the given type is compatible with the Expected type
  319. static bool is_compatible(int which)
  320. {
  321. return which == distance::value;
  322. }
  323. };
  324. template <typename Expected, typename Attribute, typename Domain>
  325. struct compute_compatible_component
  326. : compute_compatible_component_variant<Attribute, Expected
  327. , typename not_is_variant_or_variant_in_optional<Attribute, Domain>::type> {};
  328. template <typename Expected, typename Domain>
  329. struct compute_compatible_component<Expected, unused_type, Domain>
  330. : mpl::false_ {};
  331. template <typename Attribute, typename Domain>
  332. struct compute_compatible_component<unused_type, Attribute, Domain>
  333. : mpl::false_ {};
  334. template <typename Domain>
  335. struct compute_compatible_component<unused_type, unused_type, Domain>
  336. : mpl::false_ {};
  337. ///////////////////////////////////////////////////////////////////////////
  338. // return the type currently stored in the given variant
  339. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  340. struct variant_which<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  341. {
  342. static int call(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& v)
  343. {
  344. return v.which();
  345. }
  346. };
  347. template <typename T>
  348. int which(T const& v)
  349. {
  350. return variant_which<T>::call(v);
  351. }
  352. ///////////////////////////////////////////////////////////////////////////
  353. template <typename T, typename Domain, typename Enable/* = void*/>
  354. struct not_is_optional
  355. : mpl::true_
  356. {};
  357. template <typename T, typename Domain>
  358. struct not_is_optional<boost::optional<T>, Domain>
  359. : mpl::false_
  360. {};
  361. ///////////////////////////////////////////////////////////////////////////
  362. // attribute_of
  363. //
  364. // Get the component's attribute
  365. ///////////////////////////////////////////////////////////////////////////
  366. template <typename Component
  367. , typename Context = unused_type, typename Iterator = unused_type>
  368. struct attribute_of
  369. {
  370. typedef typename Component::template
  371. attribute<Context, Iterator>::type type;
  372. };
  373. ///////////////////////////////////////////////////////////////////////////
  374. // attribute_not_unused
  375. //
  376. // An mpl meta-function class that determines whether a component's
  377. // attribute is not unused.
  378. ///////////////////////////////////////////////////////////////////////////
  379. template <typename Context, typename Iterator = unused_type>
  380. struct attribute_not_unused
  381. {
  382. template <typename Component>
  383. struct apply
  384. : not_is_unused<typename
  385. attribute_of<Component, Context, Iterator>::type>
  386. {};
  387. };
  388. ///////////////////////////////////////////////////////////////////////////
  389. // Retrieve the attribute type to use from the given type
  390. //
  391. // This is needed to extract the correct attribute type from proxy classes
  392. // as utilized in FUSION_ADAPT_ADT et. al.
  393. ///////////////////////////////////////////////////////////////////////////
  394. template <typename Attribute, typename Enable/* = void*/>
  395. struct attribute_type : mpl::identity<Attribute> {};
  396. ///////////////////////////////////////////////////////////////////////////
  397. // Retrieve the size of a fusion sequence (compile time)
  398. ///////////////////////////////////////////////////////////////////////////
  399. template <typename T>
  400. struct sequence_size
  401. : fusion::result_of::size<T>
  402. {};
  403. template <>
  404. struct sequence_size<unused_type>
  405. : mpl::int_<0>
  406. {};
  407. ///////////////////////////////////////////////////////////////////////////
  408. // Retrieve the size of an attribute (runtime)
  409. ///////////////////////////////////////////////////////////////////////////
  410. namespace detail
  411. {
  412. template <typename Attribute, typename Enable = void>
  413. struct attribute_size_impl
  414. {
  415. typedef std::size_t type;
  416. static type call(Attribute const&)
  417. {
  418. return 1;
  419. }
  420. };
  421. template <typename Attribute>
  422. struct attribute_size_impl<Attribute
  423. , typename enable_if<
  424. mpl::and_<
  425. fusion::traits::is_sequence<Attribute>
  426. , mpl::not_<traits::is_container<Attribute> >
  427. >
  428. >::type>
  429. {
  430. typedef typename fusion::result_of::size<Attribute>::value_type type;
  431. static type call(Attribute const& attr)
  432. {
  433. return fusion::size(attr);
  434. }
  435. };
  436. template <typename Attribute>
  437. struct attribute_size_impl<Attribute
  438. , typename enable_if<
  439. mpl::and_<
  440. traits::is_container<Attribute>
  441. , mpl::not_<traits::is_iterator_range<Attribute> >
  442. >
  443. >::type>
  444. {
  445. typedef typename Attribute::size_type type;
  446. static type call(Attribute const& attr)
  447. {
  448. return attr.size();
  449. }
  450. };
  451. }
  452. template <typename Attribute, typename Enable/* = void*/>
  453. struct attribute_size
  454. : detail::attribute_size_impl<Attribute>
  455. {};
  456. template <typename Attribute>
  457. struct attribute_size<optional<Attribute> >
  458. {
  459. typedef typename attribute_size<Attribute>::type type;
  460. static type call(optional<Attribute> const& val)
  461. {
  462. if (!val)
  463. return 0;
  464. return traits::size(val.get());
  465. }
  466. };
  467. namespace detail
  468. {
  469. struct attribute_size_visitor : static_visitor<std::size_t>
  470. {
  471. template <typename T>
  472. std::size_t operator()(T const& val) const
  473. {
  474. return spirit::traits::size(val);
  475. }
  476. };
  477. }
  478. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  479. struct attribute_size<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  480. {
  481. typedef std::size_t type;
  482. static type call(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& val)
  483. {
  484. return apply_visitor(detail::attribute_size_visitor(), val);
  485. }
  486. };
  487. template <typename Iterator>
  488. struct attribute_size<iterator_range<Iterator> >
  489. {
  490. typedef typename boost::detail::iterator_traits<Iterator>::
  491. difference_type type;
  492. static type call(iterator_range<Iterator> const& r)
  493. {
  494. return boost::detail::distance(r.begin(), r.end());
  495. }
  496. };
  497. template <>
  498. struct attribute_size<unused_type>
  499. {
  500. typedef std::size_t type;
  501. static type call(unused_type)
  502. {
  503. return 0;
  504. }
  505. };
  506. template <typename Attribute>
  507. typename attribute_size<Attribute>::type
  508. size (Attribute const& attr)
  509. {
  510. return attribute_size<Attribute>::call(attr);
  511. }
  512. ///////////////////////////////////////////////////////////////////////////
  513. // pass_attribute
  514. //
  515. // Determines how we pass attributes to semantic actions. This
  516. // may be specialized. By default, all attributes are wrapped in
  517. // a fusion sequence, because the attribute has to be treated as being
  518. // a single value in any case (even if it actually already is a fusion
  519. // sequence in its own).
  520. ///////////////////////////////////////////////////////////////////////////
  521. template <typename Component, typename Attribute, typename Enable/* = void*/>
  522. struct pass_attribute
  523. {
  524. typedef fusion::vector1<Attribute&> type;
  525. };
  526. ///////////////////////////////////////////////////////////////////////////
  527. // Subclass a pass_attribute specialization from this to wrap
  528. // the attribute in a tuple only IFF it is not already a fusion tuple.
  529. ///////////////////////////////////////////////////////////////////////////
  530. template <typename Attribute, typename Force = mpl::false_>
  531. struct wrap_if_not_tuple
  532. : mpl::if_<
  533. fusion::traits::is_sequence<Attribute>
  534. , Attribute&, fusion::vector1<Attribute&> >
  535. {};
  536. template <typename Attribute>
  537. struct wrap_if_not_tuple<Attribute, mpl::true_>
  538. {
  539. typedef fusion::vector1<Attribute&> type;
  540. };
  541. template <>
  542. struct wrap_if_not_tuple<unused_type, mpl::false_>
  543. {
  544. typedef unused_type type;
  545. };
  546. template <>
  547. struct wrap_if_not_tuple<unused_type const, mpl::false_>
  548. {
  549. typedef unused_type type;
  550. };
  551. ///////////////////////////////////////////////////////////////////////////
  552. // build_optional
  553. //
  554. // Build a boost::optional from T. Return unused_type if T is unused_type.
  555. ///////////////////////////////////////////////////////////////////////////
  556. template <typename T>
  557. struct build_optional
  558. {
  559. typedef boost::optional<T> type;
  560. };
  561. template <typename T>
  562. struct build_optional<boost::optional<T> >
  563. {
  564. typedef boost::optional<T> type;
  565. };
  566. template <>
  567. struct build_optional<unused_type>
  568. {
  569. typedef unused_type type;
  570. };
  571. ///////////////////////////////////////////////////////////////////////////
  572. // build_std_vector
  573. //
  574. // Build a std::vector from T. Return unused_type if T is unused_type.
  575. ///////////////////////////////////////////////////////////////////////////
  576. template <typename T>
  577. struct build_std_vector
  578. {
  579. typedef std::vector<T> type;
  580. };
  581. template <>
  582. struct build_std_vector<unused_type>
  583. {
  584. typedef unused_type type;
  585. };
  586. ///////////////////////////////////////////////////////////////////////////
  587. // filter_unused_attributes
  588. //
  589. // Remove unused_types from a sequence
  590. ///////////////////////////////////////////////////////////////////////////
  591. // Compute the list of all *used* attributes of sub-components
  592. // (filter all unused attributes from the list)
  593. template <typename Sequence>
  594. struct filter_unused_attributes
  595. : fusion::result_of::filter_if<Sequence, not_is_unused<mpl::_> >
  596. {};
  597. ///////////////////////////////////////////////////////////////////////////
  598. // sequence_attribute_transform
  599. //
  600. // This transform is invoked for every attribute in a sequence allowing
  601. // to modify the attribute type exposed by a component to the enclosing
  602. // sequence component. By default no transformation is performed.
  603. ///////////////////////////////////////////////////////////////////////////
  604. template <typename Attribute, typename Domain>
  605. struct sequence_attribute_transform
  606. : mpl::identity<Attribute>
  607. {};
  608. ///////////////////////////////////////////////////////////////////////////
  609. // permutation_attribute_transform
  610. //
  611. // This transform is invoked for every attribute in a sequence allowing
  612. // to modify the attribute type exposed by a component to the enclosing
  613. // permutation component. By default a build_optional transformation is
  614. // performed.
  615. ///////////////////////////////////////////////////////////////////////////
  616. template <typename Attribute, typename Domain>
  617. struct permutation_attribute_transform
  618. : traits::build_optional<Attribute>
  619. {};
  620. ///////////////////////////////////////////////////////////////////////////
  621. // sequential_or_attribute_transform
  622. //
  623. // This transform is invoked for every attribute in a sequential_or allowing
  624. // to modify the attribute type exposed by a component to the enclosing
  625. // sequential_or component. By default a build_optional transformation is
  626. // performed.
  627. ///////////////////////////////////////////////////////////////////////////
  628. template <typename Attribute, typename Domain>
  629. struct sequential_or_attribute_transform
  630. : traits::build_optional<Attribute>
  631. {};
  632. ///////////////////////////////////////////////////////////////////////////
  633. // build_fusion_vector
  634. //
  635. // Build a fusion vector from a fusion sequence. All unused attributes
  636. // are filtered out. If the result is empty after the removal of unused
  637. // types, return unused_type. If the input sequence is an unused_type,
  638. // also return unused_type.
  639. ///////////////////////////////////////////////////////////////////////////
  640. template <typename Sequence>
  641. struct build_fusion_vector
  642. {
  643. // Remove all unused attributes
  644. typedef typename
  645. filter_unused_attributes<Sequence>::type
  646. filtered_attributes;
  647. // Build a fusion vector from a fusion sequence (Sequence),
  648. // But *only if* the sequence is not empty. i.e. if the
  649. // sequence is empty, our result will be unused_type.
  650. typedef typename
  651. mpl::eval_if<
  652. fusion::result_of::empty<filtered_attributes>
  653. , mpl::identity<unused_type>
  654. , fusion::result_of::as_vector<filtered_attributes>
  655. >::type
  656. type;
  657. };
  658. template <>
  659. struct build_fusion_vector<unused_type>
  660. {
  661. typedef unused_type type;
  662. };
  663. ///////////////////////////////////////////////////////////////////////////
  664. // build_attribute_sequence
  665. //
  666. // Build a fusion sequence attribute sequence from a sequence of
  667. // components. Transform<T>::type is called on each element.
  668. ///////////////////////////////////////////////////////////////////////////
  669. template <typename Sequence, typename Context
  670. , template <typename T, typename D> class Transform
  671. , typename Iterator = unused_type, typename Domain = unused_type>
  672. struct build_attribute_sequence
  673. {
  674. struct element_attribute
  675. {
  676. template <typename T>
  677. struct result;
  678. template <typename F, typename Element>
  679. struct result<F(Element)>
  680. {
  681. typedef typename
  682. Transform<
  683. typename attribute_of<Element, Context, Iterator>::type
  684. , Domain
  685. >::type
  686. type;
  687. };
  688. // never called, but needed for decltype-based result_of (C++0x)
  689. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  690. template <typename Element>
  691. typename result<element_attribute(Element)>::type
  692. operator()(Element&&) const;
  693. #endif
  694. };
  695. // Compute the list of attributes of all sub-components
  696. typedef typename
  697. fusion::result_of::transform<Sequence, element_attribute>::type
  698. type;
  699. };
  700. ///////////////////////////////////////////////////////////////////////////
  701. // has_no_unused
  702. //
  703. // Test if there are no unused attributes in Sequence
  704. ///////////////////////////////////////////////////////////////////////////
  705. template <typename Sequence>
  706. struct has_no_unused
  707. : is_same<
  708. typename mpl::find_if<Sequence, is_same<mpl::_, unused_type> >::type
  709. , typename mpl::end<Sequence>::type>
  710. {};
  711. namespace detail
  712. {
  713. template <typename Sequence, bool no_unused
  714. , int size = mpl::size<Sequence>::value>
  715. struct build_collapsed_variant;
  716. // N element case, no unused
  717. template <typename Sequence, int size>
  718. struct build_collapsed_variant<Sequence, true, size>
  719. : spirit::detail::as_variant<Sequence> {};
  720. // N element case with unused
  721. template <typename Sequence, int size>
  722. struct build_collapsed_variant<Sequence, false, size>
  723. {
  724. typedef boost::optional<
  725. typename spirit::detail::as_variant<
  726. typename fusion::result_of::pop_front<Sequence>::type
  727. >::type
  728. > type;
  729. };
  730. // 1 element case, no unused
  731. template <typename Sequence>
  732. struct build_collapsed_variant<Sequence, true, 1>
  733. : mpl::front<Sequence> {};
  734. // 1 element case, with unused
  735. template <typename Sequence>
  736. struct build_collapsed_variant<Sequence, false, 1>
  737. : mpl::front<Sequence> {};
  738. // 2 element case, no unused
  739. template <typename Sequence>
  740. struct build_collapsed_variant<Sequence, true, 2>
  741. : spirit::detail::as_variant<Sequence> {};
  742. // 2 element case, with unused
  743. template <typename Sequence>
  744. struct build_collapsed_variant<Sequence, false, 2>
  745. {
  746. typedef boost::optional<
  747. typename mpl::deref<
  748. typename mpl::next<
  749. typename mpl::begin<Sequence>::type
  750. >::type
  751. >::type
  752. >
  753. type;
  754. };
  755. }
  756. ///////////////////////////////////////////////////////////////////////////
  757. // alternative_attribute_transform
  758. //
  759. // This transform is invoked for every attribute in an alternative allowing
  760. // to modify the attribute type exposed by a component to the enclosing
  761. // alternative component. By default no transformation is performed.
  762. ///////////////////////////////////////////////////////////////////////////
  763. template <typename Attribute, typename Domain>
  764. struct alternative_attribute_transform
  765. : mpl::identity<Attribute>
  766. {};
  767. ///////////////////////////////////////////////////////////////////////////
  768. // build_variant
  769. //
  770. // Build a boost::variant from a fusion sequence. build_variant makes sure
  771. // that 1) all attributes in the variant are unique 2) puts the unused
  772. // attribute, if there is any, to the front and 3) collapses single element
  773. // variants, variant<T> to T.
  774. ///////////////////////////////////////////////////////////////////////////
  775. template <typename Sequence>
  776. struct build_variant
  777. {
  778. // Remove all unused attributes.
  779. typedef typename
  780. filter_unused_attributes<Sequence>::type
  781. filtered_attributes;
  782. typedef has_no_unused<Sequence> no_unused;
  783. // If the original attribute list does not contain any unused
  784. // attributes, it is used, otherwise a single unused_type is
  785. // pushed to the front of the list. This is to make sure that if
  786. // there is an unused_type in the list, it is the first one.
  787. typedef typename
  788. mpl::eval_if<
  789. no_unused,
  790. mpl::identity<Sequence>,
  791. fusion::result_of::push_front<filtered_attributes, unused_type>
  792. >::type
  793. attribute_sequence;
  794. // Make sure each of the types occur only once in the type list
  795. typedef typename
  796. mpl::fold<
  797. attribute_sequence, mpl::vector<>,
  798. mpl::if_<
  799. mpl::contains<mpl::_1, mpl::_2>,
  800. mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
  801. >
  802. >::type
  803. no_duplicates;
  804. // If there is only one type in the list of types we strip off the
  805. // variant. IOTW, collapse single element variants, variant<T> to T.
  806. // Take note that this also collapses variant<unused_type, T> to T.
  807. typedef typename
  808. traits::detail::build_collapsed_variant<
  809. no_duplicates, no_unused::value>::type
  810. type;
  811. };
  812. ///////////////////////////////////////////////////////////////////////////
  813. // transform_attribute
  814. //
  815. // Sometimes the user needs to transform the attribute types for certain
  816. // attributes. This template can be used as a customization point, where
  817. // the user is able specify specific transformation rules for any attribute
  818. // type.
  819. ///////////////////////////////////////////////////////////////////////////
  820. template <typename Exposed, typename Transformed, typename Domain
  821. , typename Enable/* = void*/>
  822. struct transform_attribute;
  823. ///////////////////////////////////////////////////////////////////////////
  824. template <typename Domain, typename Transformed, typename Exposed>
  825. typename spirit::result_of::pre_transform<Exposed, Transformed, Domain>::type
  826. pre_transform(Exposed& attr BOOST_PROTO_DISABLE_IF_IS_CONST(Exposed))
  827. {
  828. return transform_attribute<Exposed, Transformed, Domain>::pre(attr);
  829. }
  830. template <typename Domain, typename Transformed, typename Exposed>
  831. typename spirit::result_of::pre_transform<Exposed const, Transformed, Domain>::type
  832. pre_transform(Exposed const& attr)
  833. {
  834. return transform_attribute<Exposed const, Transformed, Domain>::pre(attr);
  835. }
  836. ///////////////////////////////////////////////////////////////////////////
  837. // make_attribute
  838. //
  839. // All parsers and generators have specific attribute types.
  840. // Spirit parsers and generators are passed an attribute; these are either
  841. // references to the expected type, or an unused_type -- to flag that we do
  842. // not care about the attribute. For semantic actions, however, we need to
  843. // have a real value to pass to the semantic action. If the client did not
  844. // provide one, we will have to synthesize the value. This class takes care
  845. // of that. *Note that this behavior has changed. From Boost 1.47, semantic
  846. // actions always take in the passed attribute as-is if the PP constant:
  847. // BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT is defined.
  848. ///////////////////////////////////////////////////////////////////////////
  849. template <typename Attribute, typename ActualAttribute>
  850. struct make_attribute
  851. {
  852. typedef typename remove_const<Attribute>::type attribute_type;
  853. typedef typename
  854. mpl::if_<
  855. is_same<typename remove_const<ActualAttribute>::type, unused_type>
  856. , attribute_type
  857. , ActualAttribute&>::type
  858. type;
  859. typedef typename
  860. mpl::if_<
  861. is_same<typename remove_const<ActualAttribute>::type, unused_type>
  862. , attribute_type
  863. , ActualAttribute>::type
  864. value_type;
  865. static Attribute call(unused_type)
  866. {
  867. // synthesize the attribute/parameter
  868. return boost::get(value_initialized<attribute_type>());
  869. }
  870. template <typename T>
  871. static T& call(T& value)
  872. {
  873. return value; // just pass the one provided
  874. }
  875. };
  876. template <typename Attribute, typename ActualAttribute>
  877. struct make_attribute<Attribute&, ActualAttribute>
  878. : make_attribute<Attribute, ActualAttribute>
  879. {};
  880. template <typename Attribute, typename ActualAttribute>
  881. struct make_attribute<Attribute const&, ActualAttribute>
  882. : make_attribute<Attribute const, ActualAttribute>
  883. {};
  884. template <typename ActualAttribute>
  885. struct make_attribute<unused_type, ActualAttribute>
  886. {
  887. typedef unused_type type;
  888. typedef unused_type value_type;
  889. static unused_type call(unused_type)
  890. {
  891. return unused;
  892. }
  893. };
  894. ///////////////////////////////////////////////////////////////////////////
  895. // swap_impl
  896. //
  897. // Swap (with proper handling of unused_types)
  898. ///////////////////////////////////////////////////////////////////////////
  899. template <typename A, typename B>
  900. void swap_impl(A& a, B& b)
  901. {
  902. A temp = a;
  903. a = b;
  904. b = temp;
  905. }
  906. template <typename T>
  907. void swap_impl(T& a, T& b)
  908. {
  909. boost::swap(a, b);
  910. }
  911. template <typename A>
  912. void swap_impl(A&, unused_type)
  913. {
  914. }
  915. template <typename A>
  916. void swap_impl(unused_type, A&)
  917. {
  918. }
  919. inline void swap_impl(unused_type, unused_type)
  920. {
  921. }
  922. ///////////////////////////////////////////////////////////////////////////
  923. // Strips single element fusion vectors into its 'naked'
  924. // form: vector<T> --> T
  925. ///////////////////////////////////////////////////////////////////////////
  926. template <typename T>
  927. struct strip_single_element_vector
  928. {
  929. typedef T type;
  930. };
  931. #if !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
  932. template <typename T>
  933. struct strip_single_element_vector<fusion::vector1<T> >
  934. {
  935. typedef T type;
  936. };
  937. #endif
  938. template <typename T>
  939. struct strip_single_element_vector<fusion::vector<T> >
  940. {
  941. typedef T type;
  942. };
  943. ///////////////////////////////////////////////////////////////////////////
  944. // meta function to return whether the argument is a one element fusion
  945. // sequence
  946. ///////////////////////////////////////////////////////////////////////////
  947. template <typename T
  948. , bool IsFusionSeq = fusion::traits::is_sequence<T>::value
  949. , bool IsProtoExpr = proto::is_expr<T>::value>
  950. struct one_element_sequence
  951. : mpl::false_
  952. {};
  953. template <typename T>
  954. struct one_element_sequence<T, true, false>
  955. : mpl::bool_<mpl::size<T>::value == 1>
  956. {};
  957. ///////////////////////////////////////////////////////////////////////////
  958. // clear
  959. //
  960. // Clear data efficiently
  961. ///////////////////////////////////////////////////////////////////////////
  962. template <typename T>
  963. void clear(T& val);
  964. namespace detail
  965. {
  966. // this is used by the variant and fusion sequence dispatch
  967. struct clear_visitor : static_visitor<>
  968. {
  969. template <typename T>
  970. void operator()(T& val) const
  971. {
  972. spirit::traits::clear(val);
  973. }
  974. };
  975. // default
  976. template <typename T>
  977. void clear_impl2(T& val, mpl::false_)
  978. {
  979. val = T();
  980. }
  981. // for fusion sequences
  982. template <typename T>
  983. void clear_impl2(T& val, mpl::true_)
  984. {
  985. fusion::for_each(val, clear_visitor());
  986. }
  987. // dispatch default or fusion sequence
  988. template <typename T>
  989. void clear_impl(T& val, mpl::false_)
  990. {
  991. clear_impl2(val, fusion::traits::is_sequence<T>());
  992. }
  993. // STL containers
  994. template <typename T>
  995. void clear_impl(T& val, mpl::true_)
  996. {
  997. val.clear();
  998. }
  999. }
  1000. template <typename T, typename Enable/* = void*/>
  1001. struct clear_value
  1002. {
  1003. static void call(T& val)
  1004. {
  1005. detail::clear_impl(val, typename is_container<T>::type());
  1006. }
  1007. };
  1008. // optionals
  1009. template <typename T>
  1010. struct clear_value<boost::optional<T> >
  1011. {
  1012. static void call(boost::optional<T>& val)
  1013. {
  1014. if (val)
  1015. val = none; // leave optional uninitialized
  1016. }
  1017. };
  1018. // variants
  1019. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  1020. struct clear_value<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  1021. {
  1022. static void call(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& val)
  1023. {
  1024. apply_visitor(detail::clear_visitor(), val);
  1025. }
  1026. };
  1027. // iterator range
  1028. template <typename T>
  1029. struct clear_value<iterator_range<T> >
  1030. {
  1031. static void call(iterator_range<T>& val)
  1032. {
  1033. val = iterator_range<T>(val.end(), val.end());
  1034. }
  1035. };
  1036. // main dispatch
  1037. template <typename T>
  1038. void clear(T& val)
  1039. {
  1040. clear_value<T>::call(val);
  1041. }
  1042. // for unused
  1043. inline void clear(unused_type)
  1044. {
  1045. }
  1046. ///////////////////////////////////////////////////////////////////////////
  1047. namespace detail
  1048. {
  1049. template <typename Out>
  1050. struct print_fusion_sequence
  1051. {
  1052. print_fusion_sequence(Out& out_)
  1053. : out(out_), is_first(true) {}
  1054. typedef void result_type;
  1055. template <typename T>
  1056. void operator()(T const& val) const
  1057. {
  1058. if (is_first)
  1059. is_first = false;
  1060. else
  1061. out << ", ";
  1062. spirit::traits::print_attribute(out, val);
  1063. }
  1064. Out& out;
  1065. mutable bool is_first;
  1066. };
  1067. // print elements in a variant
  1068. template <typename Out>
  1069. struct print_visitor : static_visitor<>
  1070. {
  1071. print_visitor(Out& out_) : out(out_) {}
  1072. template <typename T>
  1073. void operator()(T const& val) const
  1074. {
  1075. spirit::traits::print_attribute(out, val);
  1076. }
  1077. Out& out;
  1078. };
  1079. }
  1080. template <typename Out, typename T, typename Enable>
  1081. struct print_attribute_debug
  1082. {
  1083. // for plain data types
  1084. template <typename T_>
  1085. static void call_impl3(Out& out, T_ const& val, mpl::false_)
  1086. {
  1087. out << val;
  1088. }
  1089. // for fusion data types
  1090. template <typename T_>
  1091. static void call_impl3(Out& out, T_ const& val, mpl::true_)
  1092. {
  1093. out << '[';
  1094. fusion::for_each(val, detail::print_fusion_sequence<Out>(out));
  1095. out << ']';
  1096. }
  1097. // non-stl container
  1098. template <typename T_>
  1099. static void call_impl2(Out& out, T_ const& val, mpl::false_)
  1100. {
  1101. call_impl3(out, val, fusion::traits::is_sequence<T_>());
  1102. }
  1103. // stl container
  1104. template <typename T_>
  1105. static void call_impl2(Out& out, T_ const& val, mpl::true_)
  1106. {
  1107. out << '[';
  1108. if (!traits::is_empty(val))
  1109. {
  1110. bool first = true;
  1111. typename container_iterator<T_ const>::type iend = traits::end(val);
  1112. for (typename container_iterator<T_ const>::type i = traits::begin(val);
  1113. !traits::compare(i, iend); traits::next(i))
  1114. {
  1115. if (!first)
  1116. out << ", ";
  1117. first = false;
  1118. spirit::traits::print_attribute(out, traits::deref(i));
  1119. }
  1120. }
  1121. out << ']';
  1122. }
  1123. // for variant types
  1124. template <typename T_>
  1125. static void call_impl(Out& out, T_ const& val, mpl::false_)
  1126. {
  1127. apply_visitor(detail::print_visitor<Out>(out), val);
  1128. }
  1129. // for non-variant types
  1130. template <typename T_>
  1131. static void call_impl(Out& out, T_ const& val, mpl::true_)
  1132. {
  1133. call_impl2(out, val, is_container<T_>());
  1134. }
  1135. // main entry point
  1136. static void call(Out& out, T const& val)
  1137. {
  1138. call_impl(out, val, not_is_variant<T>());
  1139. }
  1140. };
  1141. template <typename Out, typename T>
  1142. struct print_attribute_debug<Out, boost::optional<T> >
  1143. {
  1144. static void call(Out& out, boost::optional<T> const& val)
  1145. {
  1146. if (val)
  1147. spirit::traits::print_attribute(out, *val);
  1148. else
  1149. out << "[empty]";
  1150. }
  1151. };
  1152. ///////////////////////////////////////////////////////////////////////////
  1153. template <typename Out, typename T>
  1154. inline void print_attribute(Out& out, T const& val)
  1155. {
  1156. print_attribute_debug<Out, T>::call(out, val);
  1157. }
  1158. template <typename Out>
  1159. inline void print_attribute(Out&, unused_type)
  1160. {
  1161. }
  1162. ///////////////////////////////////////////////////////////////////////////
  1163. // generate debug output for lookahead token (character) stream
  1164. namespace detail
  1165. {
  1166. struct token_printer_debug_for_chars
  1167. {
  1168. template<typename Out, typename Char>
  1169. static void print(Out& o, Char c)
  1170. {
  1171. using namespace std; // allow for ADL to find the proper iscntrl
  1172. if (c == static_cast<Char>('\a'))
  1173. o << "\\a";
  1174. else if (c == static_cast<Char>('\b'))
  1175. o << "\\b";
  1176. else if (c == static_cast<Char>('\f'))
  1177. o << "\\f";
  1178. else if (c == static_cast<Char>('\n'))
  1179. o << "\\n";
  1180. else if (c == static_cast<Char>('\r'))
  1181. o << "\\r";
  1182. else if (c == static_cast<Char>('\t'))
  1183. o << "\\t";
  1184. else if (c == static_cast<Char>('\v'))
  1185. o << "\\v";
  1186. else if (c >= 0 && c < 127 && iscntrl(c))
  1187. o << "\\" << std::oct << static_cast<int>(c);
  1188. else
  1189. o << static_cast<char>(c);
  1190. }
  1191. };
  1192. // for token types where the comparison with char constants wouldn't work
  1193. struct token_printer_debug
  1194. {
  1195. template<typename Out, typename T>
  1196. static void print(Out& o, T const& val)
  1197. {
  1198. o << val;
  1199. }
  1200. };
  1201. }
  1202. template <typename T, typename Enable>
  1203. struct token_printer_debug
  1204. : mpl::if_<
  1205. mpl::and_<
  1206. is_convertible<T, char>, is_convertible<char, T> >
  1207. , detail::token_printer_debug_for_chars
  1208. , detail::token_printer_debug>::type
  1209. {};
  1210. template <typename Out, typename T>
  1211. inline void print_token(Out& out, T const& val)
  1212. {
  1213. // allow to customize the token printer routine
  1214. token_printer_debug<T>::print(out, val);
  1215. }
  1216. }}}
  1217. ///////////////////////////////////////////////////////////////////////////////
  1218. namespace boost { namespace spirit { namespace result_of
  1219. {
  1220. template <typename Exposed, typename Transformed, typename Domain>
  1221. struct pre_transform
  1222. : traits::transform_attribute<Exposed, Transformed, Domain>
  1223. {};
  1224. }}}
  1225. #endif