1/*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 Copyright (c) 2013-2014 Agustin Berge
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#if !defined(BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM)
9#define BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM
10
11#include <boost/spirit/home/x3/core/parser.hpp>
12#include <boost/spirit/home/x3/support/context.hpp>
13#include <boost/spirit/home/x3/support/subcontext.hpp>
14#include <boost/spirit/home/x3/support/unused.hpp>
15#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
16#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
17#include <boost/spirit/home/x3/support/traits/move_to.hpp>
18#include <boost/spirit/home/x3/support/traits/is_parser.hpp>
19#include <memory>
20#include <string>
21
22namespace boost { namespace spirit { namespace x3
23{
24 template <
25 typename Iterator
26 , typename Attribute = unused_type
27 , typename Context = subcontext<>>
28 struct any_parser : parser<any_parser<Iterator, Attribute, Context>>
29 {
30 typedef Attribute attribute_type;
31
32 static bool const has_attribute =
33 !is_same<unused_type, attribute_type>::value;
34 static bool const handles_container =
35 traits::is_container<Attribute>::value;
36
37 public:
38 any_parser() = default;
39
40 template <typename Expr,
41 typename Enable = typename enable_if<traits::is_parser<Expr>>::type>
42 any_parser(Expr const& expr)
43 : _content(new holder<Expr>(expr)) {}
44
45 any_parser(any_parser const& other)
46 : _content(other._content ? other._content->clone() : nullptr) {}
47
48 any_parser(any_parser&& other) = default;
49
50 any_parser& operator=(any_parser const& other)
51 {
52 _content.reset(other._content ? other._content->clone() : nullptr);
53 return *this;
54 }
55
56 any_parser& operator=(any_parser&& other) = default;
57
58 template <typename Iterator_, typename Context_>
59 bool parse(Iterator_& first, Iterator_ const& last
60 , Context_ const& context, unused_type, Attribute& attr) const
61 {
62 BOOST_STATIC_ASSERT_MSG(
63 (is_same<Iterator, Iterator_>::value)
64 , "Incompatible iterator used"
65 );
66
67 BOOST_ASSERT_MSG(
68 (_content != nullptr)
69 , "Invalid use of uninitialized any_parser"
70 );
71
72 return _content->parse(first, last, context, attr);
73 }
74
75 template <typename Iterator_, typename Context_, typename Attribute_>
76 bool parse(Iterator_& first, Iterator_ const& last
77 , Context_ const& context, unused_type, Attribute_& attr_) const
78 {
79 Attribute attr;
80 if (parse(first, last, context, unused, attr))
81 {
82 traits::move_to(attr, attr_);
83 return true;
84 }
85 return false;
86 }
87
88 std::string get_info() const
89 {
90 return _content ? _content->get_info() : "";
91 }
92
93 private:
94
95 struct placeholder
96 {
97 virtual placeholder* clone() const = 0;
98
99 virtual bool parse(Iterator& first, Iterator const& last
100 , Context const& context, Attribute& attr) const = 0;
101
102 virtual std::string get_info() const = 0;
103
104 virtual ~placeholder() {}
105 };
106
107 template <typename Expr>
108 struct holder : placeholder
109 {
110 typedef typename extension::as_parser<Expr>::value_type parser_type;
111
112 explicit holder(Expr const& p)
113 : _parser(as_parser(p)) {}
114
115 holder* clone() const override
116 {
117 return new holder(*this);
118 }
119
120 bool parse(Iterator& first, Iterator const& last
121 , Context const& context, Attribute& attr) const override
122 {
123 return _parser.parse(first, last, context, unused, attr);
124 }
125
126 std::string get_info() const override
127 {
128 return x3::what(_parser);
129 }
130
131 parser_type _parser;
132 };
133
134 private:
135 std::unique_ptr<placeholder> _content;
136 };
137
138 template <typename Iterator, typename Attribute, typename Context>
139 struct get_info<any_parser<Iterator, Attribute, Context>>
140 {
141 typedef std::string result_type;
142 std::string operator()(
143 any_parser<Iterator, Attribute, Context> const& p) const
144 {
145 return p.get_info();
146 }
147 };
148}}}
149
150#endif
151

source code of boost/libs/spirit/include/boost/spirit/home/x3/auxiliary/any_parser.hpp