• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_METAPARSE_V1_CPP11_STRING_HPP
2 #define BOOST_METAPARSE_V1_CPP11_STRING_HPP
3 
4 // Copyright Abel Sinkovics (abel@sinkovics.hu)  2012.
5 // Distributed under the Boost Software License, Version 1.0.
6 //    (See accompanying file LICENSE_1_0.txt or copy at
7 //          http://www.boost.org/LICENSE_1_0.txt)
8 
9 #include <boost/metaparse/v1/cpp11/fwd/string.hpp>
10 #include <boost/metaparse/v1/string_tag.hpp>
11 #include <boost/metaparse/v1/impl/string_iterator.hpp>
12 #include <boost/metaparse/v1/cpp11/impl/empty_string.hpp>
13 #include <boost/metaparse/v1/cpp11/impl/size.hpp>
14 #include <boost/metaparse/v1/cpp11/impl/pop_front.hpp>
15 #include <boost/metaparse/v1/cpp11/impl/push_front_c.hpp>
16 #include <boost/metaparse/v1/cpp11/impl/push_back_c.hpp>
17 #include <boost/metaparse/v1/cpp11/impl/pop_back.hpp>
18 #include <boost/metaparse/v1/cpp11/impl/string_at.hpp>
19 
20 #include <type_traits>
21 
22 /*
23  * The string type
24  */
25 
26 namespace boost
27 {
28   namespace metaparse
29   {
30     namespace v1
31     {
32       template <char... Cs>
33       struct string
34       {
35         typedef string type;
36         typedef string_tag tag;
37       };
38     }
39   }
40 }
41 
42 /*
43  * Boost.MPL overloads
44  */
45 
46 namespace boost
47 {
48   namespace mpl
49   {
50     // push_back
51     template <class S>
52     struct push_back_impl;
53 
54     template <>
55     struct push_back_impl<boost::metaparse::v1::string_tag>
56     {
57       typedef push_back_impl type;
58 
59       template <class S, class C>
60       struct apply :
61         boost::metaparse::v1::impl::push_back_c<
62           typename S::type,
63           C::type::value
64         >
65       {};
66     };
67 
68     // pop_back
69     template <class S>
70     struct pop_back_impl;
71 
72     template <>
73     struct pop_back_impl<boost::metaparse::v1::string_tag>
74     {
75       typedef pop_back_impl type;
76 
77       template <class S>
78       struct apply : boost::metaparse::v1::impl::pop_back<S> {};
79     };
80 
81     // push_front
82     template <class S>
83     struct push_front_impl;
84 
85     template <>
86     struct push_front_impl<boost::metaparse::v1::string_tag>
87     {
88       typedef push_front_impl type;
89 
90       template <class S, class C>
91       struct apply :
92         boost::metaparse::v1::impl::push_front_c<
93           typename S::type,
94           C::type::value
95         >
96       {};
97     };
98 
99     // pop_front
100     template <class S>
101     struct pop_front_impl;
102 
103     template <>
104     struct pop_front_impl<boost::metaparse::v1::string_tag>
105     {
106       typedef pop_front_impl type;
107 
108       template <class S>
109       struct apply : boost::metaparse::v1::impl::pop_front<S> {};
110     };
111 
112     // clear
113     template <class S>
114     struct clear_impl;
115 
116     template <>
117     struct clear_impl<boost::metaparse::v1::string_tag>
118     {
119       typedef clear_impl type;
120 
121       template <class S>
122       struct apply : boost::metaparse::v1::string<> {};
123     };
124 
125     // begin
126     template <class S>
127     struct begin_impl;
128 
129     template <>
130     struct begin_impl<boost::metaparse::v1::string_tag>
131     {
132       typedef begin_impl type;
133 
134       template <class S>
135       struct apply :
136         boost::metaparse::v1::impl::string_iterator<typename S::type, 0>
137       {};
138     };
139 
140     // end
141     template <class S>
142     struct end_impl;
143 
144     template <>
145     struct end_impl<boost::metaparse::v1::string_tag>
146     {
147       typedef end_impl type;
148 
149       template <class S>
150       struct apply :
151         boost::metaparse::v1::impl::string_iterator<
152           typename S::type,
153           boost::metaparse::v1::impl::size<typename S::type>::type::value
154         >
155       {};
156     };
157 
158     // equal_to
159     template <class A, class B>
160     struct equal_to_impl;
161 
162     template <>
163     struct equal_to_impl<
164       boost::metaparse::v1::string_tag,
165       boost::metaparse::v1::string_tag
166     >
167     {
168       typedef equal_to_impl type;
169 
170       template <class A, class B>
171       struct apply : std::is_same<typename A::type, typename B::type> {};
172     };
173 
174     template <class T>
175     struct equal_to_impl<boost::metaparse::v1::string_tag, T>
176     {
177       typedef equal_to_impl type;
178 
179       template <class, class>
180       struct apply : false_ {};
181     };
182 
183     template <class T>
184     struct equal_to_impl<T, boost::metaparse::v1::string_tag> :
185       equal_to_impl<boost::metaparse::v1::string_tag, T>
186     {};
187 
188     // c_str
189     template <class S>
190     struct c_str;
191 
192     template <char... Cs>
193     struct c_str<boost::metaparse::v1::string<Cs...>>
194     {
195       typedef c_str type;
196       static constexpr char value[sizeof...(Cs) + 1] = {Cs..., 0};
197     };
198 
199     template <>
200     struct c_str<boost::metaparse::v1::string<>> :
201       boost::metaparse::v1::impl::empty_string<>
202     {};
203 
204     template <char... Cs>
205     constexpr char c_str<boost::metaparse::v1::string<Cs...>>::value[];
206   }
207 }
208 
209 #if __clang__
210 #  if __has_extension(cxx_string_literal_templates)
211 #    define BOOST_METAPARSE_V1_STRING(...) ::boost::metaparse::string<__VA_ARGS__>
212 #  else
213 #    include <boost/metaparse/v1/cpp11/impl/string.hpp>
214 #  endif
215 #else
216 #  include <boost/metaparse/v1/cpp11/impl/string.hpp>
217 #endif
218 
219 #endif
220 
221