Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / spirit / home / qi / directive / as.hpp
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3     Copyright (c) 2001-2011 Hartmut Kaiser
4     Copyright (c)      2010 Bryce Lelbach
5
6     Distributed under the Boost Software License, Version 1.0. (See accompanying
7     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 #if !defined(SPIRIT_AS_DECEMBER_6_2010_1013AM)
10 #define SPIRIT_AS_DECEMBER_6_2010_1013AM
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <boost/spirit/home/qi/meta_compiler.hpp>
17 #include <boost/spirit/home/qi/skip_over.hpp>
18 #include <boost/spirit/home/qi/parser.hpp>
19 #include <boost/spirit/home/qi/detail/assign_to.hpp>
20 #include <boost/spirit/home/support/unused.hpp>
21 #include <boost/spirit/home/support/info.hpp>
22 #include <boost/spirit/home/support/common_terminals.hpp>
23 #include <boost/spirit/home/support/unused.hpp>
24 #include <boost/spirit/home/support/has_semantic_action.hpp>
25 #include <boost/spirit/home/support/handles_container.hpp>
26 #include <boost/spirit/home/support/assert_msg.hpp>
27 #include <boost/spirit/home/support/container.hpp>
28 #include <boost/range/iterator_range.hpp>
29 #include <string>
30
31 namespace boost { namespace spirit { namespace qi
32 {
33     template <typename T>
34     struct as
35       : stateful_tag_type<T, tag::as>
36     {
37         //~ BOOST_SPIRIT_ASSERT_MSG(
38             //~ (traits::is_container<T>::type::value),
39             //~ error_type_must_be_a_container,
40             //~ (T));
41     };
42 }}}
43
44 namespace boost { namespace spirit
45 {
46     ///////////////////////////////////////////////////////////////////////////
47     // Enablers
48     ///////////////////////////////////////////////////////////////////////////
49     // enables as_string[...]
50     template <>
51     struct use_directive<qi::domain, tag::as_string>
52       : mpl::true_ {};
53
54     // enables as_wstring[...]
55     template <>
56     struct use_directive<qi::domain, tag::as_wstring>
57       : mpl::true_ {};
58
59     // enables as<T>[...]
60     template <typename T>
61     struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> >
62       : mpl::true_
63     {};
64 }}
65
66 namespace boost { namespace spirit { namespace qi
67 {
68 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
69     using spirit::as_string;
70     using spirit::as_wstring;
71 #endif
72     using spirit::as_string_type;
73     using spirit::as_wstring_type;
74
75     template <typename Subject, typename T>
76     struct as_directive : unary_parser<as_directive<Subject, T> >
77     {
78         typedef Subject subject_type;
79         as_directive(Subject const& subject_)
80           : subject(subject_) {}
81
82         template <typename Context, typename Iterator>
83         struct attribute
84         {
85             typedef T type;
86         };
87
88         template <typename Iterator, typename Context
89           , typename Skipper, typename Attribute>
90         bool parse(Iterator& first, Iterator const& last
91           , Context& context, Skipper const& skipper, Attribute& attr_) const
92         {
93             Iterator i = first;
94             T as_attr;
95             if (subject.parse(i, last, context, skipper, as_attr))
96             {
97                 spirit::traits::assign_to(as_attr, attr_);
98                 first = i;
99                 return true;
100             }
101             return false;
102         }
103
104         template <typename Iterator, typename Context, typename Skipper>
105         bool parse(Iterator& first, Iterator const& last
106           , Context& context, Skipper const& skipper, T& attr_) const
107         {
108             Iterator i = first;
109             if (subject.parse(i, last, context, skipper, attr_))
110             {
111                 first = i;
112                 return true;
113             }
114             return false;
115         }
116
117         template <typename Context>
118         info what(Context& context) const
119         {
120             return info("as", subject.what(context));
121         }
122
123         Subject subject;
124     };
125
126     ///////////////////////////////////////////////////////////////////////////
127     // Parser generators: make_xxx function (objects)
128     ///////////////////////////////////////////////////////////////////////////
129     template <typename Subject, typename Modifiers>
130     struct make_directive<tag::as_string, Subject, Modifiers>
131     {
132         typedef as_directive<Subject, std::string> result_type;
133         result_type operator()(unused_type, Subject const& subject
134           , unused_type) const
135         {
136             return result_type(subject);
137         }
138     };
139
140     template <typename Subject, typename Modifiers>
141     struct make_directive<tag::as_wstring, Subject, Modifiers>
142     {
143         typedef as_directive<Subject, std::basic_string<wchar_t> > result_type;
144         result_type operator()(unused_type, Subject const& subject
145           , unused_type) const
146         {
147             return result_type(subject);
148         }
149     };
150
151     template <typename T, typename Subject, typename Modifiers>
152     struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
153     {
154         typedef as_directive<Subject, T> result_type;
155         result_type operator()(unused_type, Subject const& subject
156           , unused_type) const
157         {
158             return result_type(subject);
159         }
160     };
161 }}}
162
163 namespace boost { namespace spirit { namespace traits
164 {
165     ///////////////////////////////////////////////////////////////////////////
166     template <typename Subject, typename T>
167     struct has_semantic_action<qi::as_directive<Subject, T> >
168       : unary_has_semantic_action<Subject> {};
169
170     ///////////////////////////////////////////////////////////////////////////
171     template <typename Subject, typename T, typename Attribute
172         , typename Context, typename Iterator>
173     struct handles_container<qi::as_directive<Subject, T>, Attribute
174         , Context, Iterator>
175       : mpl::false_ {};
176 }}}
177
178 #endif