1 /*============================================================================= 2 Copyright (c) 2001-2014 Joel de Guzman 3 Copyright (c) 2001-2011 Hartmut Kaiser 4 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 #ifndef BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP 9 #define BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP 10 11 #include <boost/spirit/home/x3/support/traits/transform_attribute.hpp> 12 #include <boost/spirit/home/x3/support/traits/move_to.hpp> 13 #include <type_traits> 14 #include <utility> 15 16 /////////////////////////////////////////////////////////////////////////////// 17 namespace boost { namespace spirit { namespace x3 18 { 19 struct parser_id; 20 21 template <typename Exposed, typename Transformed> 22 struct default_transform_attribute 23 { 24 typedef Transformed type; 25 preboost::spirit::x3::default_transform_attribute26 static Transformed pre(Exposed&) { return Transformed(); } 27 postboost::spirit::x3::default_transform_attribute28 static void post(Exposed& val, Transformed&& attr) 29 { 30 traits::move_to(std::forward<Transformed>(attr), val); 31 } 32 }; 33 34 // handle case where no transformation is required as the types are the same 35 template <typename Attribute> 36 struct default_transform_attribute<Attribute, Attribute> 37 { 38 typedef Attribute& type; preboost::spirit::x3::default_transform_attribute39 static Attribute& pre(Attribute& val) { return val; } postboost::spirit::x3::default_transform_attribute40 static void post(Attribute&, Attribute const&) {} 41 }; 42 43 // main specialization for x3 44 template <typename Exposed, typename Transformed, typename Enable = void> 45 struct transform_attribute 46 : default_transform_attribute<Exposed, Transformed> {}; 47 48 // unused_type needs some special handling as well 49 template <> 50 struct transform_attribute<unused_type, unused_type> 51 { 52 typedef unused_type type; preboost::spirit::x3::transform_attribute53 static unused_type pre(unused_type) { return unused; } postboost::spirit::x3::transform_attribute54 static void post(unused_type, unused_type) {} 55 }; 56 57 template <> 58 struct transform_attribute<unused_type const, unused_type> 59 : transform_attribute<unused_type, unused_type> {}; 60 61 template <typename Attribute> 62 struct transform_attribute<unused_type, Attribute> 63 : transform_attribute<unused_type, unused_type> {}; 64 65 template <typename Attribute> 66 struct transform_attribute<unused_type const, Attribute> 67 : transform_attribute<unused_type, unused_type> {}; 68 69 template <typename Attribute> 70 struct transform_attribute<Attribute, unused_type> 71 : transform_attribute<unused_type, unused_type> {}; 72 73 template <typename Attribute> 74 struct transform_attribute<Attribute const, unused_type> 75 : transform_attribute<unused_type, unused_type> {}; 76 }}} 77 78 /////////////////////////////////////////////////////////////////////////////// 79 namespace boost { namespace spirit { namespace x3 { namespace traits 80 { 81 template <typename Exposed, typename Transformed> 82 struct transform_attribute<Exposed, Transformed, x3::parser_id> 83 : x3::transform_attribute<Exposed, Transformed> 84 { 85 static_assert(!std::is_reference<Exposed>::value, 86 "Exposed cannot be a reference type"); 87 static_assert(!std::is_reference<Transformed>::value, 88 "Transformed cannot be a reference type"); 89 }; 90 }}}} 91 92 #endif 93