diff options
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/qi/detail/attributes.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/spirit/home/qi/detail/attributes.hpp | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/spirit/home/qi/detail/attributes.hpp b/3rdParty/Boost/src/boost/spirit/home/qi/detail/attributes.hpp new file mode 100644 index 0000000..0a66a65 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/qi/detail/attributes.hpp @@ -0,0 +1,176 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 Joel de Guzman +// +// 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(SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM) +#define SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM + +#include <boost/spirit/home/qi/domain.hpp> +#include <boost/spirit/home/support/attributes_fwd.hpp> +#include <boost/spirit/home/support/attributes.hpp> +#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace qi +{ + template <typename Exposed, typename Transformed> + struct default_transform_attribute + { + typedef Transformed type; + + static Transformed pre(Exposed&) { return Transformed(); } + + static void post(Exposed& val, Transformed const& attr) + { + traits::assign_to(attr, val); + } + + // fail() will be called by Qi rule's if the rhs failed parsing + static void fail(Exposed&) {} + }; + + // handle case where no transformation is required as the types are the same + template <typename Attribute> + struct default_transform_attribute<Attribute, Attribute> + { + typedef Attribute& type; + static Attribute& pre(Attribute& val) { return val; } + static void post(Attribute&, Attribute const&) {} + static void fail(Attribute&) {} + }; + + template <typename Exposed, typename Transformed> + struct proxy_transform_attribute + { + typedef Transformed type; + + static Transformed pre(Exposed& val) { return Transformed(val); } + static void post(Exposed&, Transformed const&) { /* no-op */ } + + // fail() will be called by Qi rule's if the rhs failed parsing + static void fail(Exposed&) {} + }; + + // handle case where no transformation is required as the types are the same + template <typename Attribute> + struct proxy_transform_attribute<Attribute, Attribute> + { + typedef Attribute& type; + static Attribute& pre(Attribute& val) { return val; } + static void post(Attribute&, Attribute const&) {} + static void fail(Attribute&) {} + }; + + // main specialization for Qi + template <typename Exposed, typename Transformed, typename Enable = void> + struct transform_attribute + : mpl::if_< + mpl::and_< + mpl::not_<is_const<Exposed> > + , mpl::not_<is_reference<Exposed> > + , traits::is_proxy<Transformed> > + , proxy_transform_attribute<Exposed, Transformed> + , default_transform_attribute<Exposed, Transformed> + >::type + {}; + + template <typename Exposed, typename Transformed> + struct transform_attribute<boost::optional<Exposed>, Transformed + , typename disable_if<is_same<boost::optional<Exposed>, Transformed> >::type> + { + typedef Transformed& type; + static Transformed& pre(boost::optional<Exposed>& val) + { + if (!val) + val = Transformed(); + return boost::get<Transformed>(val); + } + static void post(boost::optional<Exposed>&, Transformed const&) {} + static void fail(boost::optional<Exposed>& val) + { + val = none_t(); // leave optional uninitialized if rhs failed + } + }; + + // reference types need special handling + template <typename Attribute> + struct transform_attribute<Attribute&, Attribute> + { + typedef Attribute& type; + static Attribute& pre(Attribute& val) { return val; } + static void post(Attribute&, Attribute const&) {} + static void fail(Attribute&) {} + }; + + // unused_type needs some special handling as well + template <> + struct transform_attribute<unused_type, unused_type> + { + typedef unused_type type; + static unused_type pre(unused_type) { return unused; } + static void post(unused_type, unused_type) {} + static void fail(unused_type) {} + }; + + template <> + struct transform_attribute<unused_type const, unused_type> + : transform_attribute<unused_type, unused_type> + {}; + + template <typename Attribute> + struct transform_attribute<unused_type, Attribute> + : transform_attribute<unused_type, unused_type> + {}; + + template <typename Attribute> + struct transform_attribute<unused_type const, Attribute> + : transform_attribute<unused_type, unused_type> + {}; + + template <typename Attribute> + struct transform_attribute<Attribute, unused_type> + : transform_attribute<unused_type, unused_type> + {}; + + template <typename Attribute> + struct transform_attribute<Attribute const, unused_type> + : transform_attribute<unused_type, unused_type> + {}; +}}} + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace traits +{ + template <typename Exposed, typename Transformed> + struct transform_attribute<Exposed, Transformed, qi::domain> + : qi::transform_attribute<Exposed, Transformed> + {}; + + template <typename Exposed, typename Transformed> + struct transform_attribute<Exposed&, Transformed, qi::domain> + : transform_attribute<Exposed, Transformed, qi::domain> + {}; + + template <typename Attribute> + struct transform_attribute<Attribute&, Attribute, qi::domain> + : qi::transform_attribute<Attribute&, Attribute> + {}; + + /////////////////////////////////////////////////////////////////////////// + template <typename Exposed, typename Transformed> + void post_transform(Exposed& dest, Transformed const& attr) + { + return transform_attribute<Exposed, Transformed, qi::domain>::post(dest, attr); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Exposed, typename Transformed> + void fail_transform(Exposed& dest, Transformed const&) + { + return transform_attribute<Exposed, Transformed, qi::domain>::fail(dest); + } +}}} + +#endif |