1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294 |
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2001-2011 Hartmut Kaiser
- Copyright (c) 2010-2011 Bryce Lelbach
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
- #if !defined(BOOST_SPIRIT_OUTPUT_UTREE_TRAITS_APR_16_2010_0655AM)
- #define BOOST_SPIRIT_OUTPUT_UTREE_TRAITS_APR_16_2010_0655AM
- #include <boost/spirit/home/support/attributes.hpp>
- #include <boost/spirit/home/support/container.hpp>
- #include <boost/spirit/home/support/utree.hpp>
- #include <boost/spirit/home/qi/domain.hpp>
- #include <boost/spirit/home/karma/domain.hpp>
- #include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
- #include <boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp>
- #include <string>
- #include <boost/cstdint.hpp>
- #include <boost/variant.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/identity.hpp>
- #include <boost/mpl/or.hpp>
- #include <boost/range/iterator_range_core.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/utility/enable_if.hpp>
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost
- {
- template <typename T>
- inline T get(boost::spirit::utree const& x)
- {
- return x.get<T>();
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost { namespace spirit { namespace traits
- {
- namespace detail
- {
- inline bool is_list(utree const& ut)
- {
- switch (traits::which(ut))
- {
- case utree_type::reference_type:
- return is_list(ut.deref());
- case utree_type::list_type:
- case utree_type::range_type:
- return true;
- default:
- break;
- }
- return false;
- }
- inline bool is_uninitialized(utree const& ut)
- {
- return traits::which(ut) == utree_type::invalid_type;
- }
- }
- // this specialization tells Spirit how to extract the type of the value
- // stored in the given utree node
- template <>
- struct variant_which<utree>
- {
- static int call(utree const& u) { return u.which(); }
- };
-
- template <>
- struct variant_which<utree::list_type>
- {
- static int call(utree::list_type const& u) { return u.which(); }
- };
- ///////////////////////////////////////////////////////////////////////////
- // Make sure all components of an alternative expose utree, even if they
- // actually expose a utree::list_type
- template <typename Domain>
- struct alternative_attribute_transform<utree::list_type, Domain>
- : mpl::identity<utree>
- {};
- ///////////////////////////////////////////////////////////////////////////
- // Make sure all components of a sequence expose utree, even if they
- // actually expose a utree::list_type
- template <typename Domain>
- struct sequence_attribute_transform<utree::list_type, Domain>
- : mpl::identity<utree>
- {};
- ///////////////////////////////////////////////////////////////////////////
- // this specialization lets Spirit know that typed basic_strings
- // are strings
- template <typename Base, utree_type::info I>
- struct is_string<spirit::basic_string<Base, I> >
- : mpl::true_
- {};
- ///////////////////////////////////////////////////////////////////////////
- // these specializations extract the character type of a utree typed string
- template <typename T, utree_type::info I>
- struct char_type_of<spirit::basic_string<iterator_range<T>, I> >
- : char_type_of<T>
- {};
- template <utree_type::info I>
- struct char_type_of<spirit::basic_string<std::string, I> >
- : mpl::identity<char>
- {};
- ///////////////////////////////////////////////////////////////////////////
- // these specializations extract a c string from a utree typed string
- template <typename String>
- struct extract_c_string;
- template <typename T, utree_type::info I>
- struct extract_c_string<
- spirit::basic_string<iterator_range<T const*>, I>
- > {
- typedef T char_type;
- typedef spirit::basic_string<iterator_range<T const*>, I> string;
- static T const* call (string& s)
- {
- return s.begin();
- }
- static T const* call (string const& s)
- {
- return s.begin();
- }
- };
-
- template <utree_type::info I>
- struct extract_c_string<spirit::basic_string<std::string, I> >
- {
- typedef char char_type;
- typedef spirit::basic_string<std::string, I> string;
- static char const* call (string& s)
- {
- return s.c_str();
- }
- static char const* call (string const& s)
- {
- return s.c_str();
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // these specializations are needed because utree::value_type == utree
- template <>
- struct is_substitute<utree, utree>
- : mpl::true_
- {};
- template <>
- struct is_weak_substitute<utree, utree>
- : mpl::true_
- {};
- template <>
- struct is_substitute<utree::list_type, utree::list_type>
- : mpl::true_
- {};
- template <>
- struct is_weak_substitute<utree::list_type, utree::list_type>
- : mpl::true_
- {};
- ///////////////////////////////////////////////////////////////////////////
- // this specialization tells Spirit.Qi to allow assignment to an utree from
- // a variant
- namespace detail
- {
- struct assign_to_utree_visitor : static_visitor<>
- {
- assign_to_utree_visitor(utree& ut) : ut_(ut) {}
- template <typename T>
- void operator()(T& val) const
- {
- ut_ = val;
- }
- utree& ut_;
- };
- }
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct assign_to_container_from_value<
- utree, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- {
- static void
- call(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& val, utree& attr)
- {
- apply_visitor(detail::assign_to_utree_visitor(attr), val);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // this specialization tells Spirit.Qi to allow assignment to an utree from
- // a STL container
- template <typename Attribute>
- struct assign_to_container_from_value<utree, Attribute>
- {
- // any non-container type will be either directly assigned or appended
- static void call(Attribute const& val, utree& attr, mpl::false_)
- {
- if (attr.empty())
- attr = val;
- else
- push_back(attr, val);
- }
- // any container type will be converted into a list_type utree
- static void call(Attribute const& val, utree& attr, mpl::true_)
- {
- typedef typename traits::container_iterator<Attribute const>::type
- iterator_type;
- // make sure the attribute is a list, at least an empty one
- if (attr.empty())
- attr = empty_list;
- iterator_type end = traits::end(val);
- for (iterator_type i = traits::begin(val); i != end; traits::next(i))
- push_back(attr, traits::deref(i));
- }
- static void call(Attribute const& val, utree& attr)
- {
- call(val, attr, is_container<Attribute>());
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // this specialization is required to disambiguate the specializations
- // related to utree
- template <>
- struct assign_to_container_from_value<utree, utree>
- {
- static void call(utree const& val, utree& attr)
- {
- if (attr.empty()) {
- attr = val;
- }
- else if (detail::is_list(val)) {
- typedef utree::const_iterator iterator_type;
- iterator_type end = traits::end(val);
- for (iterator_type i = traits::begin(val); i != end; traits::next(i))
- push_back(attr, traits::deref(i));
- }
- else {
- push_back(attr, val);
- }
- }
- };
- template <>
- struct assign_to_container_from_value<utree, utree::list_type>
- : assign_to_container_from_value<utree, utree>
- {};
- // If the destination is a utree_list, we need to force the right hand side
- // value into a new sub-node, always, no questions asked.
- template <>
- struct assign_to_container_from_value<utree::list_type, utree>
- {
- static void call(utree const& val, utree& attr)
- {
- push_back(attr, val);
- }
- };
- // If both, the right hand side and the left hand side are utree_lists
- // we have a lhs rule which has a single rule exposing a utree_list as its
- // rhs (optionally wrapped into a directive or other unary parser). In this
- // case we do not create a new sub-node.
- template <>
- struct assign_to_container_from_value<utree::list_type, utree::list_type>
- : assign_to_container_from_value<utree, utree>
- {};
- ///////////////////////////////////////////////////////////////////////////
- // this specialization makes sure strings get assigned as a whole and are
- // not converted into a utree list
- template <>
- struct assign_to_container_from_value<utree, utf8_string_type>
- {
- static void call(utf8_string_type const& val, utree& attr)
- {
- if (attr.empty())
- attr = val;
- else
- push_back(attr, val);
- }
- };
- // this specialization keeps symbols from being transformed into strings
- template<>
- struct assign_to_container_from_value<utree, utf8_symbol_type>
- {
- static void call (utf8_symbol_type const& val, utree& attr)
- {
- if (attr.empty())
- attr = val;
- else
- push_back(attr, val);
- }
- };
-
- template <>
- struct assign_to_container_from_value<utree, binary_string_type>
- {
- static void call(binary_string_type const& val, utree& attr)
- {
- if (attr.empty())
- attr = val;
- else
- push_back(attr, val);
- }
- };
- template<>
- struct assign_to_container_from_value<utree, utf8_symbol_range_type>
- {
- static void call (utf8_symbol_range_type const& val, utree& attr)
- {
- if (attr.empty())
- attr = val;
- else
- push_back(attr, val);
- }
- };
-
- template <>
- struct assign_to_container_from_value<utree, binary_range_type>
- {
- static void call(binary_range_type const& val, utree& attr)
- {
- if (attr.empty())
- attr = val;
- else
- push_back(attr, val);
- }
- };
- template <>
- struct assign_to_container_from_value<utree, std::string>
- {
- static void call(std::string const& val, utree& attr)
- {
- if (attr.empty())
- attr = val;
- else
- push_back(attr, val);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // this specialization tells Spirit.Qi to allow assignment to an utree from
- // generic iterators
- template <typename Iterator>
- struct assign_to_attribute_from_iterators<utree, Iterator>
- {
- static void
- call(Iterator const& first, Iterator const& last, utree& attr)
- {
- if (attr.empty())
- attr.assign(first, last);
- else {
- for (Iterator i = first; i != last; ++i)
- push_back(attr, traits::deref(i));
- }
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // Karma only: convert utree node to string
- namespace detail
- {
- struct attribute_as_string_type
- {
- typedef utf8_string_range_type type;
- static type call(utree const& attr)
- {
- return boost::get<utf8_string_range_type>(attr);
- }
- static bool is_valid(utree const& attr)
- {
- switch (traits::which(attr))
- {
- case utree_type::reference_type:
- return is_valid(attr.deref());
- case utree_type::string_range_type:
- case utree_type::string_type:
- return true;
- default:
- return false;
- }
- }
- };
- }
- template <>
- struct attribute_as<std::string, utree>
- : detail::attribute_as_string_type
- {};
- template <>
- struct attribute_as<utf8_string_type, utree>
- : detail::attribute_as_string_type
- {};
- template <>
- struct attribute_as<utf8_string_range_type, utree>
- : detail::attribute_as_string_type
- {};
- ///////////////////////////////////////////////////////////////////////////
- namespace detail
- {
- struct attribute_as_symbol_type
- {
- typedef utf8_symbol_range_type type;
- static type call(utree const& attr)
- {
- return boost::get<utf8_symbol_range_type>(attr);
- }
- static bool is_valid(utree const& attr)
- {
- switch (traits::which(attr))
- {
- case utree_type::reference_type:
- return is_valid(attr.deref());
- case utree_type::symbol_type:
- return true;
- default:
- return false;
- }
- }
- };
- }
- template <>
- struct attribute_as<utf8_symbol_type, utree>
- : detail::attribute_as_symbol_type
- {};
- template <>
- struct attribute_as<utf8_symbol_range_type, utree>
- : detail::attribute_as_symbol_type
- {};
-
- template <typename Attribute>
- struct attribute_as<Attribute, utree::list_type>
- : attribute_as<Attribute, utree>
- {};
- ///////////////////////////////////////////////////////////////////////////
- namespace detail
- {
- struct attribute_as_binary_string_type
- {
- typedef binary_range_type type;
- static type call(utree const& attr)
- {
- return boost::get<binary_range_type>(attr);
- }
- static bool is_valid(utree const& attr)
- {
- switch (traits::which(attr))
- {
- case utree_type::reference_type:
- return is_valid(attr.deref());
- case utree_type::binary_type:
- return true;
- default:
- return false;
- }
- }
- };
- }
- template <>
- struct attribute_as<binary_string_type, utree>
- : detail::attribute_as_binary_string_type
- {};
- template <>
- struct attribute_as<binary_range_type, utree>
- : detail::attribute_as_binary_string_type
- {};
- ///////////////////////////////////////////////////////////////////////////
- // push_back support for utree
- template <typename T>
- struct push_back_container<utree, T>
- {
- static bool call(utree& c, T const& val)
- {
- switch (traits::which(c))
- {
- case utree_type::invalid_type:
- case utree_type::nil_type:
- case utree_type::list_type:
- c.push_back(val);
- break;
- default:
- {
- utree ut;
- ut.push_back(c);
- ut.push_back(val);
- c.swap(ut);
- }
- break;
- }
- return true;
- }
- };
- template <typename T>
- struct push_back_container<utree::list_type, T>
- : push_back_container<utree, T>
- {};
- ///////////////////////////////////////////////////////////////////////////
- // ensure the utree attribute is an empty list
- template <>
- struct make_container_attribute<utree>
- {
- static void call(utree& ut)
- {
- if (!detail::is_list(ut)) {
- if (detail::is_uninitialized(ut))
- ut = empty_list;
- else {
- utree retval (empty_list);
- retval.push_back(ut);
- ut.swap(retval);
- }
- }
- }
- };
- template <>
- struct make_container_attribute<utree::list_type>
- : make_container_attribute<utree>
- {};
- ///////////////////////////////////////////////////////////////////////////
- // an utree is a container on its own
- template <>
- struct build_std_vector<utree>
- {
- typedef utree type;
- };
- template <>
- struct build_std_vector<utree::list_type>
- {
- typedef utree::list_type type;
- };
- ///////////////////////////////////////////////////////////////////////////
- // debug support for utree
- template <typename Out>
- struct print_attribute_debug<Out, utree>
- {
- static void call(Out& out, utree const& val)
- {
- out << val;
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // force utree list attribute in a sequence to be dereferenced if a rule
- // or a grammar exposes an utree as it's attribute
- namespace detail
- {
- // Checks whether the exposed Attribute allows to handle utree or
- // utree::list_type directly. Returning mpl::false_ from this meta
- // function will force a new utree instance to be created for each
- // invocation of the embedded parser.
- // The purpose of using utree::list_type as an attribute is to force a
- // new sub-node in the result.
- template <typename Attribute, typename Enable = void>
- struct handles_utree_list_container
- : mpl::and_<
- mpl::not_<is_same<utree::list_type, Attribute> >,
- traits::is_container<Attribute> >
- {};
- // The following specializations make sure that the actual handling of
- // an utree (or utree::list_type) attribute is deferred to the embedded
- // parsers of a sequence, alternative or optional component.
- template <typename Attribute>
- struct handles_utree_list_container<Attribute
- , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
- : mpl::true_
- {};
- template <typename Attribute>
- struct handles_utree_list_container<boost::optional<Attribute> >
- : mpl::true_
- {};
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct handles_utree_list_container<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- : mpl::true_
- {};
- }
- template <
- typename IteratorA, typename IteratorB, typename Context
- , typename T1, typename T2, typename T3, typename T4>
- struct handles_container<qi::rule<IteratorA, T1, T2, T3, T4>
- , utree, Context, IteratorB>
- : detail::handles_utree_list_container<typename attribute_of<
- qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
- >::type>
- {};
- template <
- typename IteratorA, typename IteratorB, typename Context
- , typename T1, typename T2, typename T3, typename T4>
- struct handles_container<qi::grammar<IteratorA, T1, T2, T3, T4>
- , utree, Context, IteratorB>
- : detail::handles_utree_list_container<typename attribute_of<
- qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
- >::type>
- {};
- template <
- typename IteratorA, typename IteratorB, typename Context
- , typename T1, typename T2, typename T3, typename T4>
- struct handles_container<qi::rule<IteratorA, T1, T2, T3, T4>
- , utree::list_type, Context, IteratorB>
- : detail::handles_utree_list_container<typename attribute_of<
- qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
- >::type>
- {};
- template <
- typename IteratorA, typename IteratorB, typename Context
- , typename T1, typename T2, typename T3, typename T4>
- struct handles_container<qi::grammar<IteratorA, T1, T2, T3, T4>
- , utree::list_type, Context, IteratorB>
- : detail::handles_utree_list_container<typename attribute_of<
- qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
- >::type>
- {};
- ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename Sequence>
- struct pass_through_container<
- utree, utree, Attribute, Sequence, qi::domain>
- : detail::handles_utree_list_container<Attribute>
- {};
- template <typename Attribute, typename Sequence>
- struct pass_through_container<
- utree::list_type, utree, Attribute, Sequence, qi::domain>
- : detail::handles_utree_list_container<Attribute>
- {};
- ///////////////////////////////////////////////////////////////////////////
- namespace detail
- {
- // Checks whether the exposed Attribute allows to handle utree or
- // utree::list_type directly. Returning mpl::false_ from this meta
- // function will force a new utree instance to be created for each
- // invocation of the embedded parser.
- // The purpose of using utree::list_type as an attribute is to force a
- // new sub-node in the result.
- template <typename Attribute, typename Enable = void>
- struct handles_utree_container
- : mpl::and_<
- mpl::not_<is_same<utree, Attribute> >,
- traits::is_container<Attribute> >
- {};
- // The following specializations make sure that the actual handling of
- // an utree (or utree::list_type) attribute is deferred to the embedded
- // parsers of a sequence, alternative or optional component.
- template <typename Attribute>
- struct handles_utree_container<Attribute
- , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
- : mpl::true_
- {};
- template <typename Attribute>
- struct handles_utree_container<boost::optional<Attribute> >
- : mpl::true_
- {};
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct handles_utree_container<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- : mpl::true_
- {};
- }
- template <
- typename IteratorA, typename IteratorB, typename Context
- , typename T1, typename T2, typename T3, typename T4>
- struct handles_container<karma::rule<IteratorA, T1, T2, T3, T4>
- , utree, Context, IteratorB>
- : detail::handles_utree_container<typename attribute_of<
- karma::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
- >::type>
- {};
- template <
- typename IteratorA, typename IteratorB, typename Context
- , typename T1, typename T2, typename T3, typename T4>
- struct handles_container<karma::grammar<IteratorA, T1, T2, T3, T4>
- , utree, Context, IteratorB>
- : detail::handles_utree_container<typename attribute_of<
- karma::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
- >::type>
- {};
- ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename Sequence>
- struct pass_through_container<
- utree, utree, Attribute, Sequence, karma::domain>
- : detail::handles_utree_container<Attribute>
- {};
- ///////////////////////////////////////////////////////////////////////////
- // the specialization below tells Spirit how to handle utree if it is used
- // with an optional component
- template <>
- struct optional_attribute<utree>
- {
- typedef utree const& type;
- static type call(utree const& val)
- {
- return val;
- }
- // only 'invalid_type' utree nodes are not valid
- static bool is_valid(utree const& val)
- {
- return !detail::is_uninitialized(val);
- }
- };
- template <>
- struct build_optional<utree>
- {
- typedef utree type;
- };
- template <>
- struct build_optional<utree::list_type>
- {
- typedef utree::list_type type;
- };
- // an utree is an optional (in any domain)
- template <>
- struct not_is_optional<utree, qi::domain>
- : mpl::false_
- {};
- template <>
- struct not_is_optional<utree::list_type, qi::domain>
- : mpl::false_
- {};
- template <>
- struct not_is_optional<utree, karma::domain>
- : mpl::false_
- {};
- template <>
- struct not_is_optional<utree::list_type, karma::domain>
- : mpl::false_
- {};
- ///////////////////////////////////////////////////////////////////////////
- // the specialization below tells Spirit to handle utree as if it
- // where a 'real' variant (in the context of karma)
- template <>
- struct not_is_variant<utree, karma::domain>
- : mpl::false_
- {};
- template <>
- struct not_is_variant<utree::list_type, karma::domain>
- : mpl::false_
- {};
- // The specializations below tell Spirit to verify whether an attribute
- // type is compatible with a given variant type
- template <>
- struct compute_compatible_component_variant<
- utree, iterator_range<utree::iterator> >
- : mpl::true_
- {
- typedef iterator_range<utree::iterator> compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::list_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<
- utree, iterator_range<utree::const_iterator> >
- : mpl::true_
- {
- typedef iterator_range<utree::const_iterator> compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::list_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<utree, utree::invalid_type>
- : mpl::true_
- {
- typedef utree::invalid_type compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::invalid_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<utree, utree::nil_type>
- : mpl::true_
- {
- typedef utree::nil_type compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::nil_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<utree, bool>
- : mpl::true_
- {
- typedef bool compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::bool_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<utree, int>
- : mpl::true_
- {
- typedef int compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::int_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<utree, double>
- : mpl::true_
- {
- typedef double compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::double_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<
- utree, utf8_string_range_type>
- : mpl::true_
- {
- typedef utf8_string_range_type compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::string_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<
- utree, utf8_string_type>
- : mpl::true_
- {
- typedef utf8_string_type compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::string_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<
- utree, utf8_symbol_range_type>
- : mpl::true_
- {
- typedef utf8_symbol_range_type compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::symbol_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<
- utree, utf8_symbol_type>
- : mpl::true_
- {
- typedef utf8_symbol_type compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::symbol_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<
- utree, binary_range_type>
- : mpl::true_
- {
- typedef binary_range_type compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::binary_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<
- utree, binary_string_type>
- : mpl::true_
- {
- typedef binary_string_type compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::binary_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<utree, utree>
- : mpl::true_
- {
- typedef utree compatible_type;
- static bool is_compatible(int d)
- {
- return d >= utree_type::invalid_type &&
- d <= utree_type::reference_type;
- }
- };
- template <>
- struct compute_compatible_component_variant<
- utree, std::vector<utree> >
- : mpl::true_
- {
- typedef utree compatible_type;
- static bool is_compatible(int d)
- {
- return d >= utree_type::invalid_type &&
- d <= utree_type::reference_type;
- }
- };
- template <typename Sequence>
- struct compute_compatible_component_variant<utree, Sequence
- , mpl::false_
- , typename enable_if<fusion::traits::is_sequence<Sequence> >::type>
- : mpl::true_
- {
- typedef iterator_range<utree::const_iterator> compatible_type;
- static bool is_compatible(int d)
- {
- return d == utree_type::list_type;
- }
- };
- template <typename Attribute>
- struct compute_compatible_component_variant<utree::list_type, Attribute>
- : compute_compatible_component_variant<utree, Attribute>
- {};
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct symbols_lookup<utree, utf8_symbol_type>
- {
- typedef std::string type;
- static type call(utree const& t)
- {
- utf8_symbol_range_type r = boost::get<utf8_symbol_range_type>(t);
- return std::string(traits::begin(r), traits::end(r));
- }
- };
- template <>
- struct symbols_lookup<utf8_symbol_type, utf8_symbol_type>
- {
- typedef std::string type;
- static type call(utf8_symbol_type const& t)
- {
- return t;
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- namespace detail
- {
- template <typename T>
- inline T get_or_deref(utree const& t)
- {
- if (detail::is_list(t))
- return boost::get<T>(t.front());
- return boost::get<T>(t);
- }
- }
- template <>
- struct extract_from_container<utree, utree::nil_type>
- {
- typedef utree::nil_type type;
- template <typename Context>
- static type call(utree const&, Context&)
- {
- return nil;
- }
- };
- template <>
- struct extract_from_container<utree, char>
- {
- typedef char type;
- template <typename Context>
- static type call(utree const& t, Context&)
- {
- utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
- return r.front();
- }
- };
- template <>
- struct extract_from_container<utree, bool>
- {
- typedef bool type;
- template <typename Context>
- static type call(utree const& t, Context&)
- {
- return detail::get_or_deref<bool>(t);
- }
- };
- template <>
- struct extract_from_container<utree, int>
- {
- typedef int type;
- template <typename Context>
- static type call(utree const& t, Context&)
- {
- return detail::get_or_deref<int>(t);
- }
- };
- template <>
- struct extract_from_container<utree, double>
- {
- typedef double type;
- template <typename Context>
- static type call(utree const& t, Context&)
- {
- return detail::get_or_deref<double>(t);
- }
- };
- template <typename Traits, typename Alloc>
- struct extract_from_container<utree, std::basic_string<char, Traits, Alloc> >
- {
- typedef std::basic_string<char, Traits, Alloc> type;
- template <typename Context>
- static type call(utree const& t, Context&)
- {
- utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
- return type(traits::begin(r), traits::end(r));
- }
- };
- template <>
- struct extract_from_container<utree, utf8_symbol_type>
- {
- typedef utf8_symbol_type type;
- template <typename Context>
- static type call(utree const& t, Context&)
- {
- utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
- return type(traits::begin(r), traits::end(r));
- }
- };
- template <>
- struct extract_from_container<utree, utf8_string_type>
- {
- typedef utf8_string_type type;
- template <typename Context>
- static type call(utree const& t, Context&)
- {
- utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
- return type(traits::begin(r), traits::end(r));
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct transform_attribute<utree const, utree::nil_type, karma::domain>
- {
- typedef utree::nil_type type;
- static type pre(utree const&)
- {
- return nil;
- }
- };
- template <>
- struct transform_attribute<utree const, char, karma::domain>
- {
- typedef char type;
- static type pre(utree const& t)
- {
- utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
- return r.front();
- }
- };
- template <>
- struct transform_attribute<utree const, bool, karma::domain>
- {
- typedef bool type;
- static type pre(utree const& t)
- {
- return detail::get_or_deref<bool>(t);
- }
- };
- template <>
- struct transform_attribute<utree const, int, karma::domain>
- {
- typedef int type;
- static type pre(utree const& t)
- {
- return detail::get_or_deref<int>(t);
- }
- };
- template <>
- struct transform_attribute<utree const, double, karma::domain>
- {
- typedef double type;
- static type pre(utree const& t)
- {
- return detail::get_or_deref<double>(t);
- }
- };
- template <typename Traits, typename Alloc>
- struct transform_attribute<
- utree const, std::basic_string<char, Traits, Alloc>, karma::domain>
- {
- typedef std::basic_string<char, Traits, Alloc> type;
- static type pre(utree const& t)
- {
- utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
- return type(traits::begin(r), traits::end(r));
- }
- };
- // this specialization is used whenever a utree is passed to a rule as part
- // of a sequence
- template <typename Iterator>
- struct transform_attribute<
- iterator_range<Iterator> const, utree, karma::domain>
- {
- typedef utree type;
- static type pre(iterator_range<Iterator> const& t)
- {
- // return utree the begin iterator points to
- Iterator it = t.begin();
- utree result(boost::ref(*it));
- ++it;
- return result;
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct transform_attribute<utree const, utf8_string_type, karma::domain>
- {
- typedef utf8_string_type type;
- static type pre(utree const& t)
- {
- utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
- return type(traits::begin(r), traits::end(r));
- }
- };
- template <>
- struct transform_attribute<utree const, utf8_symbol_type, karma::domain>
- {
- typedef utf8_symbol_type type;
- static type pre(utree const& t)
- {
- utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
- return type(traits::begin(r), traits::end(r));
- }
- };
- template <typename Attribute>
- struct transform_attribute<utree::list_type const, Attribute, karma::domain>
- : transform_attribute<utree const, Attribute, karma::domain>
- {};
- }}}
- #endif
|