File indexing completed on 2025-01-19 09:47:53
0001
0002
0003
0004
0005
0006
0007
0008
0009 #if !defined(BOOST_SPIRIT_OUTPUT_UTREE_TRAITS_APR_16_2010_0655AM)
0010 #define BOOST_SPIRIT_OUTPUT_UTREE_TRAITS_APR_16_2010_0655AM
0011
0012 #include <boost/spirit/home/support/attributes.hpp>
0013 #include <boost/spirit/home/support/container.hpp>
0014 #include <boost/spirit/home/support/utree.hpp>
0015 #include <boost/spirit/home/qi/domain.hpp>
0016 #include <boost/spirit/home/karma/domain.hpp>
0017 #include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
0018 #include <boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp>
0019
0020 #include <string>
0021
0022 #include <boost/cstdint.hpp>
0023 #include <boost/variant.hpp>
0024 #include <boost/mpl/bool.hpp>
0025 #include <boost/mpl/identity.hpp>
0026 #include <boost/mpl/or.hpp>
0027 #include <boost/range/iterator_range_core.hpp>
0028 #include <boost/type_traits/is_same.hpp>
0029 #include <boost/utility/enable_if.hpp>
0030
0031
0032 namespace boost
0033 {
0034 template <typename T>
0035 inline T get(boost::spirit::utree const& x)
0036 {
0037 return x.get<T>();
0038 }
0039 }
0040
0041
0042 namespace boost { namespace spirit { namespace traits
0043 {
0044 namespace detail
0045 {
0046 inline bool is_list(utree const& ut)
0047 {
0048 switch (traits::which(ut))
0049 {
0050 case utree_type::reference_type:
0051 return is_list(ut.deref());
0052
0053 case utree_type::list_type:
0054 case utree_type::range_type:
0055 return true;
0056
0057 default:
0058 break;
0059 }
0060 return false;
0061 }
0062
0063 inline bool is_uninitialized(utree const& ut)
0064 {
0065 return traits::which(ut) == utree_type::invalid_type;
0066 }
0067 }
0068
0069
0070
0071 template <>
0072 struct variant_which<utree>
0073 {
0074 static int call(utree const& u) { return u.which(); }
0075 };
0076
0077 template <>
0078 struct variant_which<utree::list_type>
0079 {
0080 static int call(utree::list_type const& u) { return u.which(); }
0081 };
0082
0083
0084
0085
0086 template <typename Domain>
0087 struct alternative_attribute_transform<utree::list_type, Domain>
0088 : mpl::identity<utree>
0089 {};
0090
0091
0092
0093
0094 template <typename Domain>
0095 struct sequence_attribute_transform<utree::list_type, Domain>
0096 : mpl::identity<utree>
0097 {};
0098
0099
0100
0101
0102 template <typename Base, utree_type::info I>
0103 struct is_string<spirit::basic_string<Base, I> >
0104 : mpl::true_
0105 {};
0106
0107
0108
0109 template <typename T, utree_type::info I>
0110 struct char_type_of<spirit::basic_string<iterator_range<T>, I> >
0111 : char_type_of<T>
0112 {};
0113
0114 template <utree_type::info I>
0115 struct char_type_of<spirit::basic_string<std::string, I> >
0116 : mpl::identity<char>
0117 {};
0118
0119
0120
0121 template <typename String>
0122 struct extract_c_string;
0123
0124 template <typename T, utree_type::info I>
0125 struct extract_c_string<
0126 spirit::basic_string<iterator_range<T const*>, I>
0127 > {
0128 typedef T char_type;
0129
0130 typedef spirit::basic_string<iterator_range<T const*>, I> string;
0131
0132 static T const* call (string& s)
0133 {
0134 return s.begin();
0135 }
0136
0137 static T const* call (string const& s)
0138 {
0139 return s.begin();
0140 }
0141 };
0142
0143 template <utree_type::info I>
0144 struct extract_c_string<spirit::basic_string<std::string, I> >
0145 {
0146 typedef char char_type;
0147
0148 typedef spirit::basic_string<std::string, I> string;
0149
0150 static char const* call (string& s)
0151 {
0152 return s.c_str();
0153 }
0154
0155 static char const* call (string const& s)
0156 {
0157 return s.c_str();
0158 }
0159 };
0160
0161
0162
0163 template <>
0164 struct is_substitute<utree, utree>
0165 : mpl::true_
0166 {};
0167
0168 template <>
0169 struct is_weak_substitute<utree, utree>
0170 : mpl::true_
0171 {};
0172
0173 template <>
0174 struct is_substitute<utree::list_type, utree::list_type>
0175 : mpl::true_
0176 {};
0177
0178 template <>
0179 struct is_weak_substitute<utree::list_type, utree::list_type>
0180 : mpl::true_
0181 {};
0182
0183
0184
0185
0186 namespace detail
0187 {
0188 struct assign_to_utree_visitor : static_visitor<>
0189 {
0190 assign_to_utree_visitor(utree& ut) : ut_(ut) {}
0191
0192 template <typename T>
0193 void operator()(T& val) const
0194 {
0195 ut_ = val;
0196 }
0197
0198 utree& ut_;
0199 };
0200 }
0201
0202 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
0203 struct assign_to_container_from_value<
0204 utree, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
0205 {
0206 static void
0207 call(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& val, utree& attr)
0208 {
0209 apply_visitor(detail::assign_to_utree_visitor(attr), val);
0210 }
0211 };
0212
0213
0214
0215
0216 template <typename Attribute>
0217 struct assign_to_container_from_value<utree, Attribute>
0218 {
0219
0220 static void call(Attribute const& val, utree& attr, mpl::false_)
0221 {
0222 if (attr.empty())
0223 attr = val;
0224 else
0225 push_back(attr, val);
0226 }
0227
0228
0229 static void call(Attribute const& val, utree& attr, mpl::true_)
0230 {
0231 typedef typename traits::container_iterator<Attribute const>::type
0232 iterator_type;
0233
0234
0235 if (attr.empty())
0236 attr = empty_list;
0237
0238 iterator_type end = traits::end(val);
0239 for (iterator_type i = traits::begin(val); i != end; traits::next(i))
0240 push_back(attr, traits::deref(i));
0241 }
0242
0243 static void call(Attribute const& val, utree& attr)
0244 {
0245 call(val, attr, is_container<Attribute>());
0246 }
0247 };
0248
0249
0250
0251
0252 template <>
0253 struct assign_to_container_from_value<utree, utree>
0254 {
0255 static void call(utree const& val, utree& attr)
0256 {
0257 if (attr.empty()) {
0258 attr = val;
0259 }
0260 else if (detail::is_list(val)) {
0261 typedef utree::const_iterator iterator_type;
0262
0263 iterator_type end = traits::end(val);
0264 for (iterator_type i = traits::begin(val); i != end; traits::next(i))
0265 push_back(attr, traits::deref(i));
0266 }
0267 else {
0268 push_back(attr, val);
0269 }
0270 }
0271 };
0272
0273 template <>
0274 struct assign_to_container_from_value<utree, utree::list_type>
0275 : assign_to_container_from_value<utree, utree>
0276 {};
0277
0278
0279
0280 template <>
0281 struct assign_to_container_from_value<utree::list_type, utree>
0282 {
0283 static void call(utree const& val, utree& attr)
0284 {
0285 push_back(attr, val);
0286 }
0287 };
0288
0289
0290
0291
0292
0293 template <>
0294 struct assign_to_container_from_value<utree::list_type, utree::list_type>
0295 : assign_to_container_from_value<utree, utree>
0296 {};
0297
0298
0299
0300
0301 template <>
0302 struct assign_to_container_from_value<utree, utf8_string_type>
0303 {
0304 static void call(utf8_string_type const& val, utree& attr)
0305 {
0306 if (attr.empty())
0307 attr = val;
0308 else
0309 push_back(attr, val);
0310 }
0311 };
0312
0313
0314 template<>
0315 struct assign_to_container_from_value<utree, utf8_symbol_type>
0316 {
0317 static void call (utf8_symbol_type const& val, utree& attr)
0318 {
0319 if (attr.empty())
0320 attr = val;
0321 else
0322 push_back(attr, val);
0323 }
0324 };
0325
0326 template <>
0327 struct assign_to_container_from_value<utree, binary_string_type>
0328 {
0329 static void call(binary_string_type const& val, utree& attr)
0330 {
0331 if (attr.empty())
0332 attr = val;
0333 else
0334 push_back(attr, val);
0335 }
0336 };
0337
0338 template<>
0339 struct assign_to_container_from_value<utree, utf8_symbol_range_type>
0340 {
0341 static void call (utf8_symbol_range_type const& val, utree& attr)
0342 {
0343 if (attr.empty())
0344 attr = val;
0345 else
0346 push_back(attr, val);
0347 }
0348 };
0349
0350 template <>
0351 struct assign_to_container_from_value<utree, binary_range_type>
0352 {
0353 static void call(binary_range_type const& val, utree& attr)
0354 {
0355 if (attr.empty())
0356 attr = val;
0357 else
0358 push_back(attr, val);
0359 }
0360 };
0361
0362 template <>
0363 struct assign_to_container_from_value<utree, std::string>
0364 {
0365 static void call(std::string const& val, utree& attr)
0366 {
0367 if (attr.empty())
0368 attr = val;
0369 else
0370 push_back(attr, val);
0371 }
0372 };
0373
0374
0375
0376
0377 template <typename Iterator>
0378 struct assign_to_attribute_from_iterators<utree, Iterator>
0379 {
0380 static void
0381 call(Iterator const& first, Iterator const& last, utree& attr)
0382 {
0383 if (attr.empty())
0384 attr.assign(first, last);
0385 else {
0386 for (Iterator i = first; i != last; ++i)
0387 push_back(attr, traits::deref(i));
0388 }
0389 }
0390 };
0391
0392
0393
0394 namespace detail
0395 {
0396 struct attribute_as_string_type
0397 {
0398 typedef utf8_string_range_type type;
0399
0400 static type call(utree const& attr)
0401 {
0402 return boost::get<utf8_string_range_type>(attr);
0403 }
0404
0405 static bool is_valid(utree const& attr)
0406 {
0407 switch (traits::which(attr))
0408 {
0409 case utree_type::reference_type:
0410 return is_valid(attr.deref());
0411
0412 case utree_type::string_range_type:
0413 case utree_type::string_type:
0414 return true;
0415
0416 default:
0417 return false;
0418 }
0419 }
0420 };
0421 }
0422
0423 template <>
0424 struct attribute_as<std::string, utree>
0425 : detail::attribute_as_string_type
0426 {};
0427
0428 template <>
0429 struct attribute_as<utf8_string_type, utree>
0430 : detail::attribute_as_string_type
0431 {};
0432
0433 template <>
0434 struct attribute_as<utf8_string_range_type, utree>
0435 : detail::attribute_as_string_type
0436 {};
0437
0438
0439 namespace detail
0440 {
0441 struct attribute_as_symbol_type
0442 {
0443 typedef utf8_symbol_range_type type;
0444
0445 static type call(utree const& attr)
0446 {
0447 return boost::get<utf8_symbol_range_type>(attr);
0448 }
0449
0450 static bool is_valid(utree const& attr)
0451 {
0452 switch (traits::which(attr))
0453 {
0454 case utree_type::reference_type:
0455 return is_valid(attr.deref());
0456
0457 case utree_type::symbol_type:
0458 return true;
0459
0460 default:
0461 return false;
0462 }
0463 }
0464 };
0465 }
0466
0467 template <>
0468 struct attribute_as<utf8_symbol_type, utree>
0469 : detail::attribute_as_symbol_type
0470 {};
0471
0472 template <>
0473 struct attribute_as<utf8_symbol_range_type, utree>
0474 : detail::attribute_as_symbol_type
0475 {};
0476
0477 template <typename Attribute>
0478 struct attribute_as<Attribute, utree::list_type>
0479 : attribute_as<Attribute, utree>
0480 {};
0481
0482
0483 namespace detail
0484 {
0485 struct attribute_as_binary_string_type
0486 {
0487 typedef binary_range_type type;
0488
0489 static type call(utree const& attr)
0490 {
0491 return boost::get<binary_range_type>(attr);
0492 }
0493
0494 static bool is_valid(utree const& attr)
0495 {
0496 switch (traits::which(attr))
0497 {
0498 case utree_type::reference_type:
0499 return is_valid(attr.deref());
0500
0501 case utree_type::binary_type:
0502 return true;
0503
0504 default:
0505 return false;
0506 }
0507 }
0508 };
0509 }
0510
0511 template <>
0512 struct attribute_as<binary_string_type, utree>
0513 : detail::attribute_as_binary_string_type
0514 {};
0515
0516 template <>
0517 struct attribute_as<binary_range_type, utree>
0518 : detail::attribute_as_binary_string_type
0519 {};
0520
0521
0522
0523 template <typename T>
0524 struct push_back_container<utree, T>
0525 {
0526 static bool call(utree& c, T const& val)
0527 {
0528 switch (traits::which(c))
0529 {
0530 case utree_type::invalid_type:
0531 case utree_type::nil_type:
0532 case utree_type::list_type:
0533 c.push_back(val);
0534 break;
0535
0536 default:
0537 {
0538 utree ut;
0539 ut.push_back(c);
0540 ut.push_back(val);
0541 c.swap(ut);
0542 }
0543 break;
0544 }
0545 return true;
0546 }
0547 };
0548
0549 template <typename T>
0550 struct push_back_container<utree::list_type, T>
0551 : push_back_container<utree, T>
0552 {};
0553
0554
0555
0556 template <>
0557 struct make_container_attribute<utree>
0558 {
0559 static void call(utree& ut)
0560 {
0561 if (!detail::is_list(ut)) {
0562 if (detail::is_uninitialized(ut))
0563 ut = empty_list;
0564 else {
0565 utree retval (empty_list);
0566 retval.push_back(ut);
0567 ut.swap(retval);
0568 }
0569 }
0570 }
0571 };
0572
0573 template <>
0574 struct make_container_attribute<utree::list_type>
0575 : make_container_attribute<utree>
0576 {};
0577
0578
0579
0580 template <>
0581 struct build_std_vector<utree>
0582 {
0583 typedef utree type;
0584 };
0585
0586 template <>
0587 struct build_std_vector<utree::list_type>
0588 {
0589 typedef utree::list_type type;
0590 };
0591
0592
0593
0594 template <typename Out>
0595 struct print_attribute_debug<Out, utree>
0596 {
0597 static void call(Out& out, utree const& val)
0598 {
0599 out << val;
0600 }
0601 };
0602
0603
0604
0605
0606 namespace detail
0607 {
0608
0609
0610
0611
0612
0613
0614
0615 template <typename Attribute, typename Enable = void>
0616 struct handles_utree_list_container
0617 : mpl::and_<
0618 mpl::not_<is_same<utree::list_type, Attribute> >,
0619 traits::is_container<Attribute> >
0620 {};
0621
0622
0623
0624
0625 template <typename Attribute>
0626 struct handles_utree_list_container<Attribute
0627 , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
0628 : mpl::true_
0629 {};
0630
0631 template <typename Attribute>
0632 struct handles_utree_list_container<boost::optional<Attribute> >
0633 : mpl::true_
0634 {};
0635
0636 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
0637 struct handles_utree_list_container<
0638 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
0639 : mpl::true_
0640 {};
0641 }
0642
0643 template <
0644 typename IteratorA, typename IteratorB, typename Context
0645 , typename T1, typename T2, typename T3, typename T4>
0646 struct handles_container<qi::rule<IteratorA, T1, T2, T3, T4>
0647 , utree, Context, IteratorB>
0648 : detail::handles_utree_list_container<typename attribute_of<
0649 qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
0650 >::type>
0651 {};
0652
0653 template <
0654 typename IteratorA, typename IteratorB, typename Context
0655 , typename T1, typename T2, typename T3, typename T4>
0656 struct handles_container<qi::grammar<IteratorA, T1, T2, T3, T4>
0657 , utree, Context, IteratorB>
0658 : detail::handles_utree_list_container<typename attribute_of<
0659 qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
0660 >::type>
0661 {};
0662
0663 template <
0664 typename IteratorA, typename IteratorB, typename Context
0665 , typename T1, typename T2, typename T3, typename T4>
0666 struct handles_container<qi::rule<IteratorA, T1, T2, T3, T4>
0667 , utree::list_type, Context, IteratorB>
0668 : detail::handles_utree_list_container<typename attribute_of<
0669 qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
0670 >::type>
0671 {};
0672
0673 template <
0674 typename IteratorA, typename IteratorB, typename Context
0675 , typename T1, typename T2, typename T3, typename T4>
0676 struct handles_container<qi::grammar<IteratorA, T1, T2, T3, T4>
0677 , utree::list_type, Context, IteratorB>
0678 : detail::handles_utree_list_container<typename attribute_of<
0679 qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
0680 >::type>
0681 {};
0682
0683
0684 template <typename Attribute, typename Sequence>
0685 struct pass_through_container<
0686 utree, utree, Attribute, Sequence, qi::domain>
0687 : detail::handles_utree_list_container<Attribute>
0688 {};
0689
0690 template <typename Attribute, typename Sequence>
0691 struct pass_through_container<
0692 utree::list_type, utree, Attribute, Sequence, qi::domain>
0693 : detail::handles_utree_list_container<Attribute>
0694 {};
0695
0696
0697 namespace detail
0698 {
0699
0700
0701
0702
0703
0704
0705
0706 template <typename Attribute, typename Enable = void>
0707 struct handles_utree_container
0708 : mpl::and_<
0709 mpl::not_<is_same<utree, Attribute> >,
0710 traits::is_container<Attribute> >
0711 {};
0712
0713
0714
0715
0716 template <typename Attribute>
0717 struct handles_utree_container<Attribute
0718 , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
0719 : mpl::true_
0720 {};
0721
0722 template <typename Attribute>
0723 struct handles_utree_container<boost::optional<Attribute> >
0724 : mpl::true_
0725 {};
0726
0727 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
0728 struct handles_utree_container<
0729 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
0730 : mpl::true_
0731 {};
0732 }
0733
0734 template <
0735 typename IteratorA, typename IteratorB, typename Context
0736 , typename T1, typename T2, typename T3, typename T4>
0737 struct handles_container<karma::rule<IteratorA, T1, T2, T3, T4>
0738 , utree, Context, IteratorB>
0739 : detail::handles_utree_container<typename attribute_of<
0740 karma::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
0741 >::type>
0742 {};
0743
0744 template <
0745 typename IteratorA, typename IteratorB, typename Context
0746 , typename T1, typename T2, typename T3, typename T4>
0747 struct handles_container<karma::grammar<IteratorA, T1, T2, T3, T4>
0748 , utree, Context, IteratorB>
0749 : detail::handles_utree_container<typename attribute_of<
0750 karma::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
0751 >::type>
0752 {};
0753
0754
0755 template <typename Attribute, typename Sequence>
0756 struct pass_through_container<
0757 utree, utree, Attribute, Sequence, karma::domain>
0758 : detail::handles_utree_container<Attribute>
0759 {};
0760
0761
0762
0763
0764 template <>
0765 struct optional_attribute<utree>
0766 {
0767 typedef utree const& type;
0768
0769 static type call(utree const& val)
0770 {
0771 return val;
0772 }
0773
0774
0775 static bool is_valid(utree const& val)
0776 {
0777 return !detail::is_uninitialized(val);
0778 }
0779 };
0780
0781 template <>
0782 struct build_optional<utree>
0783 {
0784 typedef utree type;
0785 };
0786
0787 template <>
0788 struct build_optional<utree::list_type>
0789 {
0790 typedef utree::list_type type;
0791 };
0792
0793
0794 template <>
0795 struct not_is_optional<utree, qi::domain>
0796 : mpl::false_
0797 {};
0798
0799 template <>
0800 struct not_is_optional<utree::list_type, qi::domain>
0801 : mpl::false_
0802 {};
0803
0804 template <>
0805 struct not_is_optional<utree, karma::domain>
0806 : mpl::false_
0807 {};
0808
0809 template <>
0810 struct not_is_optional<utree::list_type, karma::domain>
0811 : mpl::false_
0812 {};
0813
0814
0815
0816
0817 template <>
0818 struct not_is_variant<utree, karma::domain>
0819 : mpl::false_
0820 {};
0821
0822 template <>
0823 struct not_is_variant<utree::list_type, karma::domain>
0824 : mpl::false_
0825 {};
0826
0827
0828
0829 template <>
0830 struct compute_compatible_component_variant<
0831 utree, iterator_range<utree::iterator> >
0832 : mpl::true_
0833 {
0834 typedef iterator_range<utree::iterator> compatible_type;
0835
0836 static bool is_compatible(int d)
0837 {
0838 return d == utree_type::list_type;
0839 }
0840 };
0841
0842 template <>
0843 struct compute_compatible_component_variant<
0844 utree, iterator_range<utree::const_iterator> >
0845 : mpl::true_
0846 {
0847 typedef iterator_range<utree::const_iterator> compatible_type;
0848
0849 static bool is_compatible(int d)
0850 {
0851 return d == utree_type::list_type;
0852 }
0853 };
0854
0855 template <>
0856 struct compute_compatible_component_variant<utree, utree::invalid_type>
0857 : mpl::true_
0858 {
0859 typedef utree::invalid_type compatible_type;
0860
0861 static bool is_compatible(int d)
0862 {
0863 return d == utree_type::invalid_type;
0864 }
0865 };
0866
0867 template <>
0868 struct compute_compatible_component_variant<utree, utree::nil_type>
0869 : mpl::true_
0870 {
0871 typedef utree::nil_type compatible_type;
0872
0873 static bool is_compatible(int d)
0874 {
0875 return d == utree_type::nil_type;
0876 }
0877 };
0878
0879 template <>
0880 struct compute_compatible_component_variant<utree, bool>
0881 : mpl::true_
0882 {
0883 typedef bool compatible_type;
0884
0885 static bool is_compatible(int d)
0886 {
0887 return d == utree_type::bool_type;
0888 }
0889 };
0890
0891 template <>
0892 struct compute_compatible_component_variant<utree, int>
0893 : mpl::true_
0894 {
0895 typedef int compatible_type;
0896
0897 static bool is_compatible(int d)
0898 {
0899 return d == utree_type::int_type;
0900 }
0901 };
0902
0903 template <>
0904 struct compute_compatible_component_variant<utree, double>
0905 : mpl::true_
0906 {
0907 typedef double compatible_type;
0908
0909 static bool is_compatible(int d)
0910 {
0911 return d == utree_type::double_type;
0912 }
0913 };
0914
0915 template <>
0916 struct compute_compatible_component_variant<
0917 utree, utf8_string_range_type>
0918 : mpl::true_
0919 {
0920 typedef utf8_string_range_type compatible_type;
0921
0922 static bool is_compatible(int d)
0923 {
0924 return d == utree_type::string_type;
0925 }
0926 };
0927
0928 template <>
0929 struct compute_compatible_component_variant<
0930 utree, utf8_string_type>
0931 : mpl::true_
0932 {
0933 typedef utf8_string_type compatible_type;
0934
0935 static bool is_compatible(int d)
0936 {
0937 return d == utree_type::string_type;
0938 }
0939 };
0940
0941 template <>
0942 struct compute_compatible_component_variant<
0943 utree, utf8_symbol_range_type>
0944 : mpl::true_
0945 {
0946 typedef utf8_symbol_range_type compatible_type;
0947
0948 static bool is_compatible(int d)
0949 {
0950 return d == utree_type::symbol_type;
0951 }
0952 };
0953
0954 template <>
0955 struct compute_compatible_component_variant<
0956 utree, utf8_symbol_type>
0957 : mpl::true_
0958 {
0959 typedef utf8_symbol_type compatible_type;
0960
0961 static bool is_compatible(int d)
0962 {
0963 return d == utree_type::symbol_type;
0964 }
0965 };
0966
0967 template <>
0968 struct compute_compatible_component_variant<
0969 utree, binary_range_type>
0970 : mpl::true_
0971 {
0972 typedef binary_range_type compatible_type;
0973
0974 static bool is_compatible(int d)
0975 {
0976 return d == utree_type::binary_type;
0977 }
0978 };
0979
0980 template <>
0981 struct compute_compatible_component_variant<
0982 utree, binary_string_type>
0983 : mpl::true_
0984 {
0985 typedef binary_string_type compatible_type;
0986
0987 static bool is_compatible(int d)
0988 {
0989 return d == utree_type::binary_type;
0990 }
0991 };
0992
0993 template <>
0994 struct compute_compatible_component_variant<utree, utree>
0995 : mpl::true_
0996 {
0997 typedef utree compatible_type;
0998
0999 static bool is_compatible(int d)
1000 {
1001 return d >= utree_type::invalid_type &&
1002 d <= utree_type::reference_type;
1003 }
1004 };
1005
1006 template <>
1007 struct compute_compatible_component_variant<
1008 utree, std::vector<utree> >
1009 : mpl::true_
1010 {
1011 typedef utree compatible_type;
1012
1013 static bool is_compatible(int d)
1014 {
1015 return d >= utree_type::invalid_type &&
1016 d <= utree_type::reference_type;
1017 }
1018 };
1019
1020 template <typename Sequence>
1021 struct compute_compatible_component_variant<utree, Sequence
1022 , mpl::false_
1023 , typename enable_if<fusion::traits::is_sequence<Sequence> >::type>
1024 : mpl::true_
1025 {
1026 typedef iterator_range<utree::const_iterator> compatible_type;
1027
1028 static bool is_compatible(int d)
1029 {
1030 return d == utree_type::list_type;
1031 }
1032 };
1033
1034 template <typename Attribute>
1035 struct compute_compatible_component_variant<utree::list_type, Attribute>
1036 : compute_compatible_component_variant<utree, Attribute>
1037 {};
1038
1039
1040 template <>
1041 struct symbols_lookup<utree, utf8_symbol_type>
1042 {
1043 typedef std::string type;
1044
1045 static type call(utree const& t)
1046 {
1047 utf8_symbol_range_type r = boost::get<utf8_symbol_range_type>(t);
1048 return std::string(traits::begin(r), traits::end(r));
1049 }
1050 };
1051
1052 template <>
1053 struct symbols_lookup<utf8_symbol_type, utf8_symbol_type>
1054 {
1055 typedef std::string type;
1056
1057 static type call(utf8_symbol_type const& t)
1058 {
1059 return t;
1060 }
1061 };
1062
1063
1064 namespace detail
1065 {
1066 template <typename T>
1067 inline T get_or_deref(utree const& t)
1068 {
1069 if (detail::is_list(t))
1070 return boost::get<T>(t.front());
1071 return boost::get<T>(t);
1072 }
1073 }
1074
1075 template <>
1076 struct extract_from_container<utree, utree::nil_type>
1077 {
1078 typedef utree::nil_type type;
1079
1080 template <typename Context>
1081 static type call(utree const&, Context&)
1082 {
1083 return nil;
1084 }
1085 };
1086
1087 template <>
1088 struct extract_from_container<utree, char>
1089 {
1090 typedef char type;
1091
1092 template <typename Context>
1093 static type call(utree const& t, Context&)
1094 {
1095 utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
1096 return r.front();
1097 }
1098 };
1099
1100 template <>
1101 struct extract_from_container<utree, bool>
1102 {
1103 typedef bool type;
1104
1105 template <typename Context>
1106 static type call(utree const& t, Context&)
1107 {
1108 return detail::get_or_deref<bool>(t);
1109 }
1110 };
1111
1112 template <>
1113 struct extract_from_container<utree, int>
1114 {
1115 typedef int type;
1116
1117 template <typename Context>
1118 static type call(utree const& t, Context&)
1119 {
1120 return detail::get_or_deref<int>(t);
1121 }
1122 };
1123
1124 template <>
1125 struct extract_from_container<utree, double>
1126 {
1127 typedef double type;
1128
1129 template <typename Context>
1130 static type call(utree const& t, Context&)
1131 {
1132 return detail::get_or_deref<double>(t);
1133 }
1134 };
1135
1136 template <typename Traits, typename Alloc>
1137 struct extract_from_container<utree, std::basic_string<char, Traits, Alloc> >
1138 {
1139 typedef std::basic_string<char, Traits, Alloc> type;
1140
1141 template <typename Context>
1142 static type call(utree const& t, Context&)
1143 {
1144 utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
1145 return type(traits::begin(r), traits::end(r));
1146 }
1147 };
1148
1149 template <>
1150 struct extract_from_container<utree, utf8_symbol_type>
1151 {
1152 typedef utf8_symbol_type type;
1153
1154 template <typename Context>
1155 static type call(utree const& t, Context&)
1156 {
1157 utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
1158 return type(traits::begin(r), traits::end(r));
1159 }
1160 };
1161
1162 template <>
1163 struct extract_from_container<utree, utf8_string_type>
1164 {
1165 typedef utf8_string_type type;
1166
1167 template <typename Context>
1168 static type call(utree const& t, Context&)
1169 {
1170 utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
1171 return type(traits::begin(r), traits::end(r));
1172 }
1173 };
1174
1175
1176 template <>
1177 struct transform_attribute<utree const, utree::nil_type, karma::domain>
1178 {
1179 typedef utree::nil_type type;
1180
1181 static type pre(utree const&)
1182 {
1183 return nil;
1184 }
1185 };
1186
1187 template <>
1188 struct transform_attribute<utree const, char, karma::domain>
1189 {
1190 typedef char type;
1191
1192 static type pre(utree const& t)
1193 {
1194 utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
1195 return r.front();
1196 }
1197 };
1198
1199 template <>
1200 struct transform_attribute<utree const, bool, karma::domain>
1201 {
1202 typedef bool type;
1203
1204 static type pre(utree const& t)
1205 {
1206 return detail::get_or_deref<bool>(t);
1207 }
1208 };
1209
1210 template <>
1211 struct transform_attribute<utree const, int, karma::domain>
1212 {
1213 typedef int type;
1214
1215 static type pre(utree const& t)
1216 {
1217 return detail::get_or_deref<int>(t);
1218 }
1219 };
1220
1221 template <>
1222 struct transform_attribute<utree const, double, karma::domain>
1223 {
1224 typedef double type;
1225
1226 static type pre(utree const& t)
1227 {
1228 return detail::get_or_deref<double>(t);
1229 }
1230 };
1231
1232 template <typename Traits, typename Alloc>
1233 struct transform_attribute<
1234 utree const, std::basic_string<char, Traits, Alloc>, karma::domain>
1235 {
1236 typedef std::basic_string<char, Traits, Alloc> type;
1237
1238 static type pre(utree const& t)
1239 {
1240 utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
1241 return type(traits::begin(r), traits::end(r));
1242 }
1243 };
1244
1245
1246
1247 template <typename Iterator>
1248 struct transform_attribute<
1249 iterator_range<Iterator> const, utree, karma::domain>
1250 {
1251 typedef utree type;
1252
1253 static type pre(iterator_range<Iterator> const& t)
1254 {
1255
1256 Iterator it = t.begin();
1257 utree result(boost::ref(*it));
1258 ++it;
1259 return result;
1260 }
1261 };
1262
1263
1264 template <>
1265 struct transform_attribute<utree const, utf8_string_type, karma::domain>
1266 {
1267 typedef utf8_string_type type;
1268
1269 static type pre(utree const& t)
1270 {
1271 utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
1272 return type(traits::begin(r), traits::end(r));
1273 }
1274 };
1275
1276 template <>
1277 struct transform_attribute<utree const, utf8_symbol_type, karma::domain>
1278 {
1279 typedef utf8_symbol_type type;
1280
1281 static type pre(utree const& t)
1282 {
1283 utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
1284 return type(traits::begin(r), traits::end(r));
1285 }
1286 };
1287
1288 template <typename Attribute>
1289 struct transform_attribute<utree::list_type const, Attribute, karma::domain>
1290 : transform_attribute<utree const, Attribute, karma::domain>
1291 {};
1292 }}}
1293
1294 #endif