utree_traits.hpp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Copyright (c) 2010-2011 Bryce Lelbach
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(BOOST_SPIRIT_OUTPUT_UTREE_TRAITS_APR_16_2010_0655AM)
  9. #define BOOST_SPIRIT_OUTPUT_UTREE_TRAITS_APR_16_2010_0655AM
  10. #include <boost/spirit/home/support/attributes.hpp>
  11. #include <boost/spirit/home/support/container.hpp>
  12. #include <boost/spirit/home/support/utree.hpp>
  13. #include <boost/spirit/home/qi/domain.hpp>
  14. #include <boost/spirit/home/karma/domain.hpp>
  15. #include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
  16. #include <boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp>
  17. #include <string>
  18. #include <boost/cstdint.hpp>
  19. #include <boost/variant.hpp>
  20. #include <boost/range/iterator_range.hpp>
  21. #include <boost/mpl/bool.hpp>
  22. #include <boost/mpl/identity.hpp>
  23. #include <boost/mpl/or.hpp>
  24. #include <boost/type_traits/is_same.hpp>
  25. #include <boost/utility/enable_if.hpp>
  26. ///////////////////////////////////////////////////////////////////////////////
  27. namespace boost
  28. {
  29. template <typename T>
  30. inline T get(boost::spirit::utree const& x)
  31. {
  32. return x.get<T>();
  33. }
  34. }
  35. ///////////////////////////////////////////////////////////////////////////////
  36. namespace boost { namespace spirit { namespace traits
  37. {
  38. namespace detail
  39. {
  40. inline bool is_list(utree const& ut)
  41. {
  42. switch (traits::which(ut))
  43. {
  44. case utree_type::reference_type:
  45. return is_list(ut.deref());
  46. case utree_type::list_type:
  47. case utree_type::range_type:
  48. return true;
  49. default:
  50. break;
  51. }
  52. return false;
  53. }
  54. inline bool is_uninitialized(utree const& ut)
  55. {
  56. return traits::which(ut) == utree_type::invalid_type;
  57. }
  58. }
  59. // this specialization tells Spirit how to extract the type of the value
  60. // stored in the given utree node
  61. template <>
  62. struct variant_which<utree>
  63. {
  64. static int call(utree const& u) { return u.which(); }
  65. };
  66. template <>
  67. struct variant_which<utree::list_type>
  68. {
  69. static int call(utree::list_type const& u) { return u.which(); }
  70. };
  71. ///////////////////////////////////////////////////////////////////////////
  72. // Make sure all components of an alternative expose utree, even if they
  73. // actually expose a utree::list_type
  74. template <typename Domain>
  75. struct alternative_attribute_transform<utree::list_type, Domain>
  76. : mpl::identity<utree>
  77. {};
  78. ///////////////////////////////////////////////////////////////////////////
  79. // Make sure all components of a sequence expose utree, even if they
  80. // actually expose a utree::list_type
  81. template <typename Domain>
  82. struct sequence_attribute_transform<utree::list_type, Domain>
  83. : mpl::identity<utree>
  84. {};
  85. ///////////////////////////////////////////////////////////////////////////
  86. // this specialization lets Spirit know that typed basic_strings
  87. // are strings
  88. template <typename Base, utree_type::info I>
  89. struct is_string<spirit::basic_string<Base, I> >
  90. : mpl::true_
  91. {};
  92. ///////////////////////////////////////////////////////////////////////////
  93. // these specializations extract the character type of a utree typed string
  94. template <typename T, utree_type::info I>
  95. struct char_type_of<spirit::basic_string<iterator_range<T>, I> >
  96. : char_type_of<T>
  97. {};
  98. template <utree_type::info I>
  99. struct char_type_of<spirit::basic_string<std::string, I> >
  100. : mpl::identity<char>
  101. {};
  102. ///////////////////////////////////////////////////////////////////////////
  103. // these specializations extract a c string from a utree typed string
  104. template <typename String>
  105. struct extract_c_string;
  106. template <typename T, utree_type::info I>
  107. struct extract_c_string<
  108. spirit::basic_string<iterator_range<T const*>, I>
  109. > {
  110. typedef T char_type;
  111. typedef spirit::basic_string<iterator_range<T const*>, I> string;
  112. static T const* call (string& s)
  113. {
  114. return s.begin();
  115. }
  116. static T const* call (string const& s)
  117. {
  118. return s.begin();
  119. }
  120. };
  121. template <utree_type::info I>
  122. struct extract_c_string<spirit::basic_string<std::string, I> >
  123. {
  124. typedef char char_type;
  125. typedef spirit::basic_string<std::string, I> string;
  126. static char const* call (string& s)
  127. {
  128. return s.c_str();
  129. }
  130. static char const* call (string const& s)
  131. {
  132. return s.c_str();
  133. }
  134. };
  135. ///////////////////////////////////////////////////////////////////////////
  136. // these specializations are needed because utree::value_type == utree
  137. template <>
  138. struct is_substitute<utree, utree>
  139. : mpl::true_
  140. {};
  141. template <>
  142. struct is_weak_substitute<utree, utree>
  143. : mpl::true_
  144. {};
  145. template <>
  146. struct is_substitute<utree::list_type, utree::list_type>
  147. : mpl::true_
  148. {};
  149. template <>
  150. struct is_weak_substitute<utree::list_type, utree::list_type>
  151. : mpl::true_
  152. {};
  153. ///////////////////////////////////////////////////////////////////////////
  154. // this specialization tells Spirit.Qi to allow assignment to an utree from
  155. // a variant
  156. namespace detail
  157. {
  158. struct assign_to_utree_visitor : static_visitor<>
  159. {
  160. assign_to_utree_visitor(utree& ut) : ut_(ut) {}
  161. template <typename T>
  162. void operator()(T& val) const
  163. {
  164. ut_ = val;
  165. }
  166. utree& ut_;
  167. };
  168. }
  169. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  170. struct assign_to_container_from_value<
  171. utree, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  172. {
  173. static void
  174. call(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& val, utree& attr)
  175. {
  176. apply_visitor(detail::assign_to_utree_visitor(attr), val);
  177. }
  178. };
  179. ///////////////////////////////////////////////////////////////////////////
  180. // this specialization tells Spirit.Qi to allow assignment to an utree from
  181. // a STL container
  182. template <typename Attribute>
  183. struct assign_to_container_from_value<utree, Attribute>
  184. {
  185. // any non-container type will be either directly assigned or appended
  186. static void call(Attribute const& val, utree& attr, mpl::false_)
  187. {
  188. if (attr.empty())
  189. attr = val;
  190. else
  191. push_back(attr, val);
  192. }
  193. // any container type will be converted into a list_type utree
  194. static void call(Attribute const& val, utree& attr, mpl::true_)
  195. {
  196. typedef typename traits::container_iterator<Attribute const>::type
  197. iterator_type;
  198. // make sure the attribute is a list, at least an empty one
  199. if (attr.empty())
  200. attr = empty_list;
  201. iterator_type end = traits::end(val);
  202. for (iterator_type i = traits::begin(val); i != end; traits::next(i))
  203. push_back(attr, traits::deref(i));
  204. }
  205. static void call(Attribute const& val, utree& attr)
  206. {
  207. call(val, attr, is_container<Attribute>());
  208. }
  209. };
  210. ///////////////////////////////////////////////////////////////////////////
  211. // this specialization is required to disambiguate the specializations
  212. // related to utree
  213. template <>
  214. struct assign_to_container_from_value<utree, utree>
  215. {
  216. static void call(utree const& val, utree& attr)
  217. {
  218. if (attr.empty()) {
  219. attr = val;
  220. }
  221. else if (detail::is_list(val)) {
  222. typedef utree::const_iterator iterator_type;
  223. iterator_type end = traits::end(val);
  224. for (iterator_type i = traits::begin(val); i != end; traits::next(i))
  225. push_back(attr, traits::deref(i));
  226. }
  227. else {
  228. push_back(attr, val);
  229. }
  230. }
  231. };
  232. template <>
  233. struct assign_to_container_from_value<utree, utree::list_type>
  234. : assign_to_container_from_value<utree, utree>
  235. {};
  236. // If the destination is a utree_list, we need to force the right hand side
  237. // value into a new sub-node, always, no questions asked.
  238. template <>
  239. struct assign_to_container_from_value<utree::list_type, utree>
  240. {
  241. static void call(utree const& val, utree& attr)
  242. {
  243. push_back(attr, val);
  244. }
  245. };
  246. // If both, the right hand side and the left hand side are utree_lists
  247. // we have a lhs rule which has a single rule exposing a utree_list as its
  248. // rhs (optionally wrapped into a directive or other unary parser). In this
  249. // case we do not create a new sub-node.
  250. template <>
  251. struct assign_to_container_from_value<utree::list_type, utree::list_type>
  252. : assign_to_container_from_value<utree, utree>
  253. {};
  254. ///////////////////////////////////////////////////////////////////////////
  255. // this specialization makes sure strings get assigned as a whole and are
  256. // not converted into a utree list
  257. template <>
  258. struct assign_to_container_from_value<utree, utf8_string_type>
  259. {
  260. static void call(utf8_string_type const& val, utree& attr)
  261. {
  262. if (attr.empty())
  263. attr = val;
  264. else
  265. push_back(attr, val);
  266. }
  267. };
  268. // this specialization keeps symbols from being transformed into strings
  269. template<>
  270. struct assign_to_container_from_value<utree, utf8_symbol_type>
  271. {
  272. static void call (utf8_symbol_type const& val, utree& attr)
  273. {
  274. if (attr.empty())
  275. attr = val;
  276. else
  277. push_back(attr, val);
  278. }
  279. };
  280. template <>
  281. struct assign_to_container_from_value<utree, binary_string_type>
  282. {
  283. static void call(binary_string_type const& val, utree& attr)
  284. {
  285. if (attr.empty())
  286. attr = val;
  287. else
  288. push_back(attr, val);
  289. }
  290. };
  291. template<>
  292. struct assign_to_container_from_value<utree, utf8_symbol_range_type>
  293. {
  294. static void call (utf8_symbol_range_type const& val, utree& attr)
  295. {
  296. if (attr.empty())
  297. attr = val;
  298. else
  299. push_back(attr, val);
  300. }
  301. };
  302. template <>
  303. struct assign_to_container_from_value<utree, binary_range_type>
  304. {
  305. static void call(binary_range_type const& val, utree& attr)
  306. {
  307. if (attr.empty())
  308. attr = val;
  309. else
  310. push_back(attr, val);
  311. }
  312. };
  313. template <>
  314. struct assign_to_container_from_value<utree, std::string>
  315. {
  316. static void call(std::string const& val, utree& attr)
  317. {
  318. if (attr.empty())
  319. attr = val;
  320. else
  321. push_back(attr, val);
  322. }
  323. };
  324. ///////////////////////////////////////////////////////////////////////////
  325. // this specialization tells Spirit.Qi to allow assignment to an utree from
  326. // generic iterators
  327. template <typename Iterator>
  328. struct assign_to_attribute_from_iterators<utree, Iterator>
  329. {
  330. static void
  331. call(Iterator const& first, Iterator const& last, utree& attr)
  332. {
  333. if (attr.empty())
  334. attr.assign(first, last);
  335. else {
  336. for (Iterator i = first; i != last; ++i)
  337. push_back(attr, traits::deref(i));
  338. }
  339. }
  340. };
  341. ///////////////////////////////////////////////////////////////////////////
  342. // Karma only: convert utree node to string
  343. namespace detail
  344. {
  345. struct attribute_as_string_type
  346. {
  347. typedef utf8_string_range_type type;
  348. static type call(utree const& attr)
  349. {
  350. return boost::get<utf8_string_range_type>(attr);
  351. }
  352. static bool is_valid(utree const& attr)
  353. {
  354. switch (traits::which(attr))
  355. {
  356. case utree_type::reference_type:
  357. return is_valid(attr.deref());
  358. case utree_type::string_range_type:
  359. case utree_type::string_type:
  360. return true;
  361. default:
  362. return false;
  363. }
  364. }
  365. };
  366. }
  367. template <>
  368. struct attribute_as<std::string, utree>
  369. : detail::attribute_as_string_type
  370. {};
  371. template <>
  372. struct attribute_as<utf8_string_type, utree>
  373. : detail::attribute_as_string_type
  374. {};
  375. template <>
  376. struct attribute_as<utf8_string_range_type, utree>
  377. : detail::attribute_as_string_type
  378. {};
  379. ///////////////////////////////////////////////////////////////////////////
  380. namespace detail
  381. {
  382. struct attribute_as_symbol_type
  383. {
  384. typedef utf8_symbol_range_type type;
  385. static type call(utree const& attr)
  386. {
  387. return boost::get<utf8_symbol_range_type>(attr);
  388. }
  389. static bool is_valid(utree const& attr)
  390. {
  391. switch (traits::which(attr))
  392. {
  393. case utree_type::reference_type:
  394. return is_valid(attr.deref());
  395. case utree_type::symbol_type:
  396. return true;
  397. default:
  398. return false;
  399. }
  400. }
  401. };
  402. }
  403. template <>
  404. struct attribute_as<utf8_symbol_type, utree>
  405. : detail::attribute_as_symbol_type
  406. {};
  407. template <>
  408. struct attribute_as<utf8_symbol_range_type, utree>
  409. : detail::attribute_as_symbol_type
  410. {};
  411. template <typename Attribute>
  412. struct attribute_as<Attribute, utree::list_type>
  413. : attribute_as<Attribute, utree>
  414. {};
  415. ///////////////////////////////////////////////////////////////////////////
  416. namespace detail
  417. {
  418. struct attribute_as_binary_string_type
  419. {
  420. typedef binary_range_type type;
  421. static type call(utree const& attr)
  422. {
  423. return boost::get<binary_range_type>(attr);
  424. }
  425. static bool is_valid(utree const& attr)
  426. {
  427. switch (traits::which(attr))
  428. {
  429. case utree_type::reference_type:
  430. return is_valid(attr.deref());
  431. case utree_type::binary_type:
  432. return true;
  433. default:
  434. return false;
  435. }
  436. }
  437. };
  438. }
  439. template <>
  440. struct attribute_as<binary_string_type, utree>
  441. : detail::attribute_as_binary_string_type
  442. {};
  443. template <>
  444. struct attribute_as<binary_range_type, utree>
  445. : detail::attribute_as_binary_string_type
  446. {};
  447. ///////////////////////////////////////////////////////////////////////////
  448. // push_back support for utree
  449. template <typename T>
  450. struct push_back_container<utree, T>
  451. {
  452. static bool call(utree& c, T const& val)
  453. {
  454. switch (traits::which(c))
  455. {
  456. case utree_type::invalid_type:
  457. case utree_type::nil_type:
  458. case utree_type::list_type:
  459. c.push_back(val);
  460. break;
  461. default:
  462. {
  463. utree ut;
  464. ut.push_back(c);
  465. ut.push_back(val);
  466. c.swap(ut);
  467. }
  468. break;
  469. }
  470. return true;
  471. }
  472. };
  473. template <typename T>
  474. struct push_back_container<utree::list_type, T>
  475. : push_back_container<utree, T>
  476. {};
  477. ///////////////////////////////////////////////////////////////////////////
  478. // ensure the utree attribute is an empty list
  479. template <>
  480. struct make_container_attribute<utree>
  481. {
  482. static void call(utree& ut)
  483. {
  484. if (!detail::is_list(ut)) {
  485. if (detail::is_uninitialized(ut))
  486. ut = empty_list;
  487. else {
  488. utree retval (empty_list);
  489. retval.push_back(ut);
  490. ut.swap(retval);
  491. }
  492. }
  493. }
  494. };
  495. template <>
  496. struct make_container_attribute<utree::list_type>
  497. : make_container_attribute<utree>
  498. {};
  499. ///////////////////////////////////////////////////////////////////////////
  500. // an utree is a container on its own
  501. template <>
  502. struct build_std_vector<utree>
  503. {
  504. typedef utree type;
  505. };
  506. template <>
  507. struct build_std_vector<utree::list_type>
  508. {
  509. typedef utree::list_type type;
  510. };
  511. ///////////////////////////////////////////////////////////////////////////
  512. // debug support for utree
  513. template <typename Out>
  514. struct print_attribute_debug<Out, utree>
  515. {
  516. static void call(Out& out, utree const& val)
  517. {
  518. out << val;
  519. }
  520. };
  521. ///////////////////////////////////////////////////////////////////////////
  522. // force utree list attribute in a sequence to be dereferenced if a rule
  523. // or a grammar exposes an utree as it's attribute
  524. namespace detail
  525. {
  526. // Checks whether the exposed Attribute allows to handle utree or
  527. // utree::list_type directly. Returning mpl::false_ from this meta
  528. // function will force a new utree instance to be created for each
  529. // invocation of the embedded parser.
  530. // The purpose of using utree::list_type as an attribute is to force a
  531. // new sub-node in the result.
  532. template <typename Attribute, typename Enable = void>
  533. struct handles_utree_list_container
  534. : mpl::and_<
  535. mpl::not_<is_same<utree::list_type, Attribute> >,
  536. traits::is_container<Attribute> >
  537. {};
  538. // The following specializations make sure that the actual handling of
  539. // an utree (or utree::list_type) attribute is deferred to the embedded
  540. // parsers of a sequence, alternative or optional component.
  541. template <typename Attribute>
  542. struct handles_utree_list_container<Attribute
  543. , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
  544. : mpl::true_
  545. {};
  546. template <typename Attribute>
  547. struct handles_utree_list_container<boost::optional<Attribute> >
  548. : mpl::true_
  549. {};
  550. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  551. struct handles_utree_list_container<
  552. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  553. : mpl::true_
  554. {};
  555. }
  556. template <
  557. typename IteratorA, typename IteratorB, typename Context
  558. , typename T1, typename T2, typename T3, typename T4>
  559. struct handles_container<qi::rule<IteratorA, T1, T2, T3, T4>
  560. , utree, Context, IteratorB>
  561. : detail::handles_utree_list_container<typename attribute_of<
  562. qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
  563. >::type>
  564. {};
  565. template <
  566. typename IteratorA, typename IteratorB, typename Context
  567. , typename T1, typename T2, typename T3, typename T4>
  568. struct handles_container<qi::grammar<IteratorA, T1, T2, T3, T4>
  569. , utree, Context, IteratorB>
  570. : detail::handles_utree_list_container<typename attribute_of<
  571. qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
  572. >::type>
  573. {};
  574. template <
  575. typename IteratorA, typename IteratorB, typename Context
  576. , typename T1, typename T2, typename T3, typename T4>
  577. struct handles_container<qi::rule<IteratorA, T1, T2, T3, T4>
  578. , utree::list_type, Context, IteratorB>
  579. : detail::handles_utree_list_container<typename attribute_of<
  580. qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
  581. >::type>
  582. {};
  583. template <
  584. typename IteratorA, typename IteratorB, typename Context
  585. , typename T1, typename T2, typename T3, typename T4>
  586. struct handles_container<qi::grammar<IteratorA, T1, T2, T3, T4>
  587. , utree::list_type, Context, IteratorB>
  588. : detail::handles_utree_list_container<typename attribute_of<
  589. qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
  590. >::type>
  591. {};
  592. ///////////////////////////////////////////////////////////////////////////
  593. template <typename Attribute, typename Sequence>
  594. struct pass_through_container<
  595. utree, utree, Attribute, Sequence, qi::domain>
  596. : detail::handles_utree_list_container<Attribute>
  597. {};
  598. template <typename Attribute, typename Sequence>
  599. struct pass_through_container<
  600. utree::list_type, utree, Attribute, Sequence, qi::domain>
  601. : detail::handles_utree_list_container<Attribute>
  602. {};
  603. ///////////////////////////////////////////////////////////////////////////
  604. namespace detail
  605. {
  606. // Checks whether the exposed Attribute allows to handle utree or
  607. // utree::list_type directly. Returning mpl::false_ from this meta
  608. // function will force a new utree instance to be created for each
  609. // invocation of the embedded parser.
  610. // The purpose of using utree::list_type as an attribute is to force a
  611. // new sub-node in the result.
  612. template <typename Attribute, typename Enable = void>
  613. struct handles_utree_container
  614. : mpl::and_<
  615. mpl::not_<is_same<utree, Attribute> >,
  616. traits::is_container<Attribute> >
  617. {};
  618. // The following specializations make sure that the actual handling of
  619. // an utree (or utree::list_type) attribute is deferred to the embedded
  620. // parsers of a sequence, alternative or optional component.
  621. template <typename Attribute>
  622. struct handles_utree_container<Attribute
  623. , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
  624. : mpl::true_
  625. {};
  626. template <typename Attribute>
  627. struct handles_utree_container<boost::optional<Attribute> >
  628. : mpl::true_
  629. {};
  630. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  631. struct handles_utree_container<
  632. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  633. : mpl::true_
  634. {};
  635. }
  636. template <
  637. typename IteratorA, typename IteratorB, typename Context
  638. , typename T1, typename T2, typename T3, typename T4>
  639. struct handles_container<karma::rule<IteratorA, T1, T2, T3, T4>
  640. , utree, Context, IteratorB>
  641. : detail::handles_utree_container<typename attribute_of<
  642. karma::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
  643. >::type>
  644. {};
  645. template <
  646. typename IteratorA, typename IteratorB, typename Context
  647. , typename T1, typename T2, typename T3, typename T4>
  648. struct handles_container<karma::grammar<IteratorA, T1, T2, T3, T4>
  649. , utree, Context, IteratorB>
  650. : detail::handles_utree_container<typename attribute_of<
  651. karma::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
  652. >::type>
  653. {};
  654. ///////////////////////////////////////////////////////////////////////////
  655. template <typename Attribute, typename Sequence>
  656. struct pass_through_container<
  657. utree, utree, Attribute, Sequence, karma::domain>
  658. : detail::handles_utree_container<Attribute>
  659. {};
  660. ///////////////////////////////////////////////////////////////////////////
  661. // the specialization below tells Spirit how to handle utree if it is used
  662. // with an optional component
  663. template <>
  664. struct optional_attribute<utree>
  665. {
  666. typedef utree const& type;
  667. static type call(utree const& val)
  668. {
  669. return val;
  670. }
  671. // only 'invalid_type' utree nodes are not valid
  672. static bool is_valid(utree const& val)
  673. {
  674. return !detail::is_uninitialized(val);
  675. }
  676. };
  677. template <>
  678. struct build_optional<utree>
  679. {
  680. typedef utree type;
  681. };
  682. template <>
  683. struct build_optional<utree::list_type>
  684. {
  685. typedef utree::list_type type;
  686. };
  687. // an utree is an optional (in any domain)
  688. template <>
  689. struct not_is_optional<utree, qi::domain>
  690. : mpl::false_
  691. {};
  692. template <>
  693. struct not_is_optional<utree::list_type, qi::domain>
  694. : mpl::false_
  695. {};
  696. template <>
  697. struct not_is_optional<utree, karma::domain>
  698. : mpl::false_
  699. {};
  700. template <>
  701. struct not_is_optional<utree::list_type, karma::domain>
  702. : mpl::false_
  703. {};
  704. ///////////////////////////////////////////////////////////////////////////
  705. // the specialization below tells Spirit to handle utree as if it
  706. // where a 'real' variant (in the context of karma)
  707. template <>
  708. struct not_is_variant<utree, karma::domain>
  709. : mpl::false_
  710. {};
  711. template <>
  712. struct not_is_variant<utree::list_type, karma::domain>
  713. : mpl::false_
  714. {};
  715. // The specializations below tell Spirit to verify whether an attribute
  716. // type is compatible with a given variant type
  717. template <>
  718. struct compute_compatible_component_variant<
  719. utree, iterator_range<utree::iterator> >
  720. : mpl::true_
  721. {
  722. typedef iterator_range<utree::iterator> compatible_type;
  723. static bool is_compatible(int d)
  724. {
  725. return d == utree_type::list_type;
  726. }
  727. };
  728. template <>
  729. struct compute_compatible_component_variant<
  730. utree, iterator_range<utree::const_iterator> >
  731. : mpl::true_
  732. {
  733. typedef iterator_range<utree::const_iterator> compatible_type;
  734. static bool is_compatible(int d)
  735. {
  736. return d == utree_type::list_type;
  737. }
  738. };
  739. template <>
  740. struct compute_compatible_component_variant<utree, utree::invalid_type>
  741. : mpl::true_
  742. {
  743. typedef utree::invalid_type compatible_type;
  744. static bool is_compatible(int d)
  745. {
  746. return d == utree_type::invalid_type;
  747. }
  748. };
  749. template <>
  750. struct compute_compatible_component_variant<utree, utree::nil_type>
  751. : mpl::true_
  752. {
  753. typedef utree::nil_type compatible_type;
  754. static bool is_compatible(int d)
  755. {
  756. return d == utree_type::nil_type;
  757. }
  758. };
  759. template <>
  760. struct compute_compatible_component_variant<utree, bool>
  761. : mpl::true_
  762. {
  763. typedef bool compatible_type;
  764. static bool is_compatible(int d)
  765. {
  766. return d == utree_type::bool_type;
  767. }
  768. };
  769. template <>
  770. struct compute_compatible_component_variant<utree, int>
  771. : mpl::true_
  772. {
  773. typedef int compatible_type;
  774. static bool is_compatible(int d)
  775. {
  776. return d == utree_type::int_type;
  777. }
  778. };
  779. template <>
  780. struct compute_compatible_component_variant<utree, double>
  781. : mpl::true_
  782. {
  783. typedef double compatible_type;
  784. static bool is_compatible(int d)
  785. {
  786. return d == utree_type::double_type;
  787. }
  788. };
  789. template <>
  790. struct compute_compatible_component_variant<
  791. utree, utf8_string_range_type>
  792. : mpl::true_
  793. {
  794. typedef utf8_string_range_type compatible_type;
  795. static bool is_compatible(int d)
  796. {
  797. return d == utree_type::string_type;
  798. }
  799. };
  800. template <>
  801. struct compute_compatible_component_variant<
  802. utree, utf8_string_type>
  803. : mpl::true_
  804. {
  805. typedef utf8_string_type compatible_type;
  806. static bool is_compatible(int d)
  807. {
  808. return d == utree_type::string_type;
  809. }
  810. };
  811. template <>
  812. struct compute_compatible_component_variant<
  813. utree, utf8_symbol_range_type>
  814. : mpl::true_
  815. {
  816. typedef utf8_symbol_range_type compatible_type;
  817. static bool is_compatible(int d)
  818. {
  819. return d == utree_type::symbol_type;
  820. }
  821. };
  822. template <>
  823. struct compute_compatible_component_variant<
  824. utree, utf8_symbol_type>
  825. : mpl::true_
  826. {
  827. typedef utf8_symbol_type compatible_type;
  828. static bool is_compatible(int d)
  829. {
  830. return d == utree_type::symbol_type;
  831. }
  832. };
  833. template <>
  834. struct compute_compatible_component_variant<
  835. utree, binary_range_type>
  836. : mpl::true_
  837. {
  838. typedef binary_range_type compatible_type;
  839. static bool is_compatible(int d)
  840. {
  841. return d == utree_type::binary_type;
  842. }
  843. };
  844. template <>
  845. struct compute_compatible_component_variant<
  846. utree, binary_string_type>
  847. : mpl::true_
  848. {
  849. typedef binary_string_type compatible_type;
  850. static bool is_compatible(int d)
  851. {
  852. return d == utree_type::binary_type;
  853. }
  854. };
  855. template <>
  856. struct compute_compatible_component_variant<utree, utree>
  857. : mpl::true_
  858. {
  859. typedef utree compatible_type;
  860. static bool is_compatible(int d)
  861. {
  862. return d >= utree_type::invalid_type &&
  863. d <= utree_type::reference_type;
  864. }
  865. };
  866. template <>
  867. struct compute_compatible_component_variant<
  868. utree, std::vector<utree> >
  869. : mpl::true_
  870. {
  871. typedef utree compatible_type;
  872. static bool is_compatible(int d)
  873. {
  874. return d >= utree_type::invalid_type &&
  875. d <= utree_type::reference_type;
  876. }
  877. };
  878. template <typename Sequence>
  879. struct compute_compatible_component_variant<utree, Sequence
  880. , mpl::false_
  881. , typename enable_if<fusion::traits::is_sequence<Sequence> >::type>
  882. : mpl::true_
  883. {
  884. typedef iterator_range<utree::const_iterator> compatible_type;
  885. static bool is_compatible(int d)
  886. {
  887. return d == utree_type::list_type;
  888. }
  889. };
  890. template <typename Attribute>
  891. struct compute_compatible_component_variant<utree::list_type, Attribute>
  892. : compute_compatible_component_variant<utree, Attribute>
  893. {};
  894. ///////////////////////////////////////////////////////////////////////////
  895. template <>
  896. struct symbols_lookup<utree, utf8_symbol_type>
  897. {
  898. typedef std::string type;
  899. static type call(utree const& t)
  900. {
  901. utf8_symbol_range_type r = boost::get<utf8_symbol_range_type>(t);
  902. return std::string(traits::begin(r), traits::end(r));
  903. }
  904. };
  905. template <>
  906. struct symbols_lookup<utf8_symbol_type, utf8_symbol_type>
  907. {
  908. typedef std::string type;
  909. static type call(utf8_symbol_type const& t)
  910. {
  911. return t;
  912. }
  913. };
  914. ///////////////////////////////////////////////////////////////////////////
  915. namespace detail
  916. {
  917. template <typename T>
  918. inline T get_or_deref(utree const& t)
  919. {
  920. if (detail::is_list(t))
  921. return boost::get<T>(t.front());
  922. return boost::get<T>(t);
  923. }
  924. }
  925. template <>
  926. struct extract_from_container<utree, utree::nil_type>
  927. {
  928. typedef utree::nil_type type;
  929. template <typename Context>
  930. static type call(utree const&, Context&)
  931. {
  932. return nil;
  933. }
  934. };
  935. template <>
  936. struct extract_from_container<utree, char>
  937. {
  938. typedef char type;
  939. template <typename Context>
  940. static type call(utree const& t, Context&)
  941. {
  942. utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
  943. return r.front();
  944. }
  945. };
  946. template <>
  947. struct extract_from_container<utree, bool>
  948. {
  949. typedef bool type;
  950. template <typename Context>
  951. static type call(utree const& t, Context&)
  952. {
  953. return detail::get_or_deref<bool>(t);
  954. }
  955. };
  956. template <>
  957. struct extract_from_container<utree, int>
  958. {
  959. typedef int type;
  960. template <typename Context>
  961. static type call(utree const& t, Context&)
  962. {
  963. return detail::get_or_deref<int>(t);
  964. }
  965. };
  966. template <>
  967. struct extract_from_container<utree, double>
  968. {
  969. typedef double type;
  970. template <typename Context>
  971. static type call(utree const& t, Context&)
  972. {
  973. return detail::get_or_deref<double>(t);
  974. }
  975. };
  976. template <typename Traits, typename Alloc>
  977. struct extract_from_container<utree, std::basic_string<char, Traits, Alloc> >
  978. {
  979. typedef std::basic_string<char, Traits, Alloc> type;
  980. template <typename Context>
  981. static type call(utree const& t, Context&)
  982. {
  983. utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
  984. return type(traits::begin(r), traits::end(r));
  985. }
  986. };
  987. template <>
  988. struct extract_from_container<utree, utf8_symbol_type>
  989. {
  990. typedef utf8_symbol_type type;
  991. template <typename Context>
  992. static type call(utree const& t, Context&)
  993. {
  994. utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
  995. return type(traits::begin(r), traits::end(r));
  996. }
  997. };
  998. template <>
  999. struct extract_from_container<utree, utf8_string_type>
  1000. {
  1001. typedef utf8_string_type type;
  1002. template <typename Context>
  1003. static type call(utree const& t, Context&)
  1004. {
  1005. utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
  1006. return type(traits::begin(r), traits::end(r));
  1007. }
  1008. };
  1009. ///////////////////////////////////////////////////////////////////////////
  1010. template <>
  1011. struct transform_attribute<utree const, utree::nil_type, karma::domain>
  1012. {
  1013. typedef utree::nil_type type;
  1014. static type pre(utree const&)
  1015. {
  1016. return nil;
  1017. }
  1018. };
  1019. template <>
  1020. struct transform_attribute<utree const, char, karma::domain>
  1021. {
  1022. typedef char type;
  1023. static type pre(utree const& t)
  1024. {
  1025. utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
  1026. return r.front();
  1027. }
  1028. };
  1029. template <>
  1030. struct transform_attribute<utree const, bool, karma::domain>
  1031. {
  1032. typedef bool type;
  1033. static type pre(utree const& t)
  1034. {
  1035. return detail::get_or_deref<bool>(t);
  1036. }
  1037. };
  1038. template <>
  1039. struct transform_attribute<utree const, int, karma::domain>
  1040. {
  1041. typedef int type;
  1042. static type pre(utree const& t)
  1043. {
  1044. return detail::get_or_deref<int>(t);
  1045. }
  1046. };
  1047. template <>
  1048. struct transform_attribute<utree const, double, karma::domain>
  1049. {
  1050. typedef double type;
  1051. static type pre(utree const& t)
  1052. {
  1053. return detail::get_or_deref<double>(t);
  1054. }
  1055. };
  1056. template <typename Traits, typename Alloc>
  1057. struct transform_attribute<
  1058. utree const, std::basic_string<char, Traits, Alloc>, karma::domain>
  1059. {
  1060. typedef std::basic_string<char, Traits, Alloc> type;
  1061. static type pre(utree const& t)
  1062. {
  1063. utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
  1064. return type(traits::begin(r), traits::end(r));
  1065. }
  1066. };
  1067. // this specialization is used whenever a utree is passed to a rule as part
  1068. // of a sequence
  1069. template <typename Iterator>
  1070. struct transform_attribute<
  1071. iterator_range<Iterator> const, utree, karma::domain>
  1072. {
  1073. typedef utree type;
  1074. static type pre(iterator_range<Iterator> const& t)
  1075. {
  1076. // return utree the begin iterator points to
  1077. Iterator it = boost::begin(t);
  1078. utree result(boost::ref(*it));
  1079. ++it;
  1080. return result;
  1081. }
  1082. };
  1083. ///////////////////////////////////////////////////////////////////////////
  1084. template <>
  1085. struct transform_attribute<utree const, utf8_string_type, karma::domain>
  1086. {
  1087. typedef utf8_string_type type;
  1088. static type pre(utree const& t)
  1089. {
  1090. utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
  1091. return type(traits::begin(r), traits::end(r));
  1092. }
  1093. };
  1094. template <>
  1095. struct transform_attribute<utree const, utf8_symbol_type, karma::domain>
  1096. {
  1097. typedef utf8_symbol_type type;
  1098. static type pre(utree const& t)
  1099. {
  1100. utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
  1101. return type(traits::begin(r), traits::end(r));
  1102. }
  1103. };
  1104. template <typename Attribute>
  1105. struct transform_attribute<utree::list_type const, Attribute, karma::domain>
  1106. : transform_attribute<utree const, Attribute, karma::domain>
  1107. {};
  1108. }}}
  1109. #endif