diff DEPENDENCIES/generic/include/boost/spirit/home/qi/detail/attributes.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/spirit/home/qi/detail/attributes.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -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