File indexing completed on 2025-01-31 10:02:34
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
0010 #define BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
0011
0012 #include <boost/spirit/home/x3/core/parser.hpp>
0013 #include <boost/spirit/home/x3/support/unused.hpp>
0014 #include <boost/spirit/home/x3/support/traits/container_traits.hpp>
0015 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
0016 #include <boost/type_traits/is_same.hpp>
0017 #include <boost/type_traits/remove_cv.hpp>
0018 #include <boost/type_traits/remove_reference.hpp>
0019 #include <cstddef>
0020 #include <string>
0021 #include <utility>
0022
0023 namespace boost { namespace spirit { namespace x3
0024 {
0025
0026 namespace detail
0027 {
0028 template <typename Value, std::size_t N
0029 , typename = std::make_index_sequence<N>>
0030 struct array_helper;
0031
0032 template <typename Value, std::size_t N, std::size_t... Is>
0033 struct array_helper<Value, N, std::index_sequence<Is...>>
0034 {
0035 constexpr array_helper(Value const (&value)[N])
0036 : value_{ value[Is]... } {}
0037
0038 constexpr array_helper(Value (&&value)[N])
0039 : value_{ static_cast<Value&&>(value[Is])... } {}
0040
0041 Value value_[N];
0042 };
0043 }
0044
0045 template <typename Value>
0046 struct attr_parser : parser<attr_parser<Value>>
0047 {
0048 typedef Value attribute_type;
0049
0050 static bool const has_attribute =
0051 !is_same<unused_type, attribute_type>::value;
0052 static bool const handles_container =
0053 traits::is_container<attribute_type>::value;
0054
0055 constexpr attr_parser(Value const& value)
0056 : value_(value) {}
0057 constexpr attr_parser(Value&& value)
0058 : value_(std::move(value)) {}
0059
0060 template <typename Iterator, typename Context
0061 , typename RuleContext, typename Attribute>
0062 bool parse(Iterator& , Iterator const&
0063 , Context const& , RuleContext&, Attribute& attr_) const
0064 {
0065
0066 traits::move_to(value_, attr_);
0067 return true;
0068 }
0069
0070 Value value_;
0071 };
0072
0073 template <typename Value, std::size_t N>
0074 struct attr_parser<Value[N]> : parser<attr_parser<Value[N]>>
0075 , detail::array_helper<Value, N>
0076 {
0077 using detail::array_helper<Value, N>::array_helper;
0078
0079 typedef Value attribute_type[N];
0080
0081 static bool const has_attribute =
0082 !is_same<unused_type, attribute_type>::value;
0083 static bool const handles_container = true;
0084
0085 template <typename Iterator, typename Context
0086 , typename RuleContext, typename Attribute>
0087 bool parse(Iterator& , Iterator const&
0088 , Context const& , RuleContext&, Attribute& attr_) const
0089 {
0090
0091 traits::move_to(this->value_ + 0, this->value_ + N, attr_);
0092 return true;
0093 }
0094 };
0095
0096 template <typename Value>
0097 struct get_info<attr_parser<Value>>
0098 {
0099 typedef std::string result_type;
0100 std::string operator()(attr_parser<Value> const& ) const
0101 {
0102 return "attr";
0103 }
0104 };
0105
0106 struct attr_gen
0107 {
0108 template <typename Value>
0109 constexpr attr_parser<typename remove_cv<
0110 typename remove_reference<Value>::type>::type>
0111 operator()(Value&& value) const
0112 {
0113 return { std::forward<Value>(value) };
0114 }
0115 };
0116
0117 constexpr auto attr = attr_gen{};
0118 }}}
0119
0120 #endif