attributes.hpp 46 KB

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