1 /*=============================================================================
2     Copyright (c) 2001-2014 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM)
8 #define BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM
9 
10 #include <boost/spirit/home/x3/core/parser.hpp>
11 #include <boost/spirit/home/x3/core/skip_over.hpp>
12 #include <boost/spirit/home/x3/string/detail/string_parse.hpp>
13 #include <boost/spirit/home/x3/support/no_case.hpp>
14 #include <boost/spirit/home/x3/string/detail/no_case_string_parse.hpp>
15 #include <boost/spirit/home/x3/support/utility/utf8.hpp>
16 #include <boost/spirit/home/support/char_encoding/ascii.hpp>
17 #include <boost/spirit/home/support/char_encoding/standard.hpp>
18 #include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
19 
20 #include <boost/type_traits/is_same.hpp>
21 #include <boost/type_traits/add_reference.hpp>
22 #include <string>
23 
24 namespace boost { namespace spirit { namespace x3
25 {
26     template <typename String, typename Encoding,
27         typename Attribute = std::basic_string<typename Encoding::char_type>>
28     struct literal_string : parser<literal_string<String, Encoding, Attribute>>
29     {
30         typedef typename Encoding::char_type char_type;
31         typedef Encoding encoding;
32         typedef Attribute attribute_type;
33         static bool const has_attribute =
34             !is_same<unused_type, attribute_type>::value;
35         static bool const handles_container = has_attribute;
36 
literal_stringboost::spirit::x3::literal_string37         literal_string(typename add_reference< typename add_const<String>::type >::type str)
38           : str(str)
39         {}
40 
41         template <typename Iterator, typename Context, typename Attribute_>
parseboost::spirit::x3::literal_string42         bool parse(Iterator& first, Iterator const& last
43           , Context const& context, unused_type, Attribute_& attr) const
44         {
45             x3::skip_over(first, last, context);
46             return detail::string_parse(str, first, last, attr, get_case_compare<encoding>(context));
47         }
48 
49         String str;
50     };
51 
52     namespace standard
53     {
54         inline literal_string<char const*, char_encoding::standard>
string(char const * s)55         string(char const* s)
56         {
57             return { s };
58         }
59 
60         inline literal_string<std::basic_string<char>, char_encoding::standard>
string(std::basic_string<char> const & s)61         string(std::basic_string<char> const& s)
62         {
63             return { s };
64         }
65 
66         inline literal_string<char const*, char_encoding::standard, unused_type>
lit(char const * s)67         lit(char const* s)
68         {
69             return { s };
70         }
71 
72         template <typename Char>
73         literal_string<Char const*, char_encoding::standard, unused_type>
lit(std::basic_string<Char> const & s)74         lit(std::basic_string<Char> const& s)
75         {
76             return { s.c_str() };
77         }
78     }
79 
80     namespace standard_wide
81     {
82         inline literal_string<wchar_t const*, char_encoding::standard_wide>
string(wchar_t const * s)83         string(wchar_t const* s)
84         {
85             return { s };
86         }
87 
88         inline literal_string<std::basic_string<wchar_t>, char_encoding::standard_wide>
string(std::basic_string<wchar_t> const & s)89         string(std::basic_string<wchar_t> const& s)
90         {
91             return { s };
92         }
93 
94         inline literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>
lit(wchar_t const * s)95         lit(wchar_t const* s)
96         {
97             return { s };
98         }
99 
100         inline literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>
lit(std::basic_string<wchar_t> const & s)101         lit(std::basic_string<wchar_t> const& s)
102         {
103             return { s.c_str() };
104         }
105     }
106 
107     namespace ascii
108     {
109         inline literal_string<wchar_t const*, char_encoding::ascii>
string(wchar_t const * s)110         string(wchar_t const* s)
111         {
112             return { s };
113         }
114 
115         inline literal_string<std::basic_string<wchar_t>, char_encoding::ascii>
string(std::basic_string<wchar_t> const & s)116         string(std::basic_string<wchar_t> const& s)
117         {
118             return { s };
119         }
120 
121         inline literal_string<char const*, char_encoding::ascii, unused_type>
lit(char const * s)122         lit(char const* s)
123         {
124             return { s };
125         }
126 
127         template <typename Char>
128         literal_string<Char const*, char_encoding::ascii, unused_type>
lit(std::basic_string<Char> const & s)129         lit(std::basic_string<Char> const& s)
130         {
131             return { s.c_str() };
132         }
133     }
134 
135     namespace iso8859_1
136     {
137         inline literal_string<wchar_t const*, char_encoding::iso8859_1>
string(wchar_t const * s)138         string(wchar_t const* s)
139         {
140             return { s };
141         }
142 
143         inline literal_string<std::basic_string<wchar_t>, char_encoding::iso8859_1>
string(std::basic_string<wchar_t> const & s)144         string(std::basic_string<wchar_t> const& s)
145         {
146             return { s };
147         }
148 
149         inline literal_string<char const*, char_encoding::iso8859_1, unused_type>
lit(char const * s)150         lit(char const* s)
151         {
152             return { s };
153         }
154 
155         template <typename Char>
156         literal_string<Char const*, char_encoding::iso8859_1, unused_type>
lit(std::basic_string<Char> const & s)157         lit(std::basic_string<Char> const& s)
158         {
159             return { s.c_str() };
160         }
161     }
162 
163     using standard::string;
164     using standard::lit;
165     using standard_wide::string;
166     using standard_wide::lit;
167 
168     namespace extension
169     {
170         template <int N>
171         struct as_parser<char[N]>
172         {
173             typedef literal_string<
174                 char const*, char_encoding::standard, unused_type>
175             type;
176 
177             typedef type value_type;
178 
callboost::spirit::x3::extension::as_parser179             static type call(char const* s)
180             {
181                 return type(s);
182             }
183         };
184 
185         template <int N>
186         struct as_parser<char const[N]> : as_parser<char[N]> {};
187 
188         template <int N>
189         struct as_parser<wchar_t[N]>
190         {
191             typedef literal_string<
192                 wchar_t const*, char_encoding::standard_wide, unused_type>
193             type;
194 
195             typedef type value_type;
196 
callboost::spirit::x3::extension::as_parser197             static type call(wchar_t const* s)
198             {
199                 return type(s);
200             }
201         };
202 
203         template <int N>
204         struct as_parser<wchar_t const[N]> : as_parser<wchar_t[N]> {};
205 
206         template <>
207         struct as_parser<char const*>
208         {
209             typedef literal_string<
210                 char const*, char_encoding::standard, unused_type>
211             type;
212 
213             typedef type value_type;
214 
callboost::spirit::x3::extension::as_parser215             static type call(char const* s)
216             {
217                 return type(s);
218             }
219         };
220 
221         template <typename Char>
222         struct as_parser< std::basic_string<Char> >
223         {
224             typedef literal_string<
225                 Char const*, char_encoding::standard, unused_type>
226             type;
227 
228             typedef type value_type;
229 
callboost::spirit::x3::extension::as_parser230             static type call(std::basic_string<Char> const& s)
231             {
232                 return type(s.c_str());
233             }
234         };
235     }
236 
237     template <typename String, typename Encoding, typename Attribute>
238     struct get_info<literal_string<String, Encoding, Attribute>>
239     {
240         typedef std::string result_type;
operator ()boost::spirit::x3::get_info241         std::string operator()(literal_string<String, Encoding, Attribute> const& p) const
242         {
243             return '"' + to_utf8(p.str) + '"';
244         }
245     };
246 }}}
247 
248 #endif
249