File indexing completed on 2025-01-18 09:53:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_URL_GRAMMAR_STRING_TOKEN_HPP
0011 #define BOOST_URL_GRAMMAR_STRING_TOKEN_HPP
0012
0013 #include <boost/url/detail/config.hpp>
0014 #include <boost/core/detail/string_view.hpp>
0015 #include <boost/url/detail/except.hpp>
0016 #include <memory>
0017 #include <string>
0018
0019 namespace boost {
0020 namespace urls {
0021 namespace string_token {
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 struct arg
0050 {
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 virtual char* prepare(std::size_t n) = 0;
0069
0070
0071 virtual ~arg() = default;
0072 arg() = default;
0073 arg(arg&&) = default;
0074 arg(arg const&) = delete;
0075 arg& operator=(arg&&) = delete;
0076 arg& operator=(arg const&) = delete;
0077 };
0078
0079
0080
0081
0082
0083 #ifdef BOOST_URL_DOCS
0084 template<class T>
0085 using is_token = __see_below__;
0086 #else
0087 template<class T, class = void>
0088 struct is_token : std::false_type {};
0089
0090 template<class T>
0091 struct is_token<T, void_t<
0092 decltype(std::declval<T&>().prepare(
0093 std::declval<std::size_t>())),
0094 decltype(std::declval<T&>().result())
0095 > > : std::integral_constant<bool,
0096 std::is_convertible<decltype(
0097 std::declval<T&>().result()),
0098 typename T::result_type>::value &&
0099 std::is_same<decltype(
0100 std::declval<T&>().prepare(0)),
0101 char*>::value &&
0102 std::is_base_of<arg, T>::value &&
0103 std::is_convertible<T const volatile*,
0104 arg const volatile*>::value
0105 >
0106 {
0107 };
0108 #endif
0109
0110
0111
0112
0113
0114 #ifdef BOOST_URL_DOCS
0115 using return_string = __implementation_defined__;
0116 #else
0117 struct return_string
0118 : arg
0119 {
0120 using result_type = std::string;
0121
0122 char*
0123 prepare(std::size_t n) override
0124 {
0125 s_.resize(n);
0126 return &s_[0];
0127 }
0128
0129 result_type
0130 result() noexcept
0131 {
0132 return std::move(s_);
0133 }
0134
0135 private:
0136 result_type s_;
0137 };
0138 #endif
0139
0140
0141
0142
0143
0144 #ifdef BOOST_URL_DOCS
0145 template<
0146 class Allocator =
0147 std::allocator<char>>
0148 __implementation_defined__
0149 append_to(
0150 std::basic_string<
0151 char,
0152 std::char_traits<char>,
0153 Allocator>& s);
0154 #else
0155 template<class Alloc>
0156 struct append_to_t
0157 : arg
0158 {
0159 using string_type = std::basic_string<
0160 char, std::char_traits<char>,
0161 Alloc>;
0162
0163 using result_type = string_type&;
0164
0165 explicit
0166 append_to_t(
0167 string_type& s) noexcept
0168 : s_(s)
0169 {
0170 }
0171
0172 char*
0173 prepare(std::size_t n) override
0174 {
0175 std::size_t n0 = s_.size();
0176 if(n > s_.max_size() - n0)
0177 urls::detail::throw_length_error();
0178 s_.resize(n0 + n);
0179 return &s_[n0];
0180 }
0181
0182 result_type
0183 result() noexcept
0184 {
0185 return s_;
0186 }
0187
0188 private:
0189 string_type& s_;
0190 };
0191
0192 template<
0193 class Alloc =
0194 std::allocator<char>>
0195 append_to_t<Alloc>
0196 append_to(
0197 std::basic_string<
0198 char,
0199 std::char_traits<char>,
0200 Alloc>& s)
0201 {
0202 return append_to_t<Alloc>(s);
0203 }
0204 #endif
0205
0206
0207
0208
0209
0210 #ifdef BOOST_URL_DOCS
0211 template<
0212 class Allocator =
0213 std::allocator<char>>
0214 __implementation_defined__
0215 assign_to(
0216 std::basic_string<
0217 char,
0218 std::char_traits<char>,
0219 Allocator>& s);
0220 #else
0221 template<class Alloc>
0222 struct assign_to_t
0223 : arg
0224 {
0225 using string_type = std::basic_string<
0226 char, std::char_traits<char>,
0227 Alloc>;
0228
0229 using result_type = string_type&;
0230
0231 explicit
0232 assign_to_t(
0233 string_type& s) noexcept
0234 : s_(s)
0235 {
0236 }
0237
0238 char*
0239 prepare(std::size_t n) override
0240 {
0241 s_.resize(n);
0242 return &s_[0];
0243 }
0244
0245 result_type
0246 result() noexcept
0247 {
0248 return s_;
0249 }
0250
0251 private:
0252 string_type& s_;
0253 };
0254
0255 template<
0256 class Alloc =
0257 std::allocator<char>>
0258 assign_to_t<Alloc>
0259 assign_to(
0260 std::basic_string<
0261 char,
0262 std::char_traits<char>,
0263 Alloc>& s)
0264 {
0265 return assign_to_t<Alloc>(s);
0266 }
0267 #endif
0268
0269
0270
0271
0272
0273 #ifdef BOOST_URL_DOCS
0274 template<
0275 class Allocator =
0276 std::allocator<char>>
0277 __implementation_defined__
0278 preserve_size(
0279 std::basic_string<
0280 char,
0281 std::char_traits<char>,
0282 Allocator>& s);
0283 #else
0284 template<class Alloc>
0285 struct preserve_size_t
0286 : arg
0287 {
0288 using result_type = core::string_view;
0289
0290 using string_type = std::basic_string<
0291 char, std::char_traits<char>,
0292 Alloc>;
0293
0294 explicit
0295 preserve_size_t(
0296 string_type& s) noexcept
0297 : s_(s)
0298 {
0299 }
0300
0301 char*
0302 prepare(std::size_t n) override
0303 {
0304 n_ = n;
0305
0306
0307 if(s_.size() < n)
0308 s_.resize(n);
0309 return &s_[0];
0310 }
0311
0312 result_type
0313 result() noexcept
0314 {
0315 return core::string_view(
0316 s_.data(), n_);
0317 }
0318
0319 private:
0320 string_type& s_;
0321 std::size_t n_ = 0;
0322 };
0323
0324 template<
0325 class Alloc =
0326 std::allocator<char>>
0327 preserve_size_t<Alloc>
0328 preserve_size(
0329 std::basic_string<
0330 char,
0331 std::char_traits<char>,
0332 Alloc>& s)
0333 {
0334 return preserve_size_t<Alloc>(s);
0335 }
0336 #endif
0337
0338 }
0339
0340 namespace grammar {
0341 namespace string_token = ::boost::urls::string_token;
0342 }
0343
0344 }
0345 }
0346
0347 #endif