attributes.hpp 45 KB

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