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