]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/spirit/home/support/utree/utree_traits.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / spirit / home / support / utree / utree_traits.hpp
diff --git a/ceph/src/boost/boost/spirit/home/support/utree/utree_traits.hpp b/ceph/src/boost/boost/spirit/home/support/utree/utree_traits.hpp
new file mode 100644 (file)
index 0000000..4f9f46f
--- /dev/null
@@ -0,0 +1,1294 @@
+/*=============================================================================
+    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/range/iterator_range.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/or.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 std::string 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 std::string(traits::begin(r), traits::end(r));
+        }
+    };
+
+    template <>
+    struct extract_from_container<utree, utf8_string_type>
+    {
+        typedef std::string 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 std::string(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 = boost::begin(t);
+            utree result(boost::ref(*it));
+            ++it;
+            return result;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <>
+    struct transform_attribute<utree const, utf8_string_type, karma::domain>
+    {
+        typedef std::string type;
+
+        static type pre(utree const& t)
+        {
+            utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
+            return std::string(traits::begin(r), traits::end(r));
+        }
+    };
+
+    template <>
+    struct transform_attribute<utree const, utf8_symbol_type, karma::domain>
+    {
+        typedef std::string type;
+
+        static type pre(utree const& t)
+        {
+            utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
+            return std::string(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