1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 Copyright (c) 2001-2011 Hartmut Kaiser
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #if !defined(SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM)
9 #define SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM
11 #include <boost/spirit/home/x3/support/traits/transform_attribute.hpp>
12 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
15 ///////////////////////////////////////////////////////////////////////////////
16 namespace boost { namespace spirit { namespace x3
20 template <typename Exposed, typename Transformed>
21 struct default_transform_attribute
23 typedef Transformed type;
25 static Transformed pre(Exposed&) { return Transformed(); }
27 static void post(Exposed& val, Transformed&& attr)
29 traits::move_to(std::forward<Transformed>(attr), val);
33 // handle case where no transformation is required as the types are the same
34 template <typename Attribute>
35 struct default_transform_attribute<Attribute, Attribute>
37 typedef Attribute& type;
38 static Attribute& pre(Attribute& val) { return val; }
39 static void post(Attribute&, Attribute const&) {}
42 // main specialization for x3
43 template <typename Exposed, typename Transformed, typename Enable = void>
44 struct transform_attribute
45 : default_transform_attribute<Exposed, Transformed> {};
47 // reference types need special handling
48 template <typename Attribute>
49 struct transform_attribute<Attribute&, Attribute>
51 typedef Attribute& type;
52 static Attribute& pre(Attribute& val) { return val; }
53 static void post(Attribute&, Attribute const&) {}
56 // unused_type needs some special handling as well
58 struct transform_attribute<unused_type, unused_type>
60 typedef unused_type type;
61 static unused_type pre(unused_type) { return unused; }
62 static void post(unused_type, unused_type) {}
66 struct transform_attribute<unused_type const, unused_type>
67 : transform_attribute<unused_type, unused_type> {};
69 template <typename Attribute>
70 struct transform_attribute<unused_type, Attribute>
71 : transform_attribute<unused_type, unused_type> {};
73 template <typename Attribute>
74 struct transform_attribute<unused_type const, Attribute>
75 : transform_attribute<unused_type, unused_type> {};
77 template <typename Attribute>
78 struct transform_attribute<Attribute, unused_type>
79 : transform_attribute<unused_type, unused_type> {};
81 template <typename Attribute>
82 struct transform_attribute<Attribute const, unused_type>
83 : transform_attribute<unused_type, unused_type> {};
86 ///////////////////////////////////////////////////////////////////////////////
87 namespace boost { namespace spirit { namespace x3 { namespace traits
89 template <typename Exposed, typename Transformed>
90 struct transform_attribute<Exposed, Transformed, x3::parser_id>
91 : x3::transform_attribute<Exposed, Transformed> {};
93 template <typename Exposed, typename Transformed>
94 struct transform_attribute<Exposed&, Transformed, x3::parser_id>
95 : transform_attribute<Exposed, Transformed, x3::parser_id> {};
97 template <typename Attribute>
98 struct transform_attribute<Attribute&, Attribute, x3::parser_id>
99 : x3::transform_attribute<Attribute&, Attribute> {};
101 ///////////////////////////////////////////////////////////////////////////
102 template <typename Exposed, typename Transformed>
103 void post_transform(Exposed& dest, Transformed&& attr)
105 return transform_attribute<Exposed, Transformed, x3::parser_id>
106 ::post(dest, std::forward<Transformed>(attr));