attributes.hpp 45 KB

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