Chris@102
|
1 /*=============================================================================
|
Chris@102
|
2 Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@102
|
3 Copyright (c) 2001-2014 Joel de Guzman
|
Chris@102
|
4 Copyright (c) 2013 Agustin Berge
|
Chris@102
|
5
|
Chris@102
|
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
8 ==============================================================================*/
|
Chris@102
|
9 #ifndef BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
|
Chris@102
|
10 #define BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
|
Chris@102
|
11
|
Chris@102
|
12 #if defined(_MSC_VER)
|
Chris@102
|
13 #pragma once
|
Chris@102
|
14 #endif
|
Chris@102
|
15
|
Chris@102
|
16 #include <boost/spirit/home/x3/core/parser.hpp>
|
Chris@102
|
17 #include <boost/spirit/home/x3/support/unused.hpp>
|
Chris@102
|
18 #include <boost/spirit/home/x3/support/traits/container_traits.hpp>
|
Chris@102
|
19 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
|
Chris@102
|
20 #include <boost/type_traits/is_same.hpp>
|
Chris@102
|
21 #include <boost/type_traits/remove_cv.hpp>
|
Chris@102
|
22 #include <boost/type_traits/remove_reference.hpp>
|
Chris@102
|
23 #include <algorithm>
|
Chris@102
|
24 #include <cstddef>
|
Chris@102
|
25 #include <string>
|
Chris@102
|
26 #include <utility>
|
Chris@102
|
27
|
Chris@102
|
28 namespace boost { namespace spirit { namespace x3
|
Chris@102
|
29 {
|
Chris@102
|
30 template <typename Value>
|
Chris@102
|
31 struct attr_parser : parser<attr_parser<Value>>
|
Chris@102
|
32 {
|
Chris@102
|
33 typedef Value attribute_type;
|
Chris@102
|
34
|
Chris@102
|
35 static bool const has_attribute =
|
Chris@102
|
36 !is_same<unused_type, attribute_type>::value;
|
Chris@102
|
37 static bool const handles_container =
|
Chris@102
|
38 traits::is_container<attribute_type>::value;
|
Chris@102
|
39
|
Chris@102
|
40 attr_parser(Value const& value)
|
Chris@102
|
41 : value_(value) {}
|
Chris@102
|
42 attr_parser(Value&& value)
|
Chris@102
|
43 : value_(std::move(value)) {}
|
Chris@102
|
44
|
Chris@102
|
45 template <typename Iterator, typename Context
|
Chris@102
|
46 , typename RuleContext, typename Attribute>
|
Chris@102
|
47 bool parse(Iterator& first, Iterator const& last
|
Chris@102
|
48 , Context const& context, RuleContext&, Attribute& attr_) const
|
Chris@102
|
49 {
|
Chris@102
|
50 // $$$ Change to copy_to once we have it $$$
|
Chris@102
|
51 traits::move_to(value_, attr_);
|
Chris@102
|
52 return true;
|
Chris@102
|
53 }
|
Chris@102
|
54
|
Chris@102
|
55 Value value_;
|
Chris@102
|
56
|
Chris@102
|
57 private:
|
Chris@102
|
58 // silence MSVC warning C4512: assignment operator could not be generated
|
Chris@102
|
59 attr_parser& operator= (attr_parser const&);
|
Chris@102
|
60 };
|
Chris@102
|
61
|
Chris@102
|
62 template <typename Value, std::size_t N>
|
Chris@102
|
63 struct attr_parser<Value[N]> : parser<attr_parser<Value[N]>>
|
Chris@102
|
64 {
|
Chris@102
|
65 typedef Value attribute_type[N];
|
Chris@102
|
66
|
Chris@102
|
67 static bool const has_attribute =
|
Chris@102
|
68 !is_same<unused_type, attribute_type>::value;
|
Chris@102
|
69 static bool const handles_container = true;
|
Chris@102
|
70
|
Chris@102
|
71 attr_parser(Value const (&value)[N])
|
Chris@102
|
72 {
|
Chris@102
|
73 std::copy(value + 0, value + N, value_ + 0);
|
Chris@102
|
74 }
|
Chris@102
|
75
|
Chris@102
|
76 attr_parser(Value (&&value)[N])
|
Chris@102
|
77 {
|
Chris@102
|
78 std::move(value + 0, value + N, value_ + 0);
|
Chris@102
|
79 }
|
Chris@102
|
80
|
Chris@102
|
81 template <typename Iterator, typename Context
|
Chris@102
|
82 , typename RuleContext, typename Attribute>
|
Chris@102
|
83 bool parse(Iterator& first, Iterator const& last
|
Chris@102
|
84 , Context const& context, RuleContext&, Attribute& attr_) const
|
Chris@102
|
85 {
|
Chris@102
|
86 // $$$ Change to copy_to once we have it $$$
|
Chris@102
|
87 traits::move_to(value_ + 0, value_ + N, attr_);
|
Chris@102
|
88 return true;
|
Chris@102
|
89 }
|
Chris@102
|
90
|
Chris@102
|
91 Value value_[N];
|
Chris@102
|
92
|
Chris@102
|
93 private:
|
Chris@102
|
94 // silence MSVC warning C4512: assignment operator could not be generated
|
Chris@102
|
95 attr_parser& operator= (attr_parser const&);
|
Chris@102
|
96 };
|
Chris@102
|
97
|
Chris@102
|
98 template <typename Value>
|
Chris@102
|
99 struct get_info<attr_parser<Value>>
|
Chris@102
|
100 {
|
Chris@102
|
101 typedef std::string result_type;
|
Chris@102
|
102 std::string operator()(attr_parser<Value> const& /*p*/) const
|
Chris@102
|
103 {
|
Chris@102
|
104 return "attr";
|
Chris@102
|
105 }
|
Chris@102
|
106 };
|
Chris@102
|
107
|
Chris@102
|
108 struct attr_gen
|
Chris@102
|
109 {
|
Chris@102
|
110 template <typename Value>
|
Chris@102
|
111 attr_parser<typename remove_cv<
|
Chris@102
|
112 typename remove_reference<Value>::type>::type>
|
Chris@102
|
113 operator()(Value&& value) const
|
Chris@102
|
114 {
|
Chris@102
|
115 return {std::forward<Value>(value)};
|
Chris@102
|
116 }
|
Chris@102
|
117
|
Chris@102
|
118 template <typename Value, std::size_t N>
|
Chris@102
|
119 attr_parser<typename remove_cv<Value>::type[N]>
|
Chris@102
|
120 operator()(Value (&value)[N]) const
|
Chris@102
|
121 {
|
Chris@102
|
122 return {value};
|
Chris@102
|
123 }
|
Chris@102
|
124 template <typename Value, std::size_t N>
|
Chris@102
|
125 attr_parser<typename remove_cv<Value>::type[N]>
|
Chris@102
|
126 operator()(Value (&&value)[N]) const
|
Chris@102
|
127 {
|
Chris@102
|
128 return {value};
|
Chris@102
|
129 }
|
Chris@102
|
130 };
|
Chris@102
|
131
|
Chris@102
|
132 attr_gen const attr = attr_gen();
|
Chris@102
|
133 }}}
|
Chris@102
|
134
|
Chris@102
|
135 #endif
|