1 //
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 // Copyright (c) 2019-2020 Krystian Stasiowski (sdkrystian at gmail dot com)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/boostorg/static_string
9 //
10
11 #ifndef BOOST_STATIC_STRING_STATIC_STRING_HPP
12 #define BOOST_STATIC_STRING_STATIC_STRING_HPP
13
14 // External include guard
15 #ifndef BOOST_STATIC_STRING_CONFIG_HPP
16 #include <boost/static_string/config.hpp>
17 #endif
18
19 #include <algorithm>
20 #include <cstdint>
21 #include <cstdio>
22 #include <cwchar>
23 #include <functional>
24 #include <initializer_list>
25 #include <iosfwd>
26 #include <type_traits>
27
28 namespace boost {
29 namespace static_strings {
30
31 #ifndef BOOST_STATIC_STRING_DOCS
32 template<std::size_t N, typename CharT, typename Traits>
33 class basic_static_string;
34
35 //------------------------------------------------------------------------------
36 //
37 // Aliases
38 //
39 //------------------------------------------------------------------------------
40
41 template<std::size_t N>
42 using static_string =
43 basic_static_string<N, char, std::char_traits<char>>;
44
45 template<std::size_t N>
46 using static_wstring =
47 basic_static_string<N, wchar_t, std::char_traits<wchar_t>>;
48
49 template<std::size_t N>
50 using static_u16string =
51 basic_static_string<N, char16_t, std::char_traits<char16_t>>;
52
53 template<std::size_t N>
54 using static_u32string =
55 basic_static_string<N, char32_t, std::char_traits<char32_t>>;
56
57 #ifdef BOOST_STATIC_STRING_CPP20
58 template<std::size_t N>
59 using static_u8string =
60 basic_static_string<N, char8_t, std::char_traits<char8_t>>;
61 #endif
62
63 //--------------------------------------------------------------------------
64 //
65 // Detail
66 //
67 //--------------------------------------------------------------------------
68
69 namespace detail {
70
71 // Find the smallest width integral type that can hold a value as large as N (Glen Fernandes)
72 template<std::size_t N>
73 using smallest_width =
74 typename std::conditional<(N <= (std::numeric_limits<unsigned char>::max)()), unsigned char,
75 typename std::conditional<(N <= (std::numeric_limits<unsigned short>::max)()), unsigned short,
76 typename std::conditional<(N <= (std::numeric_limits<unsigned int>::max)()), unsigned int,
77 typename std::conditional<(N <= (std::numeric_limits<unsigned long>::max)()), unsigned long,
78 typename std::conditional<(N <= (std::numeric_limits<unsigned long long>::max)()), unsigned long long,
79 std::size_t>::type>::type>::type>::type>::type;
80
81 // std::is_nothrow_convertible is C++20
82 template<typename To>
83 void is_nothrow_convertible_helper(To) noexcept;
84
85 // MSVC is unable to parse this as a single expression, so a helper is needed
86 template<typename From, typename To, typename =
87 decltype(is_nothrow_convertible_helper<To>(std::declval<From>()))>
88 struct is_nothrow_convertible_msvc_helper
89 {
90 static const bool value =
91 noexcept(is_nothrow_convertible_helper<To>(std::declval<From>()));
92 };
93
94 template<typename From, typename To, typename = void>
95 struct is_nothrow_convertible
96 : std::false_type { };
97
98 template<typename From, typename To>
99 struct is_nothrow_convertible<From, To, typename std::enable_if<
100 is_nothrow_convertible_msvc_helper<From, To>::value>::type>
101 : std::true_type { };
102
103 // GCC 4.8, 4.9 workaround for void_t to make the defining-type-id dependant
104 template<typename...>
105 struct void_t_helper
106 {
107 using type = void;
108 };
109
110 // void_t for c++11
111 template<typename... Ts>
112 using void_t = typename void_t_helper<Ts...>::type;
113
114 // Check if a type can be used for templated
115 // overloads string_view_type
116 template<typename T, typename CharT, typename Traits, typename = void>
117 struct enable_if_viewable { };
118
119 template<typename T, typename CharT, typename Traits>
120 struct enable_if_viewable<T, CharT, Traits,
121 typename std::enable_if<
122 std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value &&
123 !std::is_convertible<const T&, const CharT*>::value>::type>
124 {
125 using type = void;
126 };
127
128 template<typename T, typename CharT, typename Traits>
129 using enable_if_viewable_t = typename enable_if_viewable<T, CharT, Traits>::type;
130
131 // Simplified check for if a type is an iterator
132 template<typename T, typename = void>
133 struct is_iterator : std::false_type { };
134
135 template<typename T>
136 struct is_iterator<T,
137 typename std::enable_if<std::is_class<T>::value,
138 void_t<typename T::iterator_category>>::type>
139 : std::true_type { };
140
141 template<typename T>
142 struct is_iterator<T*, void>
143 : std::true_type { };
144
145 template<typename T, typename = void>
146 struct is_input_iterator : std::false_type { };
147
148 template<typename T>
149 struct is_input_iterator<T, typename std::enable_if<is_iterator<T>::value &&
150 std::is_convertible<typename std::iterator_traits<T>::iterator_category,
151 std::input_iterator_tag>::value>::type>
152 : std::true_type { };
153
154 template<typename T, typename = void>
155 struct is_forward_iterator : std::false_type { };
156
157 template<typename T>
158 struct is_forward_iterator<T, typename std::enable_if<is_iterator<T>::value &&
159 std::is_convertible<typename std::iterator_traits<T>::iterator_category,
160 std::forward_iterator_tag>::value>::type>
161 : std::true_type { };
162
163 template<typename T, typename = void>
164 struct is_subtractable
165 : std::false_type { };
166
167 template<typename T>
168 struct is_subtractable<T, void_t<decltype(std::declval<T&>() - std::declval<T&>())>>
169 : std::true_type { };
170
171 // constexpr distance for c++14
172 template<
173 typename ForwardIt,
174 typename std::enable_if<!is_subtractable<ForwardIt>::value>::type* = nullptr>
175 BOOST_STATIC_STRING_CPP14_CONSTEXPR
176 std::size_t
distance(ForwardIt first,ForwardIt last)177 distance(ForwardIt first, ForwardIt last)
178 {
179 std::size_t dist = 0;
180 for (; first != last; ++first, ++dist);
181 return dist;
182 }
183
184 template<
185 typename RandomIt,
186 typename std::enable_if<is_subtractable<RandomIt>::value>::type* = nullptr>
187 BOOST_STATIC_STRING_CPP14_CONSTEXPR
188 std::size_t
distance(RandomIt first,RandomIt last)189 distance(RandomIt first, RandomIt last)
190 {
191 return last - first;
192 }
193
194 // Copy using traits, respecting iterator rules
195 template<typename Traits, typename InputIt, typename CharT>
196 BOOST_STATIC_STRING_CPP14_CONSTEXPR
197 void
copy_with_traits(InputIt first,InputIt last,CharT * out)198 copy_with_traits(
199 InputIt first,
200 InputIt last,
201 CharT* out)
202 {
203 for (; first != last; ++first, ++out)
204 Traits::assign(*out, *first);
205 }
206
207 // Optimization for using the smallest possible type
208 template<std::size_t N, typename CharT, typename Traits>
209 class static_string_base
210 {
211 private:
212 using size_type = smallest_width<N>;
213 using value_type = typename Traits::char_type;
214 using pointer = value_type*;
215 using const_pointer = const value_type*;
216 public:
217 BOOST_STATIC_STRING_CPP11_CONSTEXPR
static_string_base()218 static_string_base() noexcept { };
219
220 BOOST_STATIC_STRING_CPP14_CONSTEXPR
221 pointer
data_impl()222 data_impl() noexcept
223 {
224 return data_;
225 }
226
227 BOOST_STATIC_STRING_CPP14_CONSTEXPR
228 const_pointer
data_impl() const229 data_impl() const noexcept
230 {
231 return data_;
232 }
233
234 BOOST_STATIC_STRING_CPP11_CONSTEXPR
235 std::size_t
size_impl() const236 size_impl() const noexcept
237 {
238 return size_;
239 }
240
241 BOOST_STATIC_STRING_CPP14_CONSTEXPR
242 std::size_t
set_size(std::size_t n)243 set_size(std::size_t n) noexcept
244 {
245 // Functions that set size will throw
246 // if the new size would exceed max_size()
247 // therefore we can guarantee that this will
248 // not lose data.
249 return size_ = size_type(n);
250 }
251
252 BOOST_STATIC_STRING_CPP14_CONSTEXPR
253 void
term_impl()254 term_impl() noexcept
255 {
256 Traits::assign(data_[size_], value_type());
257 }
258
259 size_type size_ = 0;
260 #ifdef BOOST_STATIC_STRING_CPP20
261 value_type data_[N + 1];
262 #else
263 value_type data_[N + 1]{};
264 #endif
265 };
266
267 // Optimization for when the size is 0
268 template<typename CharT, typename Traits>
269 class static_string_base<0, CharT, Traits>
270 {
271 private:
272 using value_type = typename Traits::char_type;
273 using pointer = value_type*;
274 public:
275 BOOST_STATIC_STRING_CPP11_CONSTEXPR
static_string_base()276 static_string_base() noexcept { }
277
278 // Modifying the null terminator is UB
279 BOOST_STATIC_STRING_CPP11_CONSTEXPR
280 pointer
data_impl() const281 data_impl() const noexcept
282 {
283 return const_cast<pointer>(&null_);
284 }
285
286 BOOST_STATIC_STRING_CPP11_CONSTEXPR
287 std::size_t
size_impl() const288 size_impl() const noexcept
289 {
290 return 0;
291 }
292
293 BOOST_STATIC_STRING_CPP11_CONSTEXPR
294 std::size_t
set_size(std::size_t) const295 set_size(std::size_t) const noexcept
296 {
297 return 0;
298 }
299
300 BOOST_STATIC_STRING_CPP14_CONSTEXPR
301 void
term_impl() const302 term_impl() const noexcept { }
303
304 private:
305 static constexpr const value_type null_{};
306 };
307
308 // This is only needed in C++14 and lower.
309 // see http://eel.is/c++draft/depr.static.constexpr
310 #ifndef BOOST_STATIC_STRING_CPP17
311 template<typename CharT, typename Traits>
312 constexpr
313 const
314 typename static_string_base<0, CharT, Traits>::value_type
315 static_string_base<0, CharT, Traits>::
316 null_;
317 #endif
318
319 template<typename CharT, typename Traits>
320 BOOST_STATIC_STRING_CPP14_CONSTEXPR
321 inline
322 int
lexicographical_compare(const CharT * s1,std::size_t n1,const CharT * s2,std::size_t n2)323 lexicographical_compare(
324 const CharT* s1,
325 std::size_t n1,
326 const CharT* s2,
327 std::size_t n2) noexcept
328 {
329 if(n1 < n2)
330 return Traits::compare(
331 s1, s2, n1) <= 0 ? -1 : 1;
332 if(n1 > n2)
333 return Traits::compare(
334 s1, s2, n2) >= 0 ? 1 : -1;
335 return Traits::compare(s1, s2, n1);
336 }
337
338 template<typename Traits, typename Integer>
339 inline
340 char*
integer_to_string(char * str_end,Integer value,std::true_type)341 integer_to_string(
342 char* str_end,
343 Integer value,
344 std::true_type) noexcept
345 {
346 if (value == 0)
347 {
348 Traits::assign(*--str_end, '0');
349 return str_end;
350 }
351 if (value < 0)
352 {
353 const bool is_min = value == std::numeric_limits<Integer>::min();
354 // negation of a min value cannot be represented
355 if (is_min)
356 value = std::numeric_limits<Integer>::max();
357 else
358 value = -value;
359 const auto last_char = str_end - 1;
360 for (; value > 0; value /= 10)
361 Traits::assign(*--str_end, "0123456789"[value % 10]);
362 // minimum values are powers of 2, so it will
363 // never terminate with a 9.
364 if (is_min)
365 Traits::assign(*last_char, Traits::to_char_type(
366 Traits::to_int_type(*last_char) + 1));
367 Traits::assign(*--str_end, '-');
368 return str_end;
369 }
370 for (; value > 0; value /= 10)
371 Traits::assign(*--str_end, "0123456789"[value % 10]);
372 return str_end;
373 }
374
375 template<typename Traits, typename Integer>
376 inline
377 char*
integer_to_string(char * str_end,Integer value,std::false_type)378 integer_to_string(
379 char* str_end,
380 Integer value,
381 std::false_type) noexcept
382 {
383 if (value == 0)
384 {
385 Traits::assign(*--str_end, '0');
386 return str_end;
387 }
388 for (; value > 0; value /= 10)
389 Traits::assign(*--str_end, "0123456789"[value % 10]);
390 return str_end;
391 }
392
393 template<typename Traits, typename Integer>
394 inline
395 wchar_t*
integer_to_wstring(wchar_t * str_end,Integer value,std::true_type)396 integer_to_wstring(
397 wchar_t* str_end,
398 Integer value,
399 std::true_type) noexcept
400 {
401 if (value == 0)
402 {
403 Traits::assign(*--str_end, L'0');
404 return str_end;
405 }
406 if (value < 0)
407 {
408 const bool is_min = value == std::numeric_limits<Integer>::min();
409 // negation of a min value cannot be represented
410 if (is_min)
411 value = std::numeric_limits<Integer>::max();
412 else
413 value = -value;
414 const auto last_char = str_end - 1;
415 for (; value > 0; value /= 10)
416 Traits::assign(*--str_end, L"0123456789"[value % 10]);
417 // minimum values are powers of 2, so it will
418 // never terminate with a 9.
419 if (is_min)
420 Traits::assign(*last_char, Traits::to_char_type(
421 Traits::to_int_type(*last_char) + 1));
422 Traits::assign(*--str_end, L'-');
423 return str_end;
424 }
425 for (; value > 0; value /= 10)
426 Traits::assign(*--str_end, L"0123456789"[value % 10]);
427 return str_end;
428 }
429
430 template<typename Traits, typename Integer>
431 inline
432 wchar_t*
integer_to_wstring(wchar_t * str_end,Integer value,std::false_type)433 integer_to_wstring(
434 wchar_t* str_end,
435 Integer value,
436 std::false_type) noexcept
437 {
438 if (value == 0)
439 {
440 Traits::assign(*--str_end, L'0');
441 return str_end;
442 }
443 for (; value > 0; value /= 10)
444 Traits::assign(*--str_end, L"0123456789"[value % 10]);
445 return str_end;
446 }
447
448 template<std::size_t N, typename Integer>
449 inline
450 static_string<N>
to_static_string_int_impl(Integer value)451 to_static_string_int_impl(Integer value) noexcept
452 {
453 char buffer[N];
454 const auto digits_end = std::end(buffer);
455 const auto digits_begin = integer_to_string<std::char_traits<char>, Integer>(
456 digits_end, value, std::is_signed<Integer>{});
457 return static_string<N>(digits_begin, std::distance(digits_begin, digits_end));
458 }
459
460 template<std::size_t N, typename Integer>
461 inline
462 static_wstring<N>
to_static_wstring_int_impl(Integer value)463 to_static_wstring_int_impl(Integer value) noexcept
464 {
465 wchar_t buffer[N];
466 const auto digits_end = std::end(buffer);
467 const auto digits_begin = integer_to_wstring<std::char_traits<wchar_t>, Integer>(
468 digits_end, value, std::is_signed<Integer>{});
469 return static_wstring<N>(digits_begin, std::distance(digits_begin, digits_end));
470 }
471
472 BOOST_STATIC_STRING_CPP11_CONSTEXPR
473 inline
474 int
count_digits(std::size_t value)475 count_digits(std::size_t value)
476 {
477 return value < 10 ? 1 : count_digits(value / 10) + 1;
478 }
479
480 // Ignore -Wformat-truncation, we know what
481 // we are doing here. The version check does
482 // not need to be extremely precise.
483 #if defined(__GNUC__) && __GNUC__ >= 7
484 #pragma GCC diagnostic push
485 #pragma GCC diagnostic ignored "-Wformat-truncation"
486 #endif
487
488 template<std::size_t N>
489 inline
490 static_string<N>
to_static_string_float_impl(double value)491 to_static_string_float_impl(double value) noexcept
492 {
493 // we have to assume here that no reasonable implementation
494 // will require more than 2^63 chars to represent a float value.
495 const long long narrow =
496 static_cast<long long>(N);
497 // extra one needed for null terminator
498 char buffer[N + 1];
499 // we know that a formatting error will not occur, so
500 // we assume that the result is always positive
501 if (std::size_t(std::snprintf(buffer, N + 1, "%f", value)) > N)
502 {
503 // the + 4 is for the decimal, 'e',
504 // its sign, and the sign of the integral portion
505 const int reserved_count =
506 (std::max)(2, count_digits(
507 std::numeric_limits<double>::max_exponent10)) + 4;
508 const int precision = narrow > reserved_count ?
509 N - reserved_count : 0;
510 // switch to scientific notation
511 std::snprintf(buffer, N + 1, "%.*e", precision, value);
512 }
513 // this will not throw
514 return static_string<N>(buffer);
515 }
516
517 template<std::size_t N>
518 inline
519 static_string<N>
to_static_string_float_impl(long double value)520 to_static_string_float_impl(long double value) noexcept
521 {
522 // we have to assume here that no reasonable implementation
523 // will require more than 2^63 chars to represent a float value.
524 const long long narrow =
525 static_cast<long long>(N);
526 // extra one needed for null terminator
527 char buffer[N + 1];
528 // snprintf returns the number of characters
529 // that would have been written
530 // we know that a formatting error will not occur, so
531 // we assume that the result is always positive
532 if (std::size_t(std::snprintf(buffer, N + 1, "%Lf", value)) > N)
533 {
534 // the + 4 is for the decimal, 'e',
535 // its sign, and the sign of the integral portion
536 const int reserved_count =
537 (std::max)(2, count_digits(
538 std::numeric_limits<long double>::max_exponent10)) + 4;
539 const int precision = narrow > reserved_count ?
540 N - reserved_count : 0;
541 // switch to scientific notation
542 std::snprintf(buffer, N + 1, "%.*Le", precision, value);
543 }
544 // this will not throw
545 return static_string<N>(buffer);
546 }
547
548 template<std::size_t N>
549 inline
550 static_wstring<N>
to_static_wstring_float_impl(double value)551 to_static_wstring_float_impl(double value) noexcept
552 {
553 // we have to assume here that no reasonable implementation
554 // will require more than 2^63 chars to represent a float value.
555 const long long narrow =
556 static_cast<long long>(N);
557 // extra one needed for null terminator
558 wchar_t buffer[N + 1];
559 // swprintf returns a negative number if it can't
560 // fit all the characters in the buffer.
561 // mingw has a non-standard swprintf, so
562 // this just covers all the bases. short
563 // circuit evaluation will ensure that the
564 // second operand is not evaluated on conforming
565 // implementations.
566 const long long num_written =
567 std::swprintf(buffer, N + 1, L"%f", value);
568 if (num_written < 0 ||
569 num_written > narrow)
570 {
571 // the + 4 is for the decimal, 'e',
572 // its sign, and the sign of the integral portion
573 const int reserved_count =
574 (std::max)(2, count_digits(
575 std::numeric_limits<double>::max_exponent10)) + 4;
576 const int precision = narrow > reserved_count ?
577 N - reserved_count : 0;
578 // switch to scientific notation
579 std::swprintf(buffer, N + 1, L"%.*e", precision, value);
580 }
581 // this will not throw
582 return static_wstring<N>(buffer);
583 }
584
585 template<std::size_t N>
586 inline
587 static_wstring<N>
to_static_wstring_float_impl(long double value)588 to_static_wstring_float_impl(long double value) noexcept
589 {
590 // we have to assume here that no reasonable implementation
591 // will require more than 2^63 chars to represent a float value.
592 const long long narrow =
593 static_cast<long long>(N);
594 // extra one needed for null terminator
595 wchar_t buffer[N + 1];
596 // swprintf returns a negative number if it can't
597 // fit all the characters in the buffer.
598 // mingw has a non-standard swprintf, so
599 // this just covers all the bases. short
600 // circuit evaluation will ensure that the
601 // second operand is not evaluated on conforming
602 // implementations.
603 const long long num_written =
604 std::swprintf(buffer, N + 1, L"%Lf", value);
605 if (num_written < 0 ||
606 num_written > narrow)
607 {
608 // the + 4 is for the decimal, 'e',
609 // its sign, and the sign of the integral portion
610 const int reserved_count =
611 (std::max)(2, count_digits(
612 std::numeric_limits<long double>::max_exponent10)) + 4;
613 const int precision = narrow > reserved_count ?
614 N - reserved_count : 0;
615 // switch to scientific notation
616 std::swprintf(buffer, N + 1, L"%.*Le", precision, value);
617 }
618 // this will not throw
619 return static_wstring<N>(buffer);
620 }
621
622 #if defined(__GNUC__) && __GNUC__ >= 7
623 #pragma GCC diagnostic pop
624 #endif
625
626 template<typename Traits, typename CharT, typename ForwardIterator>
627 BOOST_STATIC_STRING_CPP14_CONSTEXPR
628 inline
629 ForwardIterator
find_not_of(ForwardIterator first,ForwardIterator last,const CharT * str,std::size_t n)630 find_not_of(
631 ForwardIterator first,
632 ForwardIterator last,
633 const CharT* str,
634 std::size_t n) noexcept
635 {
636 for (; first != last; ++first)
637 if (!Traits::find(str, n, *first))
638 return first;
639 return last;
640 }
641
642 // constexpr search for C++14
643 template<typename ForwardIt1, typename ForwardIt2, typename BinaryPredicate>
644 BOOST_STATIC_STRING_CPP14_CONSTEXPR
645 inline
646 ForwardIt1
search(ForwardIt1 first,ForwardIt1 last,ForwardIt2 s_first,ForwardIt2 s_last,BinaryPredicate p)647 search(
648 ForwardIt1 first,
649 ForwardIt1 last,
650 ForwardIt2 s_first,
651 ForwardIt2 s_last,
652 BinaryPredicate p)
653 {
654 for (; ; ++first)
655 {
656 ForwardIt1 it = first;
657 for (ForwardIt2 s_it = s_first; ; ++it, ++s_it)
658 {
659 if (s_it == s_last)
660 return first;
661 if (it == last)
662 return last;
663 if (!p(*it, *s_it))
664 break;
665 }
666 }
667 }
668
669 template<typename InputIt, typename ForwardIt, typename BinaryPredicate>
670 BOOST_STATIC_STRING_CPP14_CONSTEXPR
671 inline
672 InputIt
find_first_of(InputIt first,InputIt last,ForwardIt s_first,ForwardIt s_last,BinaryPredicate p)673 find_first_of(
674 InputIt first,
675 InputIt last,
676 ForwardIt s_first,
677 ForwardIt s_last,
678 BinaryPredicate p)
679 {
680 for (; first != last; ++first)
681 for (ForwardIt it = s_first; it != s_last; ++it)
682 if (p(*first, *it))
683 return first;
684 return last;
685 }
686
687 // KRYSTIAN TODO: add a constexpr rotate
688
689 // Check if a pointer lies within the range {src_first, src_last)
690 // without unspecified behavior, allowing it to be used
691 // in a constant evaluation.
692 template<typename T>
693 BOOST_STATIC_STRING_CPP14_CONSTEXPR
694 inline
695 bool
ptr_in_range(const T * src_first,const T * src_last,const T * ptr)696 ptr_in_range(
697 const T* src_first,
698 const T* src_last,
699 const T* ptr)
700 {
701 #if defined(BOOST_STATIC_STRING_CPP14) && \
702 defined(BOOST_STATIC_STRING_IS_CONST_EVAL)
703 // Our second best option is to use is_constant_evaluated
704 // and a loop that checks for equality, since equality for
705 // pointer to object types is never unspecified in this case.
706 if (BOOST_STATIC_STRING_IS_CONST_EVAL)
707 {
708 for (; src_first != src_last; ++src_first)
709 if (ptr == src_first)
710 return true;
711 return false;
712 }
713 #endif
714 // We want to make this usable in constant expressions as much as possible
715 // while retaining the guarentee that the comparison has a strict total ordering.
716 // We also want this to be fast. Since different compilers have differing levels
717 // of conformance, we will settle for the best option that is available.
718 // We don't care about this in C++11, since this function would have
719 // no applications in constant expressions.
720 #if defined(BOOST_STATIC_STRING_CPP14) && \
721 defined(BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS)
722 // If library comparison functions don't work,
723 // we can use try builtin comparison operators instead.
724 return ptr >= src_first && ptr < src_last;
725 #else
726 // Use the library comparison functions if we can't use
727 // is_constant_evaluated or if we don't need to.
728 return std::greater_equal<const T*>()(ptr, src_first) &&
729 std::less<const T*>()(ptr, src_last);
730 #endif
731 }
732
733 // This workaround is for gcc 5,
734 // which prohibits throw expressions in constexpr
735 // functions, but for some reason permits them in
736 // constructors.
737 #ifdef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
738 template<typename Exception>
739 struct throw_exception
740 {
741 BOOST_STATIC_STRING_NORETURN
742 BOOST_STATIC_STRING_CPP14_CONSTEXPR
throw_exceptionboost::static_strings::detail::throw_exception743 throw_exception(const char* msg)
744 {
745 BOOST_STATIC_STRING_THROW(Exception(msg));
746 }
747 };
748 #else
749 template<typename Exception>
750 BOOST_STATIC_STRING_NORETURN
751 inline
752 void
throw_exception(const char * msg)753 throw_exception(const char* msg)
754 {
755 BOOST_STATIC_STRING_THROW(Exception(msg));
756 }
757 #endif
758
759 } // detail
760 #endif
761
762 //--------------------------------------------------------------------------
763 //
764 // static_string
765 //
766 //--------------------------------------------------------------------------
767
768 /** A fixed-capacity string.
769
770 These objects behave like `std::string` except that the storage
771 is not dynamically allocated but rather fixed in size, and
772 stored in the object itself.
773
774 These strings offer performance advantages when an algorithm
775 can execute with a reasonable upper limit on the size of a value.
776
777 @par Aliases
778
779 The following alias templates are provided for convenience:
780
781 @code
782 template<std::size_t N>
783 using static_string =
784 basic_static_string<N, char, std::char_traits<char>>;
785 @endcode
786
787 @code
788 template<std::size_t N>
789 using static_wstring =
790 basic_static_string<N, wchar_t, std::char_traits<wchar_t>>;
791 @endcode
792
793 @code
794 template<std::size_t N>
795 using static_u16string =
796 basic_static_string<N, char16_t, std::char_traits<char16_t>>;
797 @endcode
798
799 @code
800 template<std::size_t N>
801 using static_u32string =
802 basic_static_string<N, char32_t, std::char_traits<char32_t>>;
803 @endcode
804
805 Addtionally, the alias template `static_u8string` is provided in C++20
806
807 @code
808 template<std::size_t N>
809 using static_u8string =
810 basic_static_string<N, char8_t, std::char_traits<char8_t>>;
811 @endcode
812
813 @see to_static_string
814 */
815 template<std::size_t N, typename CharT,
816 typename Traits = std::char_traits<CharT>>
817 class basic_static_string
818 #ifndef BOOST_STATIC_STRING_DOCS
819 : private detail::static_string_base<N, CharT, Traits>
820 #endif
821 {
822 private:
823 template<std::size_t, class, class>
824 friend class basic_static_string;
825 public:
826 //--------------------------------------------------------------------------
827 //
828 // Member types
829 //
830 //--------------------------------------------------------------------------
831
832 /// The traits type.
833 using traits_type = Traits;
834
835 /// The character type.
836 using value_type = typename traits_type::char_type;
837
838 /// The size type.
839 using size_type = std::size_t;
840
841 /// The difference type.
842 using difference_type = std::ptrdiff_t;
843
844 /// The pointer type.
845 using pointer = value_type*;
846
847 /// The reference type.
848 using reference = value_type&;
849
850 /// The constant pointer type.
851 using const_pointer = const value_type*;
852
853 /// The constant reference type.
854 using const_reference = const value_type&;
855
856 /// The iterator type.
857 using iterator = value_type*;
858
859 /// The constant iterator type.
860 using const_iterator = const value_type*;
861
862 /// The reverse iterator type.
863 using reverse_iterator =
864 std::reverse_iterator<iterator>;
865
866 /// The constant reverse iterator type.
867 using const_reverse_iterator =
868 std::reverse_iterator<const_iterator>;
869
870 /// The string view type.
871 using string_view_type =
872 basic_string_view<value_type, traits_type>;
873
874 //--------------------------------------------------------------------------
875 //
876 // Constants
877 //
878 //--------------------------------------------------------------------------
879
880 /// Maximum size of the string excluding any null terminator
881 static constexpr size_type static_capacity = N;
882
883 /// A special index
884 static constexpr size_type npos = size_type(-1);
885
886 //--------------------------------------------------------------------------
887 //
888 // Construction
889 //
890 //--------------------------------------------------------------------------
891
892 /** Constructor.
893
894 Construct an empty string
895 */
896 BOOST_STATIC_STRING_CPP11_CONSTEXPR
basic_static_string()897 basic_static_string() noexcept
898 {
899 #ifdef BOOST_STATIC_STRING_CPP20
900 term();
901 #endif
902 }
903
904 /** Constructor.
905
906 Construct the string with `count` copies of character `ch`.
907
908 The behavior is undefined if `count >= npos`
909 */
910 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(size_type count,value_type ch)911 basic_static_string(
912 size_type count,
913 value_type ch)
914 {
915 assign(count, ch);
916 }
917
918 /** Constructor.
919
920 Construct with a substring (pos, other.size()) of `other`.
921 */
922 template<std::size_t M>
923 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const basic_static_string<M,CharT,Traits> & other,size_type pos)924 basic_static_string(
925 const basic_static_string<M, CharT, Traits>& other,
926 size_type pos)
927 {
928 assign(other, pos);
929 }
930
931 /** Constructor.
932
933 Construct with a substring (pos, count) of `other`.
934 */
935 template<std::size_t M>
936 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const basic_static_string<M,CharT,Traits> & other,size_type pos,size_type count)937 basic_static_string(
938 const basic_static_string<M, CharT, Traits>& other,
939 size_type pos,
940 size_type count)
941 {
942 assign(other, pos, count);
943 }
944
945 /** Constructor.
946
947 Construct with the first `count` characters of `s`, including nulls.
948 */
949 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const_pointer s,size_type count)950 basic_static_string(
951 const_pointer s,
952 size_type count)
953 {
954 assign(s, count);
955 }
956
957 /** Constructor.
958
959 Construct from a null terminated string.
960 */
961 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const_pointer s)962 basic_static_string(const_pointer s)
963 {
964 assign(s);
965 }
966
967 /** Constructor.
968
969 Construct from a range of characters
970 */
971 template<typename InputIterator
972 #ifndef BOOST_STATIC_STRING_DOCS
973 , typename std::enable_if<
974 detail::is_input_iterator<InputIterator>
975 ::value>::type* = nullptr
976 #endif
977 >
978 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(InputIterator first,InputIterator last)979 basic_static_string(
980 InputIterator first,
981 InputIterator last)
982 {
983 // KRYSTIAN TODO: we can use a better algorithm if this is a forward iterator
984 assign(first, last);
985 }
986
987 /** Constructor.
988
989 Copy constructor.
990 */
991 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const basic_static_string & other)992 basic_static_string(const basic_static_string& other) noexcept
993 {
994 assign(other);
995 }
996
997 /** Constructor.
998
999 Copy constructor.
1000 */
1001 template<std::size_t M>
1002 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const basic_static_string<M,CharT,Traits> & other)1003 basic_static_string(
1004 const basic_static_string<M, CharT, Traits>& other)
1005 {
1006 assign(other);
1007 }
1008
1009 /** Constructor.
1010
1011 Construct from an initializer list
1012 */
1013 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(std::initializer_list<value_type> init)1014 basic_static_string(std::initializer_list<value_type> init)
1015 {
1016 assign(init.begin(), init.size());
1017 }
1018
1019 /** Constructor.
1020
1021 Construct from a object convertible to `string_view_type`
1022 */
1023 template<typename T
1024 #ifndef BOOST_STATIC_STRING_DOCS
1025 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
1026 #endif
1027 >
1028 explicit
1029 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const T & t)1030 basic_static_string(const T& t)
1031 {
1032 assign(t);
1033 }
1034
1035 /** Constructor.
1036
1037 Construct from any object convertible to `string_view_type`.
1038
1039 The range (pos, n) is extracted from the value
1040 obtained by converting `t` to `string_view_type`,
1041 and used to construct the string.
1042 */
1043 template<typename T
1044 #ifndef BOOST_STATIC_STRING_DOCS
1045 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
1046 #endif
1047 >
1048 BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const T & t,size_type pos,size_type n)1049 basic_static_string(
1050 const T& t,
1051 size_type pos,
1052 size_type n)
1053 {
1054 assign(t, pos, n);
1055 }
1056
1057 //--------------------------------------------------------------------------
1058 //
1059 // Assignment
1060 //
1061 //--------------------------------------------------------------------------
1062
1063 /** Assign to the string.
1064
1065 Replaces the contents with those of
1066 the string `s`.
1067
1068 @par Complexity
1069
1070 Linear in `s.size()`.
1071
1072 @par Exception Safety
1073
1074 Strong guarantee.
1075
1076 @tparam M The size of the other string.
1077
1078 @return `*this`
1079
1080 @param s The string to replace
1081 the contents with.
1082
1083 @throw std::length_error `s.size() > max_size()`.
1084 */
1085 template<std::size_t M>
1086 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1087 basic_static_string&
operator =(const basic_static_string<M,CharT,Traits> & s)1088 operator=(const basic_static_string<M, CharT, Traits>& s)
1089 {
1090 return assign(s);
1091 }
1092
1093 /** Assign to the string.
1094
1095 Replaces the contents with those of
1096 `{s, s + traits_type::length(s))`.
1097
1098 @par Complexity
1099
1100 Linear in `count`.
1101
1102 @par Exception Safety
1103
1104 Strong guarantee.
1105
1106 @return `*this`
1107
1108 @param s A pointer to the string to copy from.
1109
1110 @throw std::length_error `traits_type::length(s) > max_size()`.
1111 */
1112 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1113 basic_static_string&
operator =(const_pointer s)1114 operator=(const_pointer s)
1115 {
1116 return assign(s);
1117 }
1118
1119 /** Assign to the string.
1120
1121 Replaces the contents with a single copy of
1122 the character `ch`.
1123
1124 @par Complexity
1125
1126 Constant.
1127
1128 @par Exception Safety
1129
1130 Strong guarantee.
1131
1132 @return `*this`
1133
1134 @param ch The character to assign to.
1135
1136 @throw std::length_error `count > max_size()`.
1137 */
1138 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1139 basic_static_string&
operator =(value_type ch)1140 operator=(value_type ch)
1141 {
1142 return assign_char(ch,
1143 std::integral_constant<bool, (N > 0)>{});
1144 }
1145
1146 /** Assign to the string.
1147
1148 Replaces the contents with those of the
1149 initializer list `ilist`.
1150
1151 @par Complexity
1152
1153 Linear in `init.size()`.
1154
1155 @par Exception Safety
1156
1157 Strong guarantee.
1158
1159 @return `*this`
1160
1161 @param ilist The initializer list to copy from.
1162
1163 @throw std::length_error `ilist.size() > max_size()`.
1164 */
1165 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1166 basic_static_string&
operator =(std::initializer_list<value_type> ilist)1167 operator=(std::initializer_list<value_type> ilist)
1168 {
1169 return assign(ilist);
1170 }
1171
1172 /** Assign to the string.
1173
1174 Replaces the contents with those of
1175 `sv`, where `sv` is `string_view_type(t)`.
1176
1177 @par Complexity
1178
1179 Linear in `sv.size()`.
1180
1181 @par Exception Safety
1182
1183 Strong guarantee.
1184
1185 @note
1186
1187 The view can contain null characters.
1188
1189 @tparam T A type convertible to `string_view_type`.
1190
1191 @par Constraints
1192
1193 @code
1194 std::is_convertible<const T&, string_view>::value &&
1195 !std::is_convertible<const T&, const CharT*>::value
1196 @endcode
1197
1198 @return `*this`
1199
1200 @param t The object to assign from.
1201
1202 @throw std::length_error `sv.size() > max_size()`.
1203 */
1204 template<typename T
1205 #ifndef BOOST_STATIC_STRING_DOCS
1206 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
1207 #endif
1208 >
1209 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1210 basic_static_string&
operator =(const T & t)1211 operator=(const T& t)
1212 {
1213 return assign(t);
1214 }
1215
1216 /** Assign to the string.
1217
1218 Replaces the contents with `count` copies of
1219 character `ch`.
1220
1221 @par Complexity
1222
1223 Linear in `count`.
1224
1225 @par Exception Safety
1226
1227 Strong guarantee.
1228
1229 @return `*this`
1230
1231 @param count The size of the resulting string.
1232
1233 @param ch The value to initialize characters
1234 of the string with.
1235
1236 @throw std::length_error `count > max_size()`.
1237 */
1238 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1239 basic_static_string&
1240 assign(
1241 size_type count,
1242 value_type ch);
1243
1244 /** Assign to the string.
1245
1246 Replaces the contents with those of
1247 the string `s`.
1248
1249 @par Complexity
1250
1251 Linear in `s.size()`.
1252
1253 @par Exception Safety
1254
1255 Strong guarantee.
1256
1257 @tparam M The size of the other string.
1258
1259 @return `*this`
1260
1261 @param s The string to replace
1262 the contents with.
1263
1264 @throw std::length_error `s.size() > max_size()`.
1265 */
1266 template<std::size_t M
1267 #ifndef BOOST_STATIC_STRING_DOCS
1268 , typename std::enable_if<(M < N)>::type* = nullptr
1269 #endif
1270 >
1271 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1272 basic_static_string&
assign(const basic_static_string<M,CharT,Traits> & s)1273 assign(const basic_static_string<M, CharT, Traits>& s)
1274 {
1275 return assign_unchecked(s.data(), s.size());
1276 }
1277
1278 #ifndef BOOST_STATIC_STRING_DOCS
1279 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1280 basic_static_string&
assign(const basic_static_string & s)1281 assign(const basic_static_string& s) noexcept
1282 {
1283 if (this == &s)
1284 return *this;
1285 return assign_unchecked(s.data(), s.size());
1286 }
1287
1288 template<std::size_t M,
1289 typename std::enable_if<(M > N)>::type* = nullptr>
1290 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1291 basic_static_string&
assign(const basic_static_string<M,CharT,Traits> & s)1292 assign(const basic_static_string<M, CharT, Traits>& s)
1293 {
1294 return assign(s.data(), s.size());
1295 }
1296 #endif
1297
1298 /** Assign to the string.
1299
1300 Replaces the contents with those of the string `sub`,
1301 where `sub` is `s.substr(pos, count)`.
1302
1303 @par Complexity
1304
1305 Linear in `sub.size()`.
1306
1307 @par Exception Safety
1308
1309 Strong guarantee.
1310
1311 @tparam M The capacity of the other string.
1312
1313 @return `*this`
1314
1315 @param s The string to replace
1316 the contents with.
1317
1318 @param pos The index at which to begin the substring.
1319
1320 @param count The size of the substring. The default
1321 argument for this parameter is @ref npos.
1322
1323 @throw std::length_error `sub.size() > max_size()`.
1324 */
1325 template<std::size_t M>
1326 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1327 basic_static_string&
assign(const basic_static_string<M,CharT,Traits> & s,size_type pos,size_type count=npos)1328 assign(
1329 const basic_static_string<M, CharT, Traits>& s,
1330 size_type pos,
1331 size_type count = npos)
1332 {
1333 return assign(s.data() + pos, s.capped_length(pos, count));
1334 }
1335
1336 /** Assign to the string.
1337
1338 Replaces the contents with those of `{s, s + count)`.
1339
1340 @par Complexity
1341
1342 Linear in `count`.
1343
1344 @par Exception Safety
1345
1346 Strong guarantee.
1347
1348 @note
1349
1350 The range can contain null characters.
1351
1352 @return `*this`
1353
1354 @param count The number of characters to copy.
1355
1356 @param s A pointer to the string to copy from.
1357
1358 @throw std::length_error `count > max_size()`.
1359 */
1360 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1361 basic_static_string&
1362 assign(
1363 const_pointer s,
1364 size_type count);
1365
1366 /** Assign to the string.
1367
1368 Replaces the contents with those of
1369 `{s, s + traits_type::length(s))`.
1370
1371 @par Complexity
1372
1373 Linear in `count`.
1374
1375 @par Exception Safety
1376
1377 Strong guarantee.
1378
1379 @return `*this`
1380
1381 @param s A pointer to the string to copy from.
1382
1383 @throw std::length_error `traits_type::length(s) > max_size()`.
1384 */
1385 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1386 basic_static_string&
assign(const_pointer s)1387 assign(const_pointer s)
1388 {
1389 return assign(s, traits_type::length(s));
1390 }
1391
1392 /** Assign to the string.
1393
1394 Replaces the contents with the characters
1395 in the range `{first, last)`.
1396
1397 @par Complexity
1398
1399 Linear in `std::distance(first, last)`.
1400
1401 @par Exception Safety
1402
1403 Strong guarantee.
1404
1405 @tparam InputIterator The type of the iterators.
1406
1407 @par Constraints
1408
1409 `InputIterator` satisfies __InputIterator__.
1410
1411 @return `*this`
1412
1413 @param first An iterator referring to the
1414 first character to assign.
1415
1416 @param last An iterator past the end
1417 of the range to assign from.
1418
1419 @throw std::length_error `std::distance(first, last) > max_size()`.
1420 */
1421 template<typename InputIterator>
1422 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1423 #ifdef BOOST_STATIC_STRING_DOCS
1424 basic_static_string&
1425 #else
1426 typename std::enable_if<
1427 detail::is_input_iterator<InputIterator>::value,
1428 basic_static_string&>::type
1429 #endif
1430 assign(
1431 InputIterator first,
1432 InputIterator last);
1433
1434 /** Assign to the string.
1435
1436 Replaces the contents with those of the
1437 initializer list `ilist`.
1438
1439 @par Complexity
1440
1441 Linear in `init.size()`.
1442
1443 @par Exception Safety
1444
1445 Strong guarantee.
1446
1447 @return `*this`
1448
1449 @param ilist The initializer list to copy from.
1450
1451 @throw std::length_error `ilist.size() > max_size()`.
1452 */
1453 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1454 basic_static_string&
assign(std::initializer_list<value_type> ilist)1455 assign(
1456 std::initializer_list<value_type> ilist)
1457 {
1458 return assign(ilist.begin(), ilist.end());
1459 }
1460
1461 /** Assign to the string.
1462
1463 Replaces the contents with those of
1464 `sv`, where `sv` is `string_view_type(t)`.
1465
1466 @par Complexity
1467
1468 Linear in `sv.size()`.
1469
1470 @par Exception Safety
1471
1472 Strong guarantee.
1473
1474 @note
1475
1476 The view can contain null characters.
1477
1478 @tparam T A type convertible to `string_view_type`.
1479
1480 @par Constraints
1481
1482 @code
1483 std::is_convertible<const T&, string_view>::value &&
1484 !std::is_convertible<const T&, const CharT*>::value
1485 @endcode
1486
1487 @return `*this`
1488
1489 @param t The object to assign from.
1490
1491 @throw std::length_error `sv.size() > max_size()`.
1492 */
1493 template<typename T
1494 #ifndef BOOST_STATIC_STRING_DOCS
1495 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
1496 #endif
1497 >
1498 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1499 basic_static_string&
assign(const T & t)1500 assign(const T& t)
1501 {
1502 const string_view_type sv = t;
1503 return assign(sv.data(), sv.size());
1504 }
1505
1506 /** Assign to the string.
1507
1508 Replaces the contents with those of the substring `sv`,
1509 where `sv` is `string_view_type(t).substr(pos, count)`.
1510
1511 @par Complexity
1512
1513 Linear in `sv.size()`.
1514
1515 @par Exception Safety
1516
1517 Strong guarantee.
1518
1519 @note
1520
1521 The view can contain null characters.
1522
1523 @tparam T A type convertible to `string_view_type`.
1524
1525 @par Constraints
1526
1527 @code
1528 std::is_convertible<const T&, string_view>::value &&
1529 !std::is_convertible<const T&, const CharT*>::value
1530 @endcode
1531
1532 @return `*this`
1533
1534 @param t The object to assign from.
1535
1536 @param pos The index at which to begin the substring.
1537
1538 @param count The size of the substring. The default
1539 argument for this parameter is @ref npos.
1540
1541 @throw std::length_error `sv.size() > max_size()`.
1542 */
1543 template<typename T
1544 #ifndef BOOST_STATIC_STRING_DOCS
1545 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
1546 #endif
1547 >
1548 basic_static_string&
assign(const T & t,size_type pos,size_type count=npos)1549 assign(
1550 const T& t,
1551 size_type pos,
1552 size_type count = npos)
1553 {
1554 const auto sv = string_view_type(t).substr(pos, count);
1555 return assign(sv.data(), sv.size());
1556 }
1557
1558 //--------------------------------------------------------------------------
1559 //
1560 // Element access
1561 //
1562 //--------------------------------------------------------------------------
1563
1564 /** Access a character with bounds checking.
1565
1566 Returns a reference to the character at
1567 index `pos`.
1568
1569 @par Complexity
1570
1571 Constant.
1572
1573 @par Exception Safety
1574
1575 Strong guarantee.
1576
1577 @param pos The index to access.
1578
1579 @throw std::out_of_range `pos >= size()`
1580 */
1581 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1582 reference
at(size_type pos)1583 at(size_type pos)
1584 {
1585 if (pos >= size())
1586 detail::throw_exception<std::out_of_range>(
1587 "pos >= size()");
1588 return data()[pos];
1589 }
1590
1591 /** Access a character with bounds checking.
1592
1593 Returns a reference to the character at
1594 index `pos`.
1595
1596 @par Complexity
1597
1598 Constant.
1599
1600 @par Exception Safety
1601
1602 Strong guarantee.
1603
1604 @param pos The index to access.
1605
1606 @throw std::out_of_range `pos >= size()`
1607 */
1608 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1609 const_reference
at(size_type pos) const1610 at(size_type pos) const
1611 {
1612 if (pos >= size())
1613 detail::throw_exception<std::out_of_range>(
1614 "pos >= size()");
1615 return data()[pos];
1616 }
1617
1618 /** Access a character.
1619
1620 Returns a reference to the character at
1621 index `pos`.
1622
1623 @par Complexity
1624
1625 Constant.
1626
1627 @par Precondition
1628
1629 `pos >= size`
1630
1631 @param pos The index to access.
1632 */
1633 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1634 reference
operator [](size_type pos)1635 operator[](size_type pos) noexcept
1636 {
1637 return data()[pos];
1638 }
1639
1640 /** Access a character.
1641
1642 Returns a reference to the character at
1643 index `pos`.
1644
1645 @par Complexity
1646
1647 Constant.
1648
1649 @par Precondition
1650
1651 `pos >= size`
1652
1653 @param pos The index to access.
1654 */
1655 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1656 const_reference
operator [](size_type pos) const1657 operator[](size_type pos) const noexcept
1658 {
1659 return data()[pos];
1660 }
1661
1662 /** Return the first character.
1663
1664 Returns a reference to the first character.
1665
1666 @par Complexity
1667
1668 Constant.
1669
1670 @par Precondition
1671
1672 `not empty()`
1673 */
1674 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1675 reference
front()1676 front() noexcept
1677 {
1678 return data()[0];
1679 }
1680
1681 /** Return the first character.
1682
1683 Returns a reference to the first character.
1684
1685 @par Complexity
1686
1687 Constant.
1688
1689 @par Precondition
1690
1691 `not empty()`
1692 */
1693 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1694 const_reference
front() const1695 front() const noexcept
1696 {
1697 return data()[0];
1698 }
1699
1700 /** Return the last character.
1701
1702 Returns a reference to the last character.
1703
1704 @par Complexity
1705
1706 Constant.
1707
1708 @par Precondition
1709
1710 `not empty()`
1711 */
1712 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1713 reference
back()1714 back() noexcept
1715 {
1716 return data()[size() - 1];
1717 }
1718
1719 /** Return the last character.
1720
1721 Returns a reference to the last character.
1722
1723 @par Complexity
1724
1725 Constant.
1726
1727 @par Precondition
1728
1729 `not empty()`
1730 */
1731 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1732 const_reference
back() const1733 back() const noexcept
1734 {
1735 return data()[size() - 1];
1736 }
1737
1738 /** Return a pointer to the string.
1739
1740 Returns a pointer to the underlying array
1741 serving as storage. The value returned is such that
1742 the range `{data(), data() + size())` is always a
1743 valid range, even if the container is empty.
1744
1745 @par Complexity
1746
1747 Constant.
1748
1749 @note The value returned from this function
1750 is never never a null pointer value.
1751 */
1752 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1753 pointer
data()1754 data() noexcept
1755 {
1756 return this->data_impl();
1757 }
1758
1759 /** Return a pointer to the string.
1760
1761 Returns a pointer to the underlying array
1762 serving as storage. The value returned is such that
1763 the range `{data(), data() + size())` is always a
1764 valid range, even if the container is empty.
1765
1766 @par Complexity
1767
1768 Constant.
1769
1770 @note The value returned from this function
1771 is never never a null pointer value.
1772 */
1773 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1774 const_pointer
data() const1775 data() const noexcept
1776 {
1777 return this->data_impl();
1778 }
1779
1780 /** Return a pointer to the string.
1781
1782 Returns a pointer to the underlying array
1783 serving as storage. The value returned is such that
1784 the range `{c_str(), c_str() + size())` is always a
1785 valid range, even if the container is empty.
1786
1787 @par Complexity
1788
1789 Constant.
1790
1791 @note The value returned from this function
1792 is never never a null pointer value.
1793 */
1794 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1795 const_pointer
c_str() const1796 c_str() const noexcept
1797 {
1798 return data();
1799 }
1800
1801 /** Convert to a string view referring to the string.
1802
1803 Returns a string view referring to the
1804 underlying character string.
1805
1806 @par Complexity
1807
1808 Constant.
1809 */
1810 BOOST_STATIC_STRING_CPP11_CONSTEXPR
operator string_view_type() const1811 operator string_view_type() const noexcept
1812 {
1813 return string_view_type(data(), size());
1814 }
1815
1816 //--------------------------------------------------------------------------
1817 //
1818 // Iterators
1819 //
1820 //--------------------------------------------------------------------------
1821
1822 /// Return an iterator to the beginning.
1823 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1824 iterator
begin()1825 begin() noexcept
1826 {
1827 return data();
1828 }
1829
1830 /// Return an iterator to the beginning.
1831 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1832 const_iterator
begin() const1833 begin() const noexcept
1834 {
1835 return data();
1836 }
1837
1838 /// Return an iterator to the beginning.
1839 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1840 const_iterator
cbegin() const1841 cbegin() const noexcept
1842 {
1843 return data();
1844 }
1845
1846 /// Return an iterator to the end.
1847 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1848 iterator
end()1849 end() noexcept
1850 {
1851 return data() + size();
1852 }
1853
1854 /// Return an iterator to the end.
1855 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1856 const_iterator
end() const1857 end() const noexcept
1858 {
1859 return data() + size();
1860 }
1861
1862 /// Return an iterator to the end.
1863 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1864 const_iterator
cend() const1865 cend() const noexcept
1866 {
1867 return data() + size();
1868 }
1869
1870 /// Return a reverse iterator to the beginning.
1871 BOOST_STATIC_STRING_CPP17_CONSTEXPR
1872 reverse_iterator
rbegin()1873 rbegin() noexcept
1874 {
1875 return reverse_iterator{end()};
1876 }
1877
1878 /// Return a reverse iterator to the beginning.
1879 BOOST_STATIC_STRING_CPP17_CONSTEXPR
1880 const_reverse_iterator
rbegin() const1881 rbegin() const noexcept
1882 {
1883 return const_reverse_iterator{cend()};
1884 }
1885
1886 /// Return a reverse iterator to the beginning.
1887 BOOST_STATIC_STRING_CPP17_CONSTEXPR
1888 const_reverse_iterator
crbegin() const1889 crbegin() const noexcept
1890 {
1891 return const_reverse_iterator{cend()};
1892 }
1893
1894 /// Return a reverse iterator to the end.
1895 BOOST_STATIC_STRING_CPP17_CONSTEXPR
1896 reverse_iterator
rend()1897 rend() noexcept
1898 {
1899 return reverse_iterator{begin()};
1900 }
1901
1902 /// Return a reverse iterator to the end.
1903 BOOST_STATIC_STRING_CPP17_CONSTEXPR
1904 const_reverse_iterator
rend() const1905 rend() const noexcept
1906 {
1907 return const_reverse_iterator{cbegin()};
1908 }
1909
1910 /// Return a reverse iterator to the end.
1911 BOOST_STATIC_STRING_CPP17_CONSTEXPR
1912 const_reverse_iterator
crend() const1913 crend() const noexcept
1914 {
1915 return const_reverse_iterator{cbegin()};
1916 }
1917
1918 //--------------------------------------------------------------------------
1919 //
1920 // Capacity
1921 //
1922 //--------------------------------------------------------------------------
1923
1924 /** Return if the string is empty.
1925
1926 Returns whether the string contains no characters.
1927
1928 @par Complexity
1929
1930 Constant.
1931
1932 @return `size() == 0`
1933 */
1934 BOOST_STATIC_STRING_NODISCARD
1935 BOOST_STATIC_STRING_CPP11_CONSTEXPR
1936 bool
empty() const1937 empty() const noexcept
1938 {
1939 return size() == 0;
1940 }
1941
1942 /** Return the size of the string.
1943
1944 Returns the number of characters stored in the
1945 string, excluding the null terminator.
1946
1947 @par Complexity
1948
1949 Constant.
1950 */
1951 BOOST_STATIC_STRING_CPP11_CONSTEXPR
1952 size_type
size() const1953 size() const noexcept
1954 {
1955 return this->size_impl();
1956 }
1957
1958 /** Return the size of the string.
1959
1960 Returns the number of characters stored in the
1961 string, excluding the null terminator.
1962
1963 @par Complexity
1964
1965 Constant.
1966 */
1967 BOOST_STATIC_STRING_CPP11_CONSTEXPR
1968 size_type
length() const1969 length() const noexcept
1970 {
1971 return size();
1972 }
1973
1974 /** Return the number of characters that can be stored.
1975
1976 Returns the maximum size of the string, excluding the
1977 null terminator. The returned value is always `N`.
1978
1979 @par Complexity
1980
1981 Constant.
1982 */
1983 BOOST_STATIC_STRING_CPP11_CONSTEXPR
1984 size_type
max_size() const1985 max_size() const noexcept
1986 {
1987 return N;
1988 }
1989
1990 /** Increase the capacity.
1991
1992 This function has no effect.
1993
1994 @throw std::length_error `n > max_size()`
1995 */
1996 BOOST_STATIC_STRING_CPP14_CONSTEXPR
1997 void
reserve(size_type n)1998 reserve(size_type n)
1999 {
2000 if (n > max_size())
2001 detail::throw_exception<std::length_error>(
2002 "n > max_size()");
2003 }
2004
2005 /** Return the number of characters that can be stored.
2006
2007 Returns the maximum size of the string, excluding the
2008 null terminator. The returned value is always `N`.
2009
2010 @par Complexity
2011
2012 Constant.
2013 */
2014 BOOST_STATIC_STRING_CPP11_CONSTEXPR
2015 size_type
capacity() const2016 capacity() const noexcept
2017 {
2018 return max_size();
2019 }
2020
2021 /** Request the removal of unused capacity.
2022
2023 This function has no effect.
2024 */
2025 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2026 void
shrink_to_fit()2027 shrink_to_fit() noexcept { }
2028
2029 //--------------------------------------------------------------------------
2030 //
2031 // Operations
2032 //
2033 //--------------------------------------------------------------------------
2034
2035 /** Clear the contents.
2036
2037 Erases all characters from the string. After this
2038 call, @ref size() returns zero.
2039
2040 @par Complexity
2041
2042 Linear in @ref size().
2043
2044 @note All references, pointers, or iterators
2045 referring to contained elements are invalidated. Any
2046 past-the-end iterators are also invalidated.
2047 */
2048 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2049 void
clear()2050 clear() noexcept
2051 {
2052 this->set_size(0);
2053 term();
2054 }
2055
2056 /** Insert into the string.
2057
2058 Inserts `count` copies of `ch` at the position `index`.
2059
2060 @par Exception Safety
2061
2062 Strong guarantee.
2063
2064 @note All references, pointers, or iterators
2065 referring to contained elements are invalidated. Any
2066 past-the-end iterators are also invalidated.
2067
2068 @return `*this`
2069
2070 @param index The index to insert at.
2071 @param count The number of characters to insert.
2072 @param ch The character to insert.
2073
2074 @throw std::length_error `size() + count > max_size()`
2075 @throw std::out_of_range `index > size()`
2076 */
2077 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2078 basic_static_string&
insert(size_type index,size_type count,value_type ch)2079 insert(
2080 size_type index,
2081 size_type count,
2082 value_type ch)
2083 {
2084 if (index > size())
2085 detail::throw_exception<std::out_of_range>(
2086 "index > size()");
2087 insert(begin() + index, count, ch);
2088 return *this;
2089 }
2090
2091 /** Insert into the string.
2092
2093 Inserts the null-terminated character string pointed to by `s`
2094 of length `count` at the position `index` where `count`
2095 is `traits_type::length(s)`.
2096
2097 @par Exception Safety
2098
2099 Strong guarantee.
2100
2101 @note All references, pointers, or iterators
2102 referring to contained elements are invalidated. Any
2103 past-the-end iterators are also invalidated.
2104
2105 @return `*this`
2106
2107 @param index The index to insert at.
2108 @param s The string to insert.
2109
2110 @throw std::length_error `size() + count > max_size()`
2111 @throw std::out_of_range `index > size()`
2112 */
2113 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2114 basic_static_string&
insert(size_type index,const_pointer s)2115 insert(
2116 size_type index,
2117 const_pointer s)
2118 {
2119 return insert(index, s, traits_type::length(s));
2120 }
2121
2122 /** Insert into the string.
2123
2124 Inserts `count` characters of the string pointed to by `s`
2125 at the position `index`.
2126
2127 @par Exception Safety
2128
2129 Strong guarantee.
2130
2131 @note All references, pointers, or iterators
2132 referring to contained elements are invalidated. Any
2133 past-the-end iterators are also invalidated.
2134
2135 @return `*this`
2136
2137 @param index The index to insert at.
2138 @param s The string to insert.
2139 @param count The length of the string to insert.
2140
2141 @throw std::length_error `size() + count > max_size()`
2142 @throw std::out_of_range `index > size()`
2143 */
2144 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2145 basic_static_string&
insert(size_type index,const_pointer s,size_type count)2146 insert(
2147 size_type index,
2148 const_pointer s,
2149 size_type count)
2150 {
2151 if (index > size())
2152 detail::throw_exception<std::out_of_range>(
2153 "index > size()");
2154 insert(data() + index, s, s + count);
2155 return *this;
2156 }
2157
2158 /** Insert into the string.
2159
2160 Inserts the string `str`
2161 at the position `index`.
2162
2163 @par Exception Safety
2164
2165 Strong guarantee.
2166
2167 @note The insertion is done unchecked when
2168 the capacity of `str` differs from that of the
2169 string the function is called on.
2170
2171 @note All references, pointers, or iterators
2172 referring to contained elements are invalidated. Any
2173 past-the-end iterators are also invalidated.
2174
2175 @tparam M The size of the input string.
2176
2177 @return `*this`
2178
2179 @param index The index to insert at.
2180 @param str The string to insert.
2181
2182 @throw std::length_error `size() + str.size() > max_size()`
2183 @throw std::out_of_range `index > size()`
2184 */
2185 template<std::size_t M>
2186 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2187 basic_static_string&
insert(size_type index,const basic_static_string<M,CharT,Traits> & str)2188 insert(
2189 size_type index,
2190 const basic_static_string<M, CharT, Traits>& str)
2191 {
2192 return insert_unchecked(index, str.data(), str.size());
2193 }
2194
2195 #ifndef BOOST_STATIC_STRING_DOCS
2196 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2197 basic_static_string&
insert(size_type index,const basic_static_string & str)2198 insert(
2199 size_type index,
2200 const basic_static_string& str)
2201 {
2202 return insert(index, str.data(), str.size());
2203 }
2204 #endif
2205
2206 /** Insert into the string.
2207
2208 Inserts a string, obtained by `str.substr(index_str, count)`
2209 at the position `index`.
2210
2211 @par Exception Safety
2212
2213 Strong guarantee.
2214
2215 @note The insertion is done unchecked when
2216 the capacity of `str` differs from that of the
2217 string the function is called on.
2218
2219 @note All references, pointers, or iterators
2220 referring to contained elements are invalidated. Any
2221 past-the-end iterators are also invalidated.
2222
2223 @tparam M The size of the input string.
2224
2225 @return `*this`
2226
2227 @param index The index to insert at.
2228 @param str The string from which to insert.
2229 @param index_str The index in `str` to start inserting from.
2230 @param count The number of characters to insert.
2231 The default argument for this parameter is @ref npos.
2232
2233 @throw std::length_error `size() + str.substr(index_str, count).size() > max_size()`
2234 @throw std::out_of_range `index > size()`
2235 @throw std::out_of_range `index_str > str.size()`
2236 */
2237 template<std::size_t M>
2238 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2239 basic_static_string&
insert(size_type index,const basic_static_string<M,CharT,Traits> & str,size_type index_str,size_type count=npos)2240 insert(
2241 size_type index,
2242 const basic_static_string<M, CharT, Traits>& str,
2243 size_type index_str,
2244 size_type count = npos)
2245 {
2246 return insert_unchecked(index, str.data() + index_str, str.capped_length(index_str, count));
2247 }
2248
2249 #ifndef BOOST_STATIC_STRING_DOCS
2250 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2251 basic_static_string&
insert(size_type index,const basic_static_string & str,size_type index_str,size_type count=npos)2252 insert(
2253 size_type index,
2254 const basic_static_string& str,
2255 size_type index_str,
2256 size_type count = npos)
2257 {
2258 return insert(index, str.data() + index_str, str.capped_length(index_str, count));
2259 }
2260 #endif
2261
2262 /** Insert into the string.
2263
2264 Inserts the character `ch` before the character pointed by `pos`.
2265
2266 @par Precondition
2267
2268 `pos` shall be vaild within `{data(), data() + size()}`
2269
2270 @par Exception Safety
2271
2272 Strong guarantee.
2273
2274 @note All references, pointers, or iterators
2275 referring to contained elements are invalidated. Any
2276 past-the-end iterators are also invalidated.
2277
2278 @return An iterator which refers to the first inserted character
2279 or `pos` if no characters were inserted
2280
2281 @param pos The index to insert at.
2282 @param ch The character to insert.
2283
2284 @throw std::length_error `size() + 1 > max_size()`
2285 */
2286 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2287 iterator
insert(const_iterator pos,value_type ch)2288 insert(
2289 const_iterator pos,
2290 value_type ch)
2291 {
2292 return insert(pos, 1, ch);
2293 }
2294
2295 /** Insert into the string.
2296
2297 Inserts `count` copies of `ch` before the character pointed by `pos`.
2298
2299 @par Precondition
2300
2301 `pos` shall be valid within `{data(), data() + size()}`
2302
2303 @par Exception Safety
2304
2305 Strong guarantee.
2306
2307 @note All references, pointers, or iterators
2308 referring to contained elements are invalidated. Any
2309 past-the-end iterators are also invalidated.
2310
2311 @return An iterator which refers to the first inserted character
2312 or `pos` if no characters were inserted
2313
2314 @param pos The position to insert at.
2315 @param count The number of characters to insert.
2316 @param ch The character to insert.
2317
2318 @throw std::length_error `size() + count > max_size()`
2319 */
2320 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2321 iterator
2322 insert(
2323 const_iterator pos,
2324 size_type count,
2325 value_type ch);
2326
2327 /** Insert into the string.
2328
2329 Inserts characters from the range `{first, last)` before the
2330 character pointed to by `pos`.
2331
2332 @par Precondition
2333
2334 `pos` shall be valid within `{data(), data() + size()}`,
2335
2336 `{first, last)` shall be a valid range
2337
2338 @par Exception Safety
2339
2340 Strong guarantee.
2341
2342 @note All references, pointers, or iterators
2343 referring to contained elements are invalidated. Any
2344 past-the-end iterators are also invalidated.
2345
2346 @tparam InputIterator The type of the iterators.
2347
2348 @par Constraints
2349
2350 `InputIterator` satisfies __InputIterator__ and does not
2351 satisfy __ForwardIterator__.
2352
2353 @return An iterator which refers to the first inserted character
2354 or `pos` if no characters were inserted
2355
2356 @param pos The position to insert at.
2357 @param first An iterator representing the first character to insert.
2358 @param last An iterator representing one past the last character to insert.
2359
2360 @throw std::length_error `size() + insert_count > max_size()`
2361 */
2362 template<typename InputIterator>
2363 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2364 #ifdef BOOST_STATIC_STRING_DOCS
2365 iterator
2366 #else
2367 typename std::enable_if<
2368 detail::is_input_iterator<
2369 InputIterator>::value &&
2370 !detail::is_forward_iterator<
2371 InputIterator>::value, iterator>::type
2372 #endif
2373 insert(
2374 const_iterator pos,
2375 InputIterator first,
2376 InputIterator last);
2377
2378 #ifndef BOOST_STATIC_STRING_DOCS
2379 template<typename ForwardIterator>
2380 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2381 typename std::enable_if<
2382 detail::is_forward_iterator<
2383 ForwardIterator>::value,
2384 iterator>::type
2385 insert(
2386 const_iterator pos,
2387 ForwardIterator first,
2388 ForwardIterator last);
2389 #endif
2390
2391 /** Insert into the string.
2392
2393 Inserts characters from `ilist` before `pos`.
2394
2395 @par Precondition
2396
2397 `pos` shall be valid within `{data(), data() + size()}`
2398
2399 @par Exception Safety
2400
2401 Strong guarantee.
2402
2403 @note All references, pointers, or iterators
2404 referring to contained elements are invalidated. Any
2405 past-the-end iterators are also invalidated.
2406
2407 @return An iterator which refers to the first inserted character
2408 or `pos` if no characters were inserted
2409
2410 @param pos The position to insert at.
2411 @param ilist The initializer list from which to insert.
2412
2413 @throw std::length_error `size() + ilist.size() > max_size()`
2414 */
2415 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2416 iterator
insert(const_iterator pos,std::initializer_list<value_type> ilist)2417 insert(
2418 const_iterator pos,
2419 std::initializer_list<value_type> ilist)
2420 {
2421 return insert_unchecked(pos, ilist.begin(), ilist.size());
2422 }
2423
2424 /** Insert into the string.
2425
2426 Constructs a temporary `string_view_type` object `sv` from `t` and
2427 inserts `{sv.begin(), sv.end())` at `index`.
2428
2429 @par Precondition
2430
2431 `index` shall be valid within `{data(), data() + size()}`
2432
2433 @par Exception Safety
2434
2435 Strong guarantee.
2436
2437 @note All references, pointers, or iterators
2438 referring to contained elements are invalidated. Any
2439 past-the-end iterators are also invalidated.
2440
2441 @return `*this`
2442
2443 @tparam T The type of the object to convert.
2444
2445 @par Constraints
2446
2447 `std::is_convertible<const T&, string_view>::value &&
2448 !std::is_convertible<const T&, const CharT*>::value`.
2449
2450 @param index The index to insert at.
2451 @param t The string to insert from.
2452
2453 @throw std::length_error `size() + sv.size() > max_size()`
2454 @throw std::out_of_range `index > size()`
2455 */
2456 template<typename T
2457 #ifndef BOOST_STATIC_STRING_DOCS
2458 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
2459 #endif
2460 >
2461 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2462 basic_static_string&
insert(size_type index,const T & t)2463 insert(
2464 size_type index,
2465 const T& t)
2466 {
2467 const string_view_type sv = t;
2468 return insert(index, sv.data(), sv.size());
2469 }
2470
2471 /** Insert into the string.
2472
2473 Constructs a temporary `string_view_type` object `sv` from `t`
2474 and inserts `sv.substr(index_str, count)` at `index`.
2475
2476 @par Exception Safety
2477
2478 Strong guarantee.
2479
2480 @note All references, pointers, or iterators
2481 referring to contained elements are invalidated. Any
2482 past-the-end iterators are also invalidated.
2483
2484 @tparam T The type of the object to convert.
2485
2486 @par Constraints
2487
2488 `std::is_convertible<const T&, string_view>::value &&
2489 !std::is_convertible<const T&, const_pointer>::value`.
2490
2491 @return `*this`
2492
2493 @param index The index to insert at.
2494 @param t The string to insert from.
2495 @param index_str The index in the temporary `string_view_type` object
2496 to start the substring from.
2497 @param count The number of characters to insert.
2498
2499 @throw std::length_error `size() + sv.size() > max_size()`
2500 @throw std::out_of_range `index > size()`
2501 @throw std::out_of_range `index_str > sv.size()`
2502 */
2503 template<typename T
2504 #ifndef BOOST_STATIC_STRING_DOCS
2505 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
2506 #endif
2507 >
2508 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2509 basic_static_string&
insert(size_type index,const T & t,size_type index_str,size_type count=npos)2510 insert(
2511 size_type index,
2512 const T& t,
2513 size_type index_str,
2514 size_type count = npos)
2515 {
2516 const auto sv = string_view_type(t).substr(index_str, count);
2517 return insert(index, sv.data(), sv.size());
2518 }
2519
2520 /** Erase from the string.
2521
2522 Erases `num` characters from the string, starting at `index`.
2523 `num` is determined as the smaller of `count` and `size() - index`.
2524
2525 @par Exception Safety
2526
2527 Strong guarantee.
2528
2529 @note All references, pointers, or iterators
2530 referring to contained elements are invalidated. Any
2531 past-the-end iterators are also invalidated.
2532
2533 @return `*this`
2534
2535 @param index The index to erase at.
2536 The default argument for this parameter is `0`.
2537
2538 @param count The number of characters to erase.
2539 The default argument for this parameter is @ref npos.
2540
2541 @throw std::out_of_range `index > size()`
2542 */
2543 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2544 basic_static_string&
erase(size_type index=0,size_type count=npos)2545 erase(
2546 size_type index = 0,
2547 size_type count = npos)
2548 {
2549 erase(data() + index, data() + index + capped_length(index, count));
2550 return *this;
2551 }
2552
2553 /** Erase from the string.
2554
2555 Erases the character at `pos`.
2556
2557 @par Preconditions
2558
2559 `pos` shall be valid within `{data(), data() + size()}`
2560
2561 @par Exception Safety
2562
2563 Strong guarantee.
2564
2565 @note All references, pointers, or iterators
2566 referring to contained elements are invalidated. Any
2567 past-the-end iterators are also invalidated.
2568
2569 @return An iterator referring to character immediately following
2570 the erased character, or @ref end() if one does not exist.
2571
2572 @param pos An iterator referring to the character to erase.
2573 */
2574 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2575 iterator
erase(const_iterator pos)2576 erase(const_iterator pos)
2577 {
2578 BOOST_STATIC_STRING_ASSERT(!empty());
2579 return erase(pos, pos + 1);
2580 }
2581
2582 /** Erase from the string.
2583
2584 Erases the characters in the range `{first, last)`.
2585
2586 @par Precondition
2587
2588 `{first, last}` shall be valid within `{data(), data() + size()}`
2589
2590 @par Exception Safety
2591
2592 Strong guarantee.
2593
2594 @note All references, pointers, or iterators
2595 referring to contained elements are invalidated. Any
2596 past-the-end iterators are also invalidated.
2597
2598 @return An iterator referring to the character `last`
2599 previously referred to, or @ref end() if one does not exist.
2600
2601 @param first An iterator referring to the first character to erase.
2602
2603 @param last An iterator past the last character to erase.
2604 */
2605 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2606 iterator
2607 erase(
2608 const_iterator first,
2609 const_iterator last);
2610
2611 /** Append a character.
2612
2613 Appends a character to the end of the string.
2614
2615 @par Exception Safety
2616
2617 Strong guarantee.
2618
2619 @param ch The character to append.
2620
2621 @throw std::length_error `size() >= max_size()`
2622 */
2623 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2624 void
2625 push_back(value_type ch);
2626
2627 /** Remove the last character.
2628
2629 Removes a character from the end of the string.
2630
2631 @par Precondition
2632
2633 `not empty()`
2634 */
2635 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2636 void
pop_back()2637 pop_back() noexcept
2638 {
2639 BOOST_STATIC_STRING_ASSERT(!empty());
2640 this->set_size(size() - 1);
2641 term();
2642 }
2643
2644 /** Append to the string.
2645
2646 Appends `count` copies of `ch` to the end of the string.
2647
2648 @par Exception Safety
2649
2650 Strong guarantee.
2651
2652 @return `*this`
2653
2654 @param count The number of characters to append.
2655
2656 @param ch The character to append.
2657
2658 @throw std::length_error `size() + count > max_size()`
2659 */
2660 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2661 basic_static_string&
2662 append(
2663 size_type count,
2664 value_type ch);
2665
2666 /** Append to the string.
2667
2668 Appends `s` to the end of the string.
2669
2670 @par Exception Safety
2671
2672 Strong guarantee.
2673
2674 @tparam M The size of the string to append.
2675
2676 @return `*this`
2677
2678 @param s The string to append.
2679
2680 @throw std::length_error `size() + s.size() > max_size()`
2681 */
2682 template<std::size_t M>
2683 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2684 basic_static_string&
append(const basic_static_string<M,CharT,Traits> & s)2685 append(
2686 const basic_static_string<M, CharT, Traits>& s)
2687 {
2688 return append(s.data(), s.size());
2689 }
2690
2691 /** Append to the string.
2692
2693 Appends the substring `sub` to the end of the string,
2694 where `sub` is `s.substr(pos, count)`.
2695
2696 @par Exception Safety
2697
2698 Strong guarantee.
2699
2700 @tparam M The size of the string to append.
2701
2702 @return `*this`
2703
2704 @param s The string to append.
2705
2706 @param pos The index at which to begin the substring.
2707
2708 @param count The size of the substring. The default
2709 argument for this parameter is @ref npos.
2710
2711 @throw std::length_error `size() + sub.size() > max_size()`
2712 @throw std::out_of_range `pos > s.size()`
2713 */
2714 template<std::size_t M>
2715 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2716 basic_static_string&
append(const basic_static_string<M,CharT,Traits> & s,size_type pos,size_type count=npos)2717 append(
2718 const basic_static_string<M, CharT, Traits>& s,
2719 size_type pos,
2720 size_type count = npos)
2721 {
2722 return append(s.data() + pos, s.capped_length(pos, count));
2723 }
2724
2725 /** Append to the string.
2726
2727 Appends `count` characters from the string pointed
2728 to by `s` to the end of the string.
2729
2730 @par Exception Safety
2731
2732 Strong guarantee.
2733
2734 @note The string can contain null characters.
2735
2736 @return `*this`
2737
2738 @param s The string to append.
2739
2740 @param count The number of characters to append.
2741
2742 @throw std::length_error `size() + count > max_size()`
2743 */
2744 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2745 basic_static_string&
2746 append(
2747 const_pointer s,
2748 size_type count);
2749
2750 /** Append to the string.
2751
2752 Appends `count` characters from the string pointed
2753 to by `s` to the end of the string, where `count`
2754 is `traits_type::length(s)`.
2755
2756 @par Exception Safety
2757
2758 Strong guarantee.
2759
2760 @return `*this`
2761
2762 @param s The string to append.
2763
2764 @throw std::length_error `size() + count > max_size()`
2765 */
2766 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2767 basic_static_string&
append(const_pointer s)2768 append(const_pointer s)
2769 {
2770 return append(s, traits_type::length(s));
2771 }
2772
2773 // KRYSTIAN TODO: change exception safety
2774 /** Append to the string.
2775
2776 Appends characters from the range `{first, last)`
2777 to the end of the string.
2778
2779 @par Precondition
2780
2781 `{first, last)` shall be a valid range
2782
2783 @par Exception Safety
2784
2785 Strong guarantee.
2786
2787 @tparam InputIterator The type of the iterators.
2788
2789 @par Constraints
2790
2791 `InputIterator` satisfies __InputIterator__.
2792
2793 @return `*this`
2794
2795 @param first An iterator referring to the
2796 first character to append.
2797
2798 @param last An iterator past the end of
2799 last character to append.
2800
2801 @throw std::length_error `size() + std::distance(first, last) > max_size()`
2802 */
2803 template<typename InputIterator>
2804 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2805 #ifdef BOOST_STATIC_STRING_DOCS
2806 basic_static_string&
2807 #else
2808 typename std::enable_if<
2809 detail::is_input_iterator<InputIterator>::value,
2810 basic_static_string&>::type
2811 #endif
append(InputIterator first,InputIterator last)2812 append(
2813 InputIterator first,
2814 InputIterator last)
2815 {
2816 this->set_size(size() + read_back(true, first, last));
2817 return term();
2818 }
2819
2820 /** Append to the string.
2821
2822 Appends the characters from `ilist` to the
2823 end of the string.
2824
2825 @par Exception Safety
2826
2827 Strong guarantee.
2828
2829 @return `*this`
2830
2831 @param ilist The initializer list to append.
2832
2833 @throw std::length_error `size() + ilist.size() > max_size()`
2834 */
2835 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2836 basic_static_string&
append(std::initializer_list<value_type> ilist)2837 append(
2838 std::initializer_list<value_type> ilist)
2839 {
2840 return append(ilist.begin(), ilist.size());
2841 }
2842
2843 /** Append to the string.
2844
2845 Appends `sv` to the end of the string,
2846 where `sv` is `string_view_type(t)`.
2847
2848 @par Exception Safety
2849
2850 Strong guarantee.
2851
2852 @tparam T The type of the object to convert.
2853
2854 @par Constraints
2855
2856 @code
2857 std::is_convertible<T const&, string_view>::value &&
2858 !std::is_convertible<T const&, char const*>::value
2859 @endcode
2860
2861 @return `*this`
2862
2863 @param t The string to append.
2864
2865 @throw std::length_error `size() + sv.size() > max_size()`
2866 */
2867 template<typename T
2868 #ifndef BOOST_STATIC_STRING_DOCS
2869 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
2870 #endif
2871 >
2872 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2873 basic_static_string&
append(const T & t)2874 append(const T& t)
2875 {
2876 const string_view_type sv = t;
2877 return append(sv.data(), sv.size());
2878 }
2879
2880 /** Append to the string.
2881
2882 Appends the substring `sv` to the end of the string,
2883 where `sv` is `string_view_type(t).substr(pos, count)`.
2884
2885 @par Exception Safety
2886
2887 Strong guarantee.
2888
2889 @tparam T The type of the object to convert.
2890
2891 @par Constraints
2892
2893 @code
2894 std::is_convertible<T const&, string_view>::value &&
2895 !std::is_convertible<T const&, char const*>::value
2896 @endcode
2897
2898 @return `*this`
2899
2900 @param t The object to append.
2901
2902 @param pos The index at which to begin the substring.
2903
2904 @param count The size of the substring. The default
2905 argument for this parameter is @ref npos.
2906
2907 @throw std::length_error `size() + sv.size() > max_size()`
2908 */
2909 template<typename T
2910 #ifndef BOOST_STATIC_STRING_DOCS
2911 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
2912 #endif
2913 >
2914 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2915 basic_static_string&
append(const T & t,size_type pos,size_type count=npos)2916 append(
2917 const T& t,
2918 size_type pos,
2919 size_type count = npos)
2920 {
2921 const auto sv = string_view_type(t).substr(pos, count);
2922 return append(sv.data(), sv.size());
2923 }
2924
2925 /** Append to the string.
2926
2927 Appends `s` to the end of the string.
2928
2929 @par Exception Safety
2930
2931 Strong guarantee.
2932
2933 @tparam M The size of the string to append.
2934
2935 @return `*this`
2936
2937 @param s The string to append.
2938
2939 @throw std::length_error `size() + s.size() > max_size()`
2940 */
2941 template<std::size_t M>
2942 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2943 basic_static_string&
operator +=(const basic_static_string<M,CharT,Traits> & s)2944 operator+=(
2945 const basic_static_string<M, CharT, Traits>& s)
2946 {
2947 return append(s);
2948 }
2949
2950 /** Append to the string.
2951
2952 Appends a character to the end of the string.
2953
2954 @par Exception Safety
2955
2956 Strong guarantee.
2957
2958 @param ch The character to append.
2959
2960 @throw std::length_error `size() >= max_size()`
2961 */
2962 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2963 basic_static_string&
operator +=(value_type ch)2964 operator+=(value_type ch)
2965 {
2966 push_back(ch);
2967 return *this;
2968 }
2969
2970 /** Append to the string.
2971
2972 Appends `count` characters from the string pointed
2973 to by `s` to the end of the string, where `count`
2974 is `traits_type::length(s)`.
2975
2976 @par Exception Safety
2977
2978 Strong guarantee.
2979
2980 @return `*this`
2981
2982 @param s The string to append.
2983
2984 @throw std::length_error `size() + count > max_size()`
2985 */
2986 BOOST_STATIC_STRING_CPP14_CONSTEXPR
2987 basic_static_string&
operator +=(const_pointer s)2988 operator+=(const_pointer s)
2989 {
2990 return append(s);
2991 }
2992
2993 /** Append to the string.
2994
2995 Appends the characters from `ilist` to the
2996 end of the string.
2997
2998 @par Exception Safety
2999
3000 Strong guarantee.
3001
3002 @return `*this`
3003
3004 @param ilist The initializer list to append.
3005
3006 @throw std::length_error `size() + ilist.size() > max_size()`
3007 */
3008 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3009 basic_static_string&
operator +=(std::initializer_list<value_type> ilist)3010 operator+=(
3011 std::initializer_list<value_type> ilist)
3012 {
3013 return append(ilist);
3014 }
3015
3016 /** Append to the string.
3017
3018 Appends `sv` to the end of the string,
3019 where `sv` is `string_view_type(t)`.
3020
3021 @par Exception Safety
3022
3023 Strong guarantee.
3024
3025 @tparam T The type of the object to convert.
3026
3027 @par Constraints
3028
3029 @code
3030 std::is_convertible<T const&, string_view>::value &&
3031 !std::is_convertible<T const&, char const*>::value
3032 @endcode
3033
3034 @return `*this`
3035
3036 @param t The string to append.
3037
3038 @throw std::length_error `size() + sv.size() > max_size()`
3039 */
3040 template<typename T
3041 #ifndef BOOST_STATIC_STRING_DOCS
3042 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
3043 #endif
3044 >
3045 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3046 basic_static_string&
operator +=(const T & t)3047 operator+=(const T& t)
3048 {
3049 return append(t);
3050 }
3051
3052 /** Compare a string with the string.
3053
3054 Let `comp` be `traits_type::compare(data(), s.data(), std::min(size(), s.size())`.
3055 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3056 `0` if `size() == s.size()`, `-1` if `size() < s.size()`, and `1`
3057 otherwise.
3058
3059 @par Complexity
3060 Linear.
3061
3062 @return The result of lexicographically comparing `s` and the string.
3063
3064 @tparam M The size of the string to compare with.
3065
3066 @param s The string to compare.
3067 */
3068 template<std::size_t M>
3069 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3070 int
compare(const basic_static_string<M,CharT,Traits> & s) const3071 compare(
3072 const basic_static_string<M, CharT, Traits>& s) const noexcept
3073 {
3074 return detail::lexicographical_compare<CharT, Traits>(
3075 data(), size(), s.data(), s.size());
3076 }
3077
3078 /** Compare a string with the string.
3079
3080 Let `sub` be `substr(pos1, count1)` and `comp` be
3081 `traits_type::compare(sub.data(), s.data(), std::min(sub.size(), s.size())`.
3082 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3083 `0` if `sub.size() == s.size()`, `-1` if `sub.size() < s.size()`, and `1`
3084 otherwise.
3085
3086 @par Complexity
3087
3088 Linear.
3089
3090 @par Exception Safety
3091
3092 Strong guarantee.
3093
3094 @return The result of lexicographically comparing `sub` and `s`.
3095
3096 @tparam M The size of the string to compare with.
3097
3098 @param pos1 The index at which to begin the substring.
3099
3100 @param count1 The size of the substring.
3101
3102 @param s The string to compare.
3103
3104 @throw std::out_of_range `pos1 > size()`
3105 */
3106 template<std::size_t M>
3107 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3108 int
compare(size_type pos1,size_type count1,const basic_static_string<M,CharT,Traits> & s) const3109 compare(
3110 size_type pos1,
3111 size_type count1,
3112 const basic_static_string<M, CharT, Traits>& s) const
3113 {
3114 return detail::lexicographical_compare<CharT, Traits>(
3115 data() + pos1, capped_length(pos1, count1), s.data(), s.size());
3116 }
3117
3118 /** Compare a string with the string.
3119
3120 Let `sub1` be `substr(pos1, count1)`, `sub2` be
3121 `s.substr(pos2, count2)`, and `comp` be
3122 `traits_type::compare(sub1.data(), sub2.data(), std::min(sub1.size(), sub2.size())`.
3123 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3124 `0` if `sub1.size() == sub2.size()`, `-1` if `sub1.size() < sub2.size()`, and `1`
3125 otherwise.
3126
3127 @par Complexity
3128
3129 Linear.
3130
3131 @par Exception Safety
3132
3133 Strong guarantee.
3134
3135 @return The result of lexicographically comparing `sub1` and `sub2`.
3136
3137 @param pos1 The index at which to begin the substring.
3138
3139 @param count1 The size of the substring.
3140
3141 @param s The string to compare.
3142
3143 @param pos2 The index at which to begin the substring to compare.
3144
3145 @param count2 The size of the substring to compare.
3146
3147 @throw std::out_of_range `pos1 > size()`
3148
3149 @throw std::out_of_range `pos2 > s.size()`
3150 */
3151 template<std::size_t M>
3152 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3153 int
compare(size_type pos1,size_type count1,const basic_static_string<M,CharT,Traits> & s,size_type pos2,size_type count2=npos) const3154 compare(
3155 size_type pos1,
3156 size_type count1,
3157 const basic_static_string<M, CharT, Traits>& s,
3158 size_type pos2,
3159 size_type count2 = npos) const
3160 {
3161 return detail::lexicographical_compare<CharT, Traits>(
3162 data() + pos1, capped_length(pos1, count1),
3163 s.data() + pos2, s.capped_length(pos2, count2));
3164 }
3165
3166 /** Compare a string with the string.
3167
3168 Let `len` be `traits_type::length(s)` and `comp` be
3169 `traits_type::compare(data(), s, std::min(size(), len)`.
3170 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3171 `0` if `size() == len`, `-1` if `size() < len`, and `1`
3172 otherwise.
3173
3174 @par Complexity
3175
3176 Linear.
3177
3178 @return The result of lexicographically comparing `s` and the string.
3179
3180 @param s The string to compare.
3181 */
3182 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3183 int
compare(const_pointer s) const3184 compare(const_pointer s) const noexcept
3185 {
3186 return detail::lexicographical_compare<CharT, Traits>(
3187 data(), size(), s, traits_type::length(s));
3188 }
3189
3190 /** Compare a string with the string.
3191
3192 Let `sub` be `substr(pos1, count1)`, `len` be
3193 `traits_type::length(s)`, and `comp` be
3194 `traits_type::compare(sub.data(), s, std::min(size(), len)`.
3195 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3196 `0` if `sub.size() == len`, `-1` if `sub.size() < len`, and `1`
3197 otherwise.
3198
3199 @par Complexity
3200
3201 Linear.
3202
3203 @par Exception Safety
3204
3205 Strong guarantee.
3206
3207 @return The result of lexicographically comparing `s` and `sub`.
3208
3209 @param pos1 The index at which to begin the substring.
3210
3211 @param count1 The size of the substring.
3212
3213 @param s The string to compare.
3214
3215 @throw std::out_of_range `pos1 > size()`
3216 */
3217 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3218 int
compare(size_type pos1,size_type count1,const_pointer s) const3219 compare(
3220 size_type pos1,
3221 size_type count1,
3222 const_pointer s) const
3223 {
3224 return detail::lexicographical_compare<CharT, Traits>(
3225 data() + pos1, capped_length(pos1, count1), s, traits_type::length(s));
3226 }
3227
3228 /** Compare a string with the string.
3229
3230 Let `sub` be `substr(pos1, count1)`, and `comp` be
3231 `traits_type::compare(sub.data(), s, std::min(size(), count2)`.
3232 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3233 `0` if `sub.size() == count2`, `-1` if `sub.size() < count2`, and `1`
3234 otherwise.
3235
3236 @par Complexity
3237
3238 Linear.
3239
3240 @par Exception Safety
3241
3242 Strong guarantee.
3243
3244 @return The result of lexicographically comparing `s` and `sub`.
3245
3246 @param pos1 The index at which to begin the substring.
3247
3248 @param count1 The size of the substring.
3249
3250 @param s The string to compare.
3251
3252 @param count2 The length of the string to compare.
3253
3254 @throw std::out_of_range `pos1 > size()`
3255 */
3256 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3257 int
compare(size_type pos1,size_type count1,const_pointer s,size_type count2) const3258 compare(
3259 size_type pos1,
3260 size_type count1,
3261 const_pointer s,
3262 size_type count2) const
3263 {
3264 return detail::lexicographical_compare<CharT, Traits>(
3265 data() + pos1, capped_length(pos1, count1), s, count2);
3266 }
3267
3268 /** Compare a string with the string.
3269
3270 Let `s` be `string_view_type(t)` and `comp` be
3271 `traits_type::compare(data(), s.data(), std::min(size(), s.size())`.
3272 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3273 `0` if `size() == s.size()`, `-1` if `size() < s.size()`, and `1`
3274 otherwise.
3275
3276 @par Complexity
3277
3278 Linear.
3279
3280 @par Exception Safety
3281
3282 Strong guarantee.
3283
3284 @tparam T The type of the object to convert.
3285
3286 @par Constraints
3287
3288 @code
3289 std::is_convertible<const T&, string_view>::value &&
3290 !std::is_convertible<const T&, const_pointer>::value.
3291 @endcode
3292
3293 @return The result of lexicographically comparing `s` and the string.
3294
3295 @param t The string to compare.
3296 */
3297 template<typename T
3298 #ifndef BOOST_STATIC_STRING_DOCS
3299 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
3300 #endif
3301 >
3302 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3303 int
compare(const T & t) const3304 compare(const T& t) const noexcept
3305 {
3306 const string_view_type sv = t;
3307 return detail::lexicographical_compare<CharT, Traits>(
3308 data(), size(), sv.data(), sv.size());
3309 }
3310
3311 /** Compare a string with the string.
3312
3313 Let `s` be `string_view_type(t)`, `sub` be
3314 `substr(pos1, count1)`, and `comp` be
3315 `traits_type::compare(sub.data(), s.data(), std::min(sub.size(), s.size())`.
3316 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3317 `0` if `sub.size() == s.size()`, `-1` if `sub.size() < s.size()`, and `1`
3318 otherwise.
3319
3320 @par Complexity
3321
3322 Linear.
3323
3324 @par Exception Safety
3325
3326 Strong guarantee.
3327
3328 @tparam T The type of the object to convert.
3329
3330 @par Constraints
3331
3332 @code
3333 std::is_convertible<const T&, string_view>::value &&
3334 !std::is_convertible<const T&, const_pointer>::value.
3335 @endcode
3336
3337 @return The result of lexicographically comparing `s` and `sub`.
3338
3339 @param pos1 The index at which to begin the substring.
3340
3341 @param count1 The length of the substring.
3342
3343 @param t The string to compare.
3344 */
3345 template<typename T
3346 #ifndef BOOST_STATIC_STRING_DOCS
3347 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
3348 #endif
3349 >
3350 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3351 int
compare(size_type pos1,size_type count1,const T & t) const3352 compare(
3353 size_type pos1,
3354 size_type count1,
3355 const T& t) const
3356 {
3357 const string_view_type sv = t;
3358 return detail::lexicographical_compare<CharT, Traits>(
3359 data() + pos1, capped_length(pos1, count1), sv.data(), sv.size());
3360 }
3361
3362 /** Compare a string with the string.
3363
3364 Let `sub1` be `substr(pos1, count1)`, `sub2` be
3365 `string_view_type(t).substr(pos2, count2)`, and `comp` be
3366 `traits_type::compare(sub1.data(), sub2.data(), std::min(sub1.size(), sub2.size())`.
3367 If `comp != 0`, then the result is `comp`. Otherwise, the result is
3368 `0` if `sub1.size() == sub2.size()`, `-1` if `sub1.size() < sub2.size()`, and `1`
3369 otherwise.
3370
3371 @par Complexity
3372
3373 Linear.
3374
3375 @par Exception Safety
3376
3377 Strong guarantee.
3378
3379 @tparam T The type of the object to convert.
3380
3381 @par Constraints
3382
3383 @code
3384 std::is_convertible<const T&, string_view>::value &&
3385 !std::is_convertible<const T&, const_pointer>::value.
3386 @endcode
3387
3388 @return The result of lexicographically comparing `sub1` and `sub2`.
3389
3390 @param pos1 The index at which to begin the substring in the string.
3391
3392 @param count1 The length of the substring in the string.
3393
3394 @param t The string to compare.
3395
3396 @param pos2 The index at which to begin the substring in the string view.
3397
3398 @param count2 The length of the substring in the string view.
3399 */
3400 template<typename T
3401 #ifndef BOOST_STATIC_STRING_DOCS
3402 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
3403 #endif
3404 >
3405 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3406 int
compare(size_type pos1,size_type count1,const T & t,size_type pos2,size_type count2=npos) const3407 compare(
3408 size_type pos1,
3409 size_type count1,
3410 const T& t,
3411 size_type pos2,
3412 size_type count2 = npos) const
3413 {
3414 const auto sv = string_view_type(t).substr(pos2, count2);
3415 return compare(pos1, count1,
3416 sv.data(), sv.size());
3417 }
3418
3419 /** Return a substring.
3420
3421 Returns a substring of the string.
3422
3423 @par Exception Safety
3424
3425 Strong guarantee.
3426
3427 @return A string object containing the characters
3428 `{data() + pos, std::min(count, size() - pos))`.
3429
3430 @param pos The index to being the substring at. The
3431 default arugment for this parameter is `0`.
3432 @param count The length of the substring. The default arugment
3433 for this parameter is @ref npos.
3434
3435 @throw std::out_of_range `pos > size()`
3436 */
3437 #ifndef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
3438 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3439 #endif
3440 basic_static_string
substr(size_type pos=0,size_type count=npos) const3441 substr(
3442 size_type pos = 0,
3443 size_type count = npos) const
3444 {
3445 return basic_static_string(
3446 data() + pos, capped_length(pos, count));
3447 }
3448
3449 /** Return a string view of a substring.
3450
3451 Returns a view of a substring.
3452
3453 @par Exception Safety
3454
3455 Strong guarantee.
3456
3457 @return A `string_view_type` object referring
3458 to `{data() + pos, std::min(count, size() - pos))`.
3459
3460 @param pos The index to being the substring at. The
3461 default arugment for this parameter is `0`.
3462 @param count The length of the substring. The default arugment
3463 for this parameter is @ref npos.
3464
3465 @throw std::out_of_range `pos > size()`
3466 */
3467 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3468 string_view_type
subview(size_type pos=0,size_type count=npos) const3469 subview(
3470 size_type pos = 0,
3471 size_type count = npos) const
3472 {
3473 return string_view_type(
3474 data() + pos, capped_length(pos, count));
3475 }
3476
3477 /** Copy a substring to another string.
3478
3479 Copies `std::min(count, size() - pos)` characters starting at
3480 index `pos` to the string pointed to by `dest`.
3481
3482 @note The resulting string is not null terminated.
3483
3484 @return The number of characters copied.
3485
3486 @param count The number of characters to copy.
3487 @param dest The string to copy to.
3488 @param pos The index to begin copying from. The
3489 default argument for this parameter is `0`.
3490
3491 @throw std::out_of_range `pos > max_size()`
3492 */
3493 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3494 size_type
copy(pointer dest,size_type count,size_type pos=0) const3495 copy(
3496 pointer dest,
3497 size_type count,
3498 size_type pos = 0) const
3499 {
3500 const auto num_copied = capped_length(pos, count);
3501 traits_type::copy(dest, data() + pos, num_copied);
3502 return num_copied;
3503 }
3504
3505 /** Change the size of the string.
3506
3507 Resizes the string to contain `n` characters. If
3508 `n > size()`, characters with the value `CharT()` are
3509 appended. Otherwise, `size()` is reduced to `n`.
3510
3511 @param n The size to resize the string to.
3512
3513 @throw std::out_of_range `n > max_size()`
3514 */
3515 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3516 void
resize(size_type n)3517 resize(size_type n)
3518 {
3519 resize(n, value_type());
3520 }
3521
3522 /** Change the size of the string.
3523
3524 Resizes the string to contain `n` characters. If
3525 `n > size()`, copies of `c` are
3526 appended. Otherwise, `size()` is reduced to `n`.
3527
3528 @param n The size to resize the string to.
3529 @param c The characters to append if the size
3530 increases.
3531
3532 @throw std::out_of_range `n > max_size()`
3533 */
3534 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3535 void
3536 resize(
3537 size_type n,
3538 value_type c);
3539
3540 /** Swap two strings.
3541
3542 Swaps the contents of the string and `s`.
3543
3544 @par Exception Safety
3545
3546 Strong guarantee.
3547
3548 @note
3549
3550 All references, pointers, or iterators
3551 referring to contained elements are invalidated. Any
3552 past-the-end iterators are also invalidated.
3553
3554 @param s The string to swap with.
3555 */
3556 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3557 void
3558 swap(basic_static_string& s) noexcept;
3559
3560 /** Swap two strings.
3561
3562 Swaps the contents of the string and `s`.
3563
3564 @par Exception Safety
3565
3566 Strong guarantee.
3567
3568 @note
3569
3570 All references, pointers, or iterators
3571 referring to contained elements are invalidated. Any
3572 past-the-end iterators are also invalidated.
3573
3574 @tparam M The size of the string to swap with.
3575
3576 @param s The string to swap with.
3577
3578 @throw std::length_error `s.size() > max_size() || size() > s.max_size()`
3579 */
3580 template<std::size_t M>
3581 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3582 void
3583 swap(basic_static_string<M, CharT, Traits>& s);
3584
3585 /** Replace a part of the string.
3586
3587 Replaces `rcount` characters starting at index `pos1` with those
3588 of `str`, where `rcount` is `std::min(n1, size() - pos1)`.
3589
3590 @par Exception Safety
3591
3592 Strong guarantee.
3593
3594 @note The replacement is done unchecked when
3595 the capacity of `str` differs from that of the
3596 string the function is called on.
3597
3598 All references, pointers, or iterators
3599 referring to contained elements are invalidated. Any
3600 past-the-end iterators are also invalidated.
3601
3602 @tparam M The size of the input string.
3603
3604 @return `*this`
3605
3606 @param pos1 The index to replace at.
3607 @param n1 The number of characters to replace.
3608 @param str The string to replace with.
3609
3610 @throw std::length_error `size() + (str.size() - rcount) > max_size()`
3611 @throw std::out_of_range `pos1 > size()`
3612 */
3613 template<size_t M>
3614 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3615 basic_static_string&
replace(size_type pos1,size_type n1,const basic_static_string<M,CharT,Traits> & str)3616 replace(
3617 size_type pos1,
3618 size_type n1,
3619 const basic_static_string<M, CharT, Traits>& str)
3620 {
3621 return replace_unchecked(pos1, n1, str.data(), str.size());
3622 }
3623
3624 #ifndef BOOST_STATIC_STRING_DOCS
3625 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3626 basic_static_string&
replace(size_type pos1,size_type n1,const basic_static_string & str)3627 replace(
3628 size_type pos1,
3629 size_type n1,
3630 const basic_static_string& str)
3631 {
3632 return replace(pos1, n1, str.data(), str.size());
3633 }
3634 #endif
3635
3636 /** Replace a part of the string.
3637
3638 Replaces `rcount` characters starting at index `pos1` with those of
3639 `str.subview(pos2, n2)`, where `rcount` is `std::min(n1, size() - pos1)`.
3640
3641 @par Exception Safety
3642
3643 Strong guarantee.
3644
3645 @note The replacement is done unchecked when
3646 the capacity of `str` differs from that of the
3647 string the function is called on.
3648
3649 All references, pointers, or iterators
3650 referring to contained elements are invalidated. Any
3651 past-the-end iterators are also invalidated.
3652
3653 @return `*this`
3654
3655 @param pos1 The index to replace at.
3656 @param n1 The number of characters to replace.
3657 @param str The string to replace with.
3658 @param pos2 The index to begin the substring.
3659 @param n2 The length of the substring.
3660 The default argument for this parameter is @ref npos.
3661
3662 @throw std::length_error `size() + (std::min(str.size(), n2) - rcount) > max_size()`
3663 @throw std::out_of_range `pos1 > size()`
3664 @throw std::out_of_range `pos2 > str.size()`
3665 */
3666 template<std::size_t M>
3667 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3668 basic_static_string&
replace(size_type pos1,size_type n1,const basic_static_string<M,CharT,Traits> & str,size_type pos2,size_type n2=npos)3669 replace(
3670 size_type pos1,
3671 size_type n1,
3672 const basic_static_string<M, CharT, Traits>& str,
3673 size_type pos2,
3674 size_type n2 = npos)
3675 {
3676 return replace_unchecked(pos1, n1, str.data() + pos2, str.capped_length(pos2, n2));
3677 }
3678
3679 #ifndef BOOST_STATIC_STRING_DOCS
3680 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3681 basic_static_string&
replace(size_type pos1,size_type n1,const basic_static_string & str,size_type pos2,size_type n2=npos)3682 replace(
3683 size_type pos1,
3684 size_type n1,
3685 const basic_static_string& str,
3686 size_type pos2,
3687 size_type n2 = npos)
3688 {
3689 return replace(pos1, n1, str.data() + pos2, str.capped_length(pos2, n2));
3690 }
3691 #endif
3692
3693 /** Replace a part of the string.
3694
3695 Constructs a temporary `string_view_type` object `sv` from `t`, and
3696 replaces `rcount` characters starting at index `pos1` with those
3697 of `sv`, where `rcount` is `std::min(n1, size() - pos1)`.
3698
3699 @par Exception Safety
3700
3701 Strong guarantee.
3702
3703 @note All references, pointers, or iterators
3704 referring to contained elements are invalidated. Any
3705 past-the-end iterators are also invalidated.
3706
3707 @tparam T The type of the object to convert.
3708
3709 @par Constraints
3710
3711 `std::is_convertible<const T&, string_view>::value &&
3712 !std::is_convertible<const T&, const CharT*>::value`.
3713
3714 @return `*this`
3715
3716 @param pos1 The index to replace at.
3717 @param n1 The number of characters to replace.
3718 @param t The object to replace with.
3719
3720 @throw std::length_error `size() + (sv.size() - rcount) > max_size()`
3721 @throw std::out_of_range `pos1 > size()`
3722 */
3723 template<typename T
3724 #ifndef BOOST_STATIC_STRING_DOCS
3725 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
3726 #endif
3727 >
3728 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3729 basic_static_string&
replace(size_type pos1,size_type n1,const T & t)3730 replace(
3731 size_type pos1,
3732 size_type n1,
3733 const T& t)
3734 {
3735 const string_view_type sv = t;
3736 return replace(pos1, n1, sv.data(), sv.size());
3737 }
3738
3739 /** Replace a part of the string.
3740
3741 Constructs a temporary `string_view_type` object `sv` from `t`, and
3742 replaces `rcount` characters starting at index `pos1` with those
3743 of `sv.substr(pos2, n2)`, where `rcount` is `std::min(n1, size() - pos)`.
3744
3745 @par Exception Safety
3746
3747 Strong guarantee.
3748
3749 @note All references, pointers, or iterators
3750 referring to contained elements are invalidated. Any
3751 past-the-end iterators are also invalidated.
3752
3753 @tparam T The type of the object to convert.
3754
3755 @par Constraints
3756
3757 `std::is_convertible<const T&, string_view>::value &&
3758 !std::is_convertible<const T&, const CharT*>::value`.
3759
3760 @return `*this`
3761
3762 @param pos1 The index to replace at.
3763 @param n1 The number of characters to replace.
3764 @param t The object to replace with.
3765 @param pos2 The index to begin the substring.
3766 @param n2 The length of the substring.
3767 The default argument for this parameter is @ref npos.
3768
3769 @throw std::length_error `size() + (std::min(n2, sv.size()) - rcount) > max_size()`
3770 @throw std::out_of_range `pos1 > size()`
3771 @throw std::out_of_range `pos2 > sv.size()`
3772 */
3773 template<typename T
3774 #ifndef BOOST_STATIC_STRING_DOCS
3775 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
3776 #endif
3777 >
3778 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3779 basic_static_string&
replace(size_type pos1,size_type n1,const T & t,size_type pos2,size_type n2=npos)3780 replace(
3781 size_type pos1,
3782 size_type n1,
3783 const T& t,
3784 size_type pos2,
3785 size_type n2 = npos)
3786 {
3787 const string_view_type sv = t;
3788 return replace(pos1, n1, sv.substr(pos2, n2));
3789 }
3790
3791 /** Replace a part of the string.
3792
3793 Replaces `rcount` characters starting at index `pos` with those of
3794 `{s, s + n2)`, where `rcount` is `std::min(n1, size() - pos)`.
3795
3796 @par Exception Safety
3797
3798 Strong guarantee.
3799
3800 @note All references, pointers, or iterators
3801 referring to contained elements are invalidated. Any
3802 past-the-end iterators are also invalidated.
3803
3804 @return `*this`
3805
3806 @param pos The index to replace at.
3807 @param n1 The number of characters to replace.
3808 @param s The string to replace with.
3809 @param n2 The length of the string to replace with.
3810
3811 @throw std::length_error `size() + (n2 - rcount) > max_size()`
3812 @throw std::out_of_range `pos > size()`
3813 */
3814 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3815 basic_static_string&
replace(size_type pos,size_type n1,const_pointer s,size_type n2)3816 replace(
3817 size_type pos,
3818 size_type n1,
3819 const_pointer s,
3820 size_type n2)
3821 {
3822 return replace(data() + pos, data() + pos + capped_length(pos, n1), s, n2);
3823 }
3824
3825 /** Replace a part of the string.
3826
3827 Replaces `rcount` characters starting at index `pos` with those of
3828 `{s, s + len)`, where the length of the string `len` is `traits_type::length(s)` and `rcount`
3829 is `std::min(n1, size() - pos)`.
3830
3831 @par Exception Safety
3832
3833 Strong guarantee.
3834
3835 @note All references, pointers, or iterators
3836 referring to contained elements are invalidated. Any
3837 past-the-end iterators are also invalidated.
3838
3839 @return `*this`
3840
3841 @param pos The index to replace at.
3842 @param n1 The number of characters to replace.
3843 @param s The string to replace with.
3844
3845 @throw std::length_error `size() + (len - rcount) > max_size()`
3846 @throw std::out_of_range `pos > size()`
3847 */
3848 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3849 basic_static_string&
replace(size_type pos,size_type n1,const_pointer s)3850 replace(
3851 size_type pos,
3852 size_type n1,
3853 const_pointer s)
3854 {
3855 return replace(pos, n1, s, traits_type::length(s));
3856 }
3857
3858 /** Replace a part of the string.
3859
3860 Replaces `rcount` characters starting at index `pos` with `n2` copies
3861 of `c`, where `rcount` is `std::min(n1, size() - pos)`.
3862
3863 @par Exception Safety
3864
3865 Strong guarantee.
3866
3867 @note All references, pointers, or iterators
3868 referring to contained elements are invalidated. Any
3869 past-the-end iterators are also invalidated.
3870
3871 @return `*this`
3872
3873 @param pos The index to replace at.
3874 @param n1 The number of characters to replace.
3875 @param n2 The number of characters to replace with.
3876 @param c The character to replace with.
3877
3878 @throw std::length_error `size() + (n2 - rcount) > max_size()`
3879 @throw std::out_of_range `pos > size()`
3880 */
3881 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3882 basic_static_string&
replace(size_type pos,size_type n1,size_type n2,value_type c)3883 replace(
3884 size_type pos,
3885 size_type n1,
3886 size_type n2,
3887 value_type c)
3888 {
3889 return replace(data() + pos, data() + pos + capped_length(pos, n1), n2, c);
3890 }
3891
3892 /** Replace a part of the string.
3893
3894 Replaces the characters in the range `{i1, i2)`
3895 with those of `str`.
3896
3897 @par Precondition
3898
3899 `{i1, i2)` is a valid range.
3900
3901 @par Exception Safety
3902
3903 Strong guarantee.
3904
3905 @note The replacement is done unchecked when
3906 the capacity of `str` differs from that of the
3907 string the function is called on.
3908
3909 All references, pointers, or iterators
3910 referring to contained elements are invalidated. Any
3911 past-the-end iterators are also invalidated.
3912
3913 @tparam M The size of the input string.
3914
3915 @return `*this`
3916
3917 @param i1 An iterator referring to the first character to replace.
3918 @param i2 An iterator referring past the end of
3919 the last character to replace.
3920 @param str The string to replace with.
3921
3922 @throw std::length_error `size() + (str.size() - std::distance(i1, i2)) > max_size()`
3923 */
3924 template<std::size_t M>
3925 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3926 basic_static_string&
replace(const_iterator i1,const_iterator i2,const basic_static_string<M,CharT,Traits> & str)3927 replace(
3928 const_iterator i1,
3929 const_iterator i2,
3930 const basic_static_string<M, CharT, Traits>& str)
3931 {
3932 return replace_unchecked(i1, i2, str.data(), str.size());
3933 }
3934
3935 #ifndef BOOST_STATIC_STRING_DOCS
3936 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3937 basic_static_string&
replace(const_iterator i1,const_iterator i2,const basic_static_string & str)3938 replace(
3939 const_iterator i1,
3940 const_iterator i2,
3941 const basic_static_string& str)
3942 {
3943 return replace(i1, i2, str.data(), str.size());
3944 }
3945 #endif
3946
3947 /** Replace a part of the string.
3948
3949 Constructs a temporary `string_view_type` object `sv` from `t`, and
3950 replaces the characters in the range `{i1, i2)` with those
3951 of `sv`.
3952
3953 @par Precondition
3954
3955 `{i1, i2)` is a valid range.
3956
3957 @par Exception Safety
3958
3959 Strong guarantee.
3960
3961 @note All references, pointers, or iterators
3962 referring to contained elements are invalidated. Any
3963 past-the-end iterators are also invalidated.
3964
3965 @tparam T The type of the object to convert.
3966
3967 @par Constraints
3968
3969 `std::is_convertible<const T&, string_view>::value &&
3970 !std::is_convertible<const T&, const CharT*>::value`.
3971
3972 @return `*this`
3973
3974 @param i1 An iterator referring to the first character to replace.
3975 @param i2 An iterator referring past the end of
3976 the last character to replace.
3977 @param t The object to replace with.
3978
3979 @throw std::length_error `size() + (sv.size() - std::distance(i1, i2)) > max_size()`
3980 */
3981 template<typename T
3982 #ifndef BOOST_STATIC_STRING_DOCS
3983 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
3984 #endif
3985 >
3986 BOOST_STATIC_STRING_CPP14_CONSTEXPR
3987 basic_static_string&
replace(const_iterator i1,const_iterator i2,const T & t)3988 replace(
3989 const_iterator i1,
3990 const_iterator i2,
3991 const T& t)
3992 {
3993 const string_view_type sv = t;
3994 return replace(i1, i2, sv.begin(), sv.end());
3995 }
3996
3997 /** Replace a part of the string.
3998
3999 Replaces the characters in the range `{i1, i2)` with those of
4000 `{s, s + n)`.
4001
4002 @par Precondition
4003
4004 `{i1, i2)` is a valid range.
4005
4006 @par Exception Safety
4007
4008 Strong guarantee.
4009
4010 @note All references, pointers, or iterators
4011 referring to contained elements are invalidated. Any
4012 past-the-end iterators are also invalidated.
4013
4014 @return `*this`
4015
4016 @param i1 An iterator referring to the first character to replace.
4017 @param i2 An iterator referring past the end of
4018 the last character to replace.
4019 @param s The string to replace with.
4020 @param n The length of the string to replace with.
4021
4022 @throw std::length_error `size() + (n - std::distance(i1, i2)) > max_size()`
4023 */
4024 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4025 basic_static_string&
replace(const_iterator i1,const_iterator i2,const_pointer s,size_type n)4026 replace(
4027 const_iterator i1,
4028 const_iterator i2,
4029 const_pointer s,
4030 size_type n)
4031 {
4032 return replace(i1, i2, s, s + n);
4033 }
4034
4035 /** Replace a part of the string.
4036
4037 Replaces the characters in the range `{i1, i2)` with those of
4038 `{s, s + len)`, where the length of the string `len` is `traits_type::length(s)`.
4039
4040 @par Precondition
4041
4042 `{i1, i2)` shall be a valid range.
4043
4044 @par Exception Safety
4045
4046 Strong guarantee.
4047
4048 @note All references, pointers, or iterators
4049 referring to contained elements are invalidated. Any
4050 past-the-end iterators are also invalidated.
4051
4052 @return `*this`
4053
4054 @param i1 An iterator referring to the first character to replace.
4055 @param i2 An iterator referring past the end of
4056 the last character to replace.
4057 @param s The string to replace with.
4058
4059 @throw std::length_error `size() + (len - std::distance(i1, i2)) > max_size()`
4060 */
4061 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4062 basic_static_string&
replace(const_iterator i1,const_iterator i2,const_pointer s)4063 replace(
4064 const_iterator i1,
4065 const_iterator i2,
4066 const_pointer s)
4067 {
4068 return replace(i1, i2, s, traits_type::length(s));
4069 }
4070
4071 /** Replace a part of the string.
4072
4073 Replaces the characters in the range `{i1, i2)` with
4074 `n` copies of `c`.
4075
4076 @par Precondition
4077
4078 `{i1, i2)` is a valid range.
4079
4080 @par Exception Safety
4081
4082 Strong guarantee.
4083
4084 @note All references, pointers, or iterators
4085 referring to contained elements are invalidated. Any
4086 past-the-end iterators are also invalidated.
4087
4088 @return `*this`
4089
4090 @param i1 An iterator referring to the first character to replace.
4091 @param i2 An iterator past the end of
4092 the last character to replace.
4093 @param n The number of characters to replace with.
4094 @param c The character to replace with.
4095
4096 @throw std::length_error `size() + (n - std::distance(i1, i2)) > max_size()`
4097 */
4098 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4099 basic_static_string&
4100 replace(
4101 const_iterator i1,
4102 const_iterator i2,
4103 size_type n,
4104 value_type c);
4105
4106 /** Replace a part of the string.
4107
4108 Replaces the characters in the range `{i1, i2)`
4109 with those of `{j1, j2)`.
4110
4111 @par Precondition
4112
4113 `{i1, i2)` is a valid range.
4114
4115 `{j1, j2)` is a valid range.
4116
4117 @par Exception Safety
4118
4119 Strong guarantee.
4120
4121 @note All references, pointers, or iterators
4122 referring to contained elements are invalidated. Any
4123 past-the-end iterators are also invalidated.
4124
4125 @tparam InputIterator The type of the iterators.
4126
4127 @par Constraints
4128
4129 `InputIterator` satisfies __InputIterator__ and does not
4130 satisfy __ForwardIterator__.
4131
4132 @return `*this`
4133
4134 @param i1 An iterator referring to the first character to replace.
4135 @param i2 An iterator referring past the end of
4136 the last character to replace.
4137 @param j1 An iterator referring to the first character to replace with.
4138 @param j2 An iterator referring past the end of
4139 the last character to replace with.
4140
4141 @throw std::length_error `size() + (inserted - std::distance(i1, i2)) > max_size()`
4142 */
4143 template<typename InputIterator>
4144 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4145 #ifdef BOOST_STATIC_STRING_DOCS
4146 basic_static_string&
4147 #else
4148 typename std::enable_if<
4149 detail::is_input_iterator<
4150 InputIterator>::value &&
4151 !detail::is_forward_iterator<
4152 InputIterator>::value,
4153 basic_static_string<N, CharT, Traits>&>::type
4154 #endif
4155 replace(
4156 const_iterator i1,
4157 const_iterator i2,
4158 InputIterator j1,
4159 InputIterator j2);
4160
4161 #ifndef BOOST_STATIC_STRING_DOCS
4162 template<typename ForwardIterator>
4163 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4164 typename std::enable_if<
4165 detail::is_forward_iterator<
4166 ForwardIterator>::value,
4167 basic_static_string<N, CharT, Traits>&>::type
4168 replace(
4169 const_iterator i1,
4170 const_iterator i2,
4171 ForwardIterator j1,
4172 ForwardIterator j2);
4173 #endif
4174
4175 /** Replace a part of the string.
4176
4177 Replaces the characters in the range `{i1, i2)`
4178 with those of contained in the initializer list `il`.
4179
4180 @par Precondition
4181
4182 `{i1, i2)` is a valid range.
4183
4184 @par Exception Safety
4185
4186 Strong guarantee.
4187
4188 @note All references, pointers, or iterators
4189 referring to contained elements are invalidated. Any
4190 past-the-end iterators are also invalidated.
4191
4192 @return `*this`
4193
4194 @param i1 An iterator referring to the first character to replace.
4195 @param i2 An iterator past the end of
4196 the last character to replace.
4197 @param il The initializer list to replace with.
4198
4199 @throw std::length_error `size() + (il.size() - std::distance(i1, i2)) > max_size()`
4200 */
4201 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4202 basic_static_string&
replace(const_iterator i1,const_iterator i2,std::initializer_list<value_type> il)4203 replace(
4204 const_iterator i1,
4205 const_iterator i2,
4206 std::initializer_list<value_type> il)
4207 {
4208 return replace_unchecked(i1, i2, il.begin(), il.size());
4209 }
4210
4211 //--------------------------------------------------------------------------
4212 //
4213 // Search
4214 //
4215 //--------------------------------------------------------------------------
4216
4217 /** Find the first occurrence of a string within the string.
4218
4219 Constructs a temporary `string_view_type` object `sv` from `t`, and finds
4220 the first occurrence of `sv` within the string starting at the index `pos`.
4221
4222 @par Complexity
4223
4224 Linear.
4225
4226 @note An empty string is always found.
4227
4228 @tparam T The type of the object to convert.
4229
4230 @par Constraints
4231
4232 `std::is_convertible<const T&, string_view>::value &&
4233 !std::is_convertible<const T&, const CharT*>::value`.
4234
4235 @return The lowest index `idx` greater than or equal to `pos`
4236 where each element of `{sv.begin(), sv.end())` is equal to
4237 that of `{begin() + idx, begin() + idx + count)` if one exists,
4238 and @ref npos otherwise.
4239
4240 @param t The string to search for.
4241 @param pos The index to start searching at. The default argument
4242 for this parameter is `0`.
4243 */
4244 template<typename T
4245 #ifndef BOOST_STATIC_STRING_DOCS
4246 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
4247 #endif
4248 >
4249 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4250 size_type
find(const T & t,size_type pos=0) const4251 find(
4252 const T& t,
4253 size_type pos = 0) const
4254 noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
4255 {
4256 const string_view_type sv = t;
4257 return find(sv.data(), pos, sv.size());
4258 }
4259
4260 /** Find the first occurrence of a string within the string.
4261
4262 Finds the first occurrence of `str` within the
4263 string starting at the index `pos`.
4264
4265 @par Complexity
4266
4267 Linear.
4268
4269 @return The lowest index `idx` greater than or equal to `pos`
4270 where each element of `str` is equal to that of
4271 `{begin() + idx, begin() + idx + str.size())`
4272 if one exists, and @ref npos otherwise.
4273
4274 @param str The string to search for.
4275 @param pos The index to start searching at. The default argument for
4276 this parameter is `0`.
4277 */
4278 template<std::size_t M>
4279 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4280 size_type
find(const basic_static_string<M,CharT,Traits> & str,size_type pos=0) const4281 find(
4282 const basic_static_string<M, CharT, Traits>& str,
4283 size_type pos = 0) const noexcept
4284 {
4285 return find(str.data(), pos, str.size());
4286 }
4287
4288 /** Find the first occurrence of a string within the string.
4289
4290 Finds the first occurrence of the string pointed to
4291 by `s` within the string starting at the index `pos`.
4292
4293 @par Complexity
4294
4295 Linear.
4296
4297 @note An empty string is always found.
4298
4299 @return The lowest index `idx` greater than or equal to `pos`
4300 where each element of `{s, s + n)` is equal to that of
4301 `{begin() + idx, begin() + idx + n)` if one exists,
4302 and @ref npos otherwise.
4303
4304 @param s The string to search for.
4305 @param pos The index to start searching at.
4306 @param n The length of the string to search for.
4307 */
4308 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4309 size_type
4310 find(
4311 const_pointer s,
4312 size_type pos,
4313 size_type n) const noexcept;
4314
4315 /** Find the first occurrence of a string within the string.
4316
4317 Finds the first occurrence of the string pointed to by `s`
4318 of length `count` within the string starting at the index `pos`,
4319 where `count` is `traits_type::length(s)`.
4320
4321 @par Complexity
4322
4323 Linear.
4324
4325 @note An empty string is always found.
4326
4327 @return The lowest index `idx` greater than or equal to `pos`
4328 where each element of `{s, s + count)` is equal to that of
4329 `{begin() + idx, begin() + idx + count)` if one exists,
4330 and @ref npos otherwise.
4331
4332 @param s The string to search for.
4333 @param pos The index to start searching at. The default argument
4334 for this parameter is `0`.
4335 */
4336 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4337 size_type
find(const_pointer s,size_type pos=0) const4338 find(
4339 const_pointer s,
4340 size_type pos = 0) const noexcept
4341 {
4342 return find(s, pos, traits_type::length(s));
4343 }
4344
4345 /** Find the first occurrence of a character within the string.
4346
4347 Finds the first occurrence of `c` within the string
4348 starting at the index `pos`.
4349
4350 @par Complexity
4351
4352 Linear.
4353
4354 @return The index corrosponding to the first occurrence of `c` within
4355 `{begin() + pos, end())` if it exists, and @ref npos otherwise.
4356
4357 @param c The character to search for.
4358 @param pos The index to start searching at. The default argument
4359 for this parameter is `0`.
4360 */
4361 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4362 size_type
find(value_type c,size_type pos=0) const4363 find(
4364 value_type c,
4365 size_type pos = 0) const noexcept
4366 {
4367 return find(&c, pos, 1);
4368 }
4369
4370
4371 /** Find the last occurrence of a string within the string.
4372
4373 Constructs a temporary `string_view_type` object `sv` from `t`, and finds
4374 the last occurrence of `sv` within the string starting before or at
4375 the index `pos`.
4376
4377 @par Complexity
4378
4379 Linear.
4380
4381 @tparam T The type of the object to convert.
4382
4383 @par Constraints
4384
4385 `std::is_convertible<const T&, string_view>::value &&
4386 !std::is_convertible<const T&, const CharT*>::value`.
4387
4388 @return The highest index `idx` less than or equal to `pos`
4389 where each element of `{sv.begin(), sv.end())` is equal to
4390 that of `{begin() + idx, begin() + idx + count)` if one exists,
4391 and @ref npos otherwise.
4392
4393 @param t The string to search for.
4394 @param pos The index to start searching at. The default argument
4395 for this parameter is @ref npos.
4396 */
4397 template<typename T
4398 #ifndef BOOST_STATIC_STRING_DOCS
4399 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
4400 #endif
4401 >
4402 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4403 size_type
rfind(const T & t,size_type pos=npos) const4404 rfind(
4405 const T& t,
4406 size_type pos = npos) const
4407 noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
4408 {
4409 const string_view_type sv = t;
4410 return rfind(sv.data(), pos, sv.size());
4411 }
4412
4413 /** Find the last occurrence of a string within the string.
4414
4415 Finds the last occurrence of `str` within the string
4416 starting before or at the index `pos`.
4417
4418 @par Complexity
4419
4420 Linear.
4421
4422 @return The highest index `idx` less than or equal to `pos`
4423 where each element of `str` is equal to that
4424 of `{begin() + idx, begin() + idx + str.size())`
4425 if one exists, and @ref npos otherwise.
4426
4427 @param str The string to search for.
4428 @param pos The index to start searching at. The default argument for
4429 this parameter is @ref npos.
4430 */
4431 template<std::size_t M>
4432 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4433 size_type
rfind(const basic_static_string<M,CharT,Traits> & str,size_type pos=npos) const4434 rfind(
4435 const basic_static_string<M, CharT, Traits>& str,
4436 size_type pos = npos) const noexcept
4437 {
4438 return rfind(str.data(), pos, str.size());
4439 }
4440
4441 /** Find the last occurrence of a string within the string.
4442
4443 Finds the last occurrence of the string pointed to
4444 by `s` within the string starting before or at
4445 the index `pos`.
4446
4447 @par Complexity
4448
4449 Linear.
4450
4451 @return The highest index `idx` less than or equal to `pos`
4452 where each element of `{s, s + n)` is equal to that of
4453 `{begin() + idx, begin() + idx + n)` if one exists,
4454 and @ref npos otherwise.
4455
4456 @param s The string to search for.
4457 @param pos The index to start searching at.
4458 @param n The length of the string to search for.
4459 */
4460 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4461 size_type
4462 rfind(
4463 const_pointer s,
4464 size_type pos,
4465 size_type n) const noexcept;
4466
4467 /** Find the last occurrence of a string within the string.
4468
4469 Finds the last occurrence of the string pointed to by `s`
4470 of length `count` within the string starting before or at the
4471 index `pos`, where `count` is `traits_type::length(s)`.
4472
4473 @par Complexity
4474
4475 Linear.
4476
4477 @return The highest index `idx` less than or equal to `pos`
4478 where each element of `{s, s + count)` is equal to that of
4479 `{begin() + idx, begin() + idx + count)` if one exists,
4480 and @ref npos otherwise.
4481
4482 @param s The string to search for.
4483 @param pos The index to stop searching at. The default argument
4484 for this parameter is @ref npos.
4485 */
4486 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4487 size_type
rfind(const_pointer s,size_type pos=npos) const4488 rfind(
4489 const_pointer s,
4490 size_type pos = npos) const noexcept
4491 {
4492 return rfind(s, pos, traits_type::length(s));
4493 }
4494
4495 /** Find the last occurrence of a character within the string.
4496
4497 Finds the last occurrence of `c` within the string
4498 starting before or at the index `pos`.
4499
4500 @par Complexity
4501
4502 Linear.
4503
4504 @return The index corrosponding to the last occurrence of `c` within
4505 `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
4506
4507 @param c The character to search for.
4508 @param pos The index to stop searching at. The default argument
4509 for this parameter is @ref npos.
4510 */
4511 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4512 size_type
rfind(value_type c,size_type pos=npos) const4513 rfind(
4514 value_type c,
4515 size_type pos = npos) const noexcept
4516 {
4517 return rfind(&c, pos, 1);
4518 }
4519
4520 /** Find the first occurrence of any of the characters within the string.
4521
4522 Constructs a temporary `string_view_type` object `sv` from `t`, and finds
4523 the first occurrence of any of the characters in `sv`
4524 within the string starting at the index `pos`.
4525
4526 @par Complexity
4527
4528 Linear.
4529
4530 @tparam T The type of the object to convert.
4531
4532 @par Constraints
4533
4534 `std::is_convertible<const T&, string_view>::value &&
4535 !std::is_convertible<const T&, const CharT*>::value`.
4536
4537 @return The index corrosponding to the first occurrence of
4538 any of the characters in `{sv.begin(), sv.end())` within
4539 `{begin() + pos, end())` if it exists, and @ref npos otherwise.
4540
4541 @param t The characters to search for.
4542 @param pos The index to start searching at. The default argument
4543 for this parameter is `0`.
4544 */
4545 template<typename T
4546 #ifndef BOOST_STATIC_STRING_DOCS
4547 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
4548 #endif
4549 >
4550 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4551 size_type
find_first_of(const T & t,size_type pos=0) const4552 find_first_of(
4553 const T& t,
4554 size_type pos = 0) const
4555 noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
4556 {
4557 const string_view_type sv = t;
4558 return find_first_of(sv.data(), pos, sv.size());
4559 }
4560
4561 /** Find the first occurrence of any of the characters within the string.
4562
4563 Finds the first occurrence of any of the characters within `str` within the
4564 string starting at the index `pos`.
4565
4566 @par Complexity
4567
4568 Linear.
4569
4570 @return The index corrosponding to the first occurrence of any of the characters
4571 of `str` within `{begin() + pos, end())` if it exists, and @ref npos otherwise.
4572
4573 @param str The characters to search for.
4574 @param pos The index to start searching at. The default argument for
4575 this parameter is `0`.
4576 */
4577 template<std::size_t M>
4578 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4579 size_type
find_first_of(const basic_static_string<M,CharT,Traits> & str,size_type pos=0) const4580 find_first_of(
4581 const basic_static_string<M, CharT, Traits>& str,
4582 size_type pos = 0) const noexcept
4583 {
4584 return find_first_of(str.data(), pos, str.size());
4585 }
4586
4587 /** Find the first occurrence of any of the characters within the string.
4588
4589 Finds the first occurrence of any of the characters within the string pointed to
4590 by `s` within the string starting at the index `pos`.
4591
4592 @par Complexity
4593
4594 Linear.
4595
4596 @return The index corrosponding to the first occurrence
4597 of any of the characters in `{s, s + n)` within `{begin() + pos, end())`
4598 if it exists, and @ref npos otherwise.
4599
4600 @param s The characters to search for.
4601 @param pos The index to start searching at.
4602 @param n The length of the string to search for.
4603 */
4604 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4605 size_type
4606 find_first_of(
4607 const_pointer s,
4608 size_type pos,
4609 size_type n) const noexcept;
4610
4611 /** Find the first occurrence of any of the characters within the string.
4612
4613 Finds the first occurrence of the any of the characters within string
4614 pointed to by `s` of length `count` within the string starting at the
4615 index `pos`, where `count` is `traits_type::length(s)`.
4616
4617 @par Complexity
4618
4619 Linear.
4620
4621 @return The index corrosponding to the first occurrence of any of
4622 the characters in `{s, s + count)` within
4623 `{begin() + pos, end())` if it exists, and @ref npos otherwise.
4624
4625 @param s The characters to search for.
4626 @param pos The index to start searching at. The default argument
4627 for this parameter is `0`.
4628 */
4629 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4630 size_type
find_first_of(const_pointer s,size_type pos=0) const4631 find_first_of(
4632 const_pointer s,
4633 size_type pos = 0) const noexcept
4634 {
4635 return find_first_of(s, pos, traits_type::length(s));
4636 }
4637
4638 /** Find the first occurrence of a character within the string.
4639
4640 Finds the first occurrence of `c` within the string
4641 starting at the index `pos`.
4642
4643 @par Complexity
4644
4645 Linear.
4646
4647 @return The index corrosponding to the first occurrence of `c` within
4648 `{begin() + pos, end())` if it exists, and @ref npos otherwise.
4649
4650 @param c The character to search for.
4651 @param pos The index to start searching at. The default argument
4652 for this parameter is `0`.
4653 */
4654 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4655 size_type
find_first_of(value_type c,size_type pos=0) const4656 find_first_of(
4657 value_type c,
4658 size_type pos = 0) const noexcept
4659 {
4660 return find_first_of(&c, pos, 1);
4661 }
4662
4663 /** Find the last occurrence of any of the characters within the string.
4664
4665 Constructs a temporary `string_view_type` object `sv` from `t`, and finds
4666 the last occurrence of any of the characters in `sv`
4667 within the string before or at the index `pos`.
4668
4669 @par Complexity
4670
4671 Linear.
4672
4673 @tparam T The type of the object to convert.
4674
4675 @par Constraints
4676
4677 `std::is_convertible<const T&, string_view>::value &&
4678 !std::is_convertible<const T&, const CharT*>::value`.
4679
4680 @return The index corrosponding to the last occurrence of
4681 any of the characters in `{sv.begin(), sv.end())` within
4682 `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
4683
4684 @param t The characters to search for.
4685 @param pos The index to stop searching at. The default argument
4686 for this parameter is @ref npos.
4687 */
4688 template<typename T
4689 #ifndef BOOST_STATIC_STRING_DOCS
4690 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
4691 #endif
4692 >
4693 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4694 size_type
find_last_of(const T & t,size_type pos=npos) const4695 find_last_of(
4696 const T& t,
4697 size_type pos = npos) const
4698 noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
4699 {
4700 const string_view_type sv = t;
4701 return find_last_of(sv.data(), pos, sv.size());
4702 }
4703
4704 /** Find the last occurrence of any of the characters within the string.
4705
4706 Finds the last occurrence of any of the characters within `str` within the
4707 string starting before or at the index `pos`.
4708
4709 @par Complexity
4710
4711 Linear.
4712
4713 @return The index corrosponding to the last occurrence of any of the characters
4714 of `str` within `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
4715
4716 @param str The characters to search for.
4717 @param pos The index to stop searching at. The default argument for
4718 this parameter is @ref npos.
4719 */
4720 template<std::size_t M>
4721 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4722 size_type
find_last_of(const basic_static_string<M,CharT,Traits> & str,size_type pos=npos) const4723 find_last_of(
4724 const basic_static_string<M, CharT, Traits>& str,
4725 size_type pos = npos) const noexcept
4726 {
4727 return find_last_of(str.data(), pos, str.size());
4728 }
4729
4730 /** Find the last occurrence of any of the characters within the string.
4731
4732 Finds the last occurrence of any of the characters within the string pointed to
4733 by `s` within the string before or at the index `pos`.
4734
4735 @par Complexity
4736
4737 Linear.
4738
4739 @return The index corrosponding to the last occurrence
4740 of any of the characters in `{s, s + n)` within `{begin(), begin() + pos}`
4741 if it exists, and @ref npos otherwise.
4742
4743 @param s The characters to search for.
4744 @param pos The index to stop searching at.
4745 @param n The length of the string to search for.
4746 */
4747 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4748 size_type
4749 find_last_of(
4750 const_pointer s,
4751 size_type pos,
4752 size_type n) const noexcept;
4753
4754 /** Find the last occurrence of any of the characters within the string.
4755
4756 Finds the last occurrence of any of the characters within the string pointed to
4757 by `s` of length `count` within the string before or at the index `pos`,
4758 where `count` is `traits_type::length(s)`.
4759
4760 @par Complexity
4761
4762 Linear.
4763
4764 @return The index corrosponding to the last occurrence
4765 of any of the characters in `{s, s + count)` within `{begin(), begin() + pos}`
4766 if it exists, and @ref npos otherwise.
4767
4768 @param s The characters to search for.
4769 @param pos The index to stop searching at. The default argument for
4770 this parameter is @ref npos.
4771 */
4772 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4773 size_type
find_last_of(const_pointer s,size_type pos=npos) const4774 find_last_of(
4775 const_pointer s,
4776 size_type pos = npos) const noexcept
4777 {
4778 return find_last_of(s, pos, traits_type::length(s));
4779 }
4780
4781 /** Find the last occurrence of a character within the string.
4782
4783 Finds the last occurrence of `c` within the string
4784 before or at the index `pos`.
4785
4786 @par Complexity
4787
4788 Linear.
4789
4790 @return The index corrosponding to the last occurrence of `c` within
4791 `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
4792
4793 @param c The character to search for.
4794 @param pos The index to stop searching at. The default argument
4795 for this parameter is @ref npos.
4796 */
4797 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4798 size_type
find_last_of(value_type c,size_type pos=npos) const4799 find_last_of(
4800 value_type c,
4801 size_type pos = npos) const noexcept
4802 {
4803 return find_last_of(&c, pos, 1);
4804 }
4805
4806 /** Find the first occurrence of a character not within the string.
4807
4808 Constructs a temporary `string_view_type` object `sv` from `t`, and finds
4809 the first character that is not within `sv`, starting at the index `pos`.
4810
4811 @par Complexity
4812
4813 Linear.
4814
4815 @tparam T The type of the object to convert.
4816
4817 @par Constraints
4818
4819 `std::is_convertible<const T&, string_view>::value &&
4820 !std::is_convertible<const T&, const CharT*>::value`.
4821
4822 @return The index corrosponding to the first occurrence of
4823 a character that is not in `{sv.begin(), sv.end())` within
4824 `{begin() + pos, end())` if it exists, and @ref npos otherwise.
4825
4826 @param t The characters to ignore.
4827 @param pos The index to start searching at. The default argument
4828 for this parameter is `0`.
4829 */
4830 template<typename T
4831 #ifndef BOOST_STATIC_STRING_DOCS
4832 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
4833 #endif
4834 >
4835 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4836 size_type
find_first_not_of(const T & t,size_type pos=0) const4837 find_first_not_of(
4838 const T& t,
4839 size_type pos = 0) const
4840 noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
4841 {
4842 const string_view_type sv = t;
4843 return find_first_not_of(sv.data(), pos, sv.size());
4844 }
4845
4846 /** Find the first occurrence of any of the characters not within the string.
4847
4848 Finds the first occurrence of a character that is not within `str`
4849 within the string starting at the index `pos`.
4850
4851 @par Complexity
4852
4853 Linear.
4854
4855 @return The index corrosponding to the first character of `{begin() + pos, end())`
4856 that is not within `str` if it exists, and @ref npos otherwise.
4857
4858 @param str The characters to ignore.
4859 @param pos The index to start searching at. The default argument for
4860 this parameter is `0`.
4861 */
4862 template<std::size_t M>
4863 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4864 size_type
find_first_not_of(const basic_static_string<M,CharT,Traits> & str,size_type pos=0) const4865 find_first_not_of(
4866 const basic_static_string<M, CharT, Traits>& str,
4867 size_type pos = 0) const noexcept
4868 {
4869 return find_first_not_of(str.data(), pos, str.size());
4870 }
4871
4872 /** Find the first occurrence of any of the characters not within the string.
4873
4874 Finds the first occurrence of a character that is not within the string
4875 pointed to by `s` within the string starting at the index `pos`.
4876
4877 @par Complexity
4878
4879 Linear.
4880
4881 @return The index corrosponding to the first character of `{begin() + pos, end())`
4882 that is not within `{s, s + n)` if it exists, and @ref npos otherwise.
4883
4884 @param s The characters to ignore.
4885 @param pos The index to start searching at. The default argument for
4886 this parameter is `0`.
4887 @param n The length of the characters to ignore.
4888 */
4889 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4890 size_type
4891 find_first_not_of(
4892 const_pointer s,
4893 size_type pos,
4894 size_type n) const noexcept;
4895
4896 /** Find the first occurrence of any of the characters not within the string.
4897
4898 Finds the first occurrence of a character that is not within the string
4899 pointed to by `s` of length `count` within the string starting
4900 at the index `pos`, where `count` is `traits_type::length(s)`.
4901
4902 @par Complexity
4903
4904 Linear.
4905
4906 @return The index corrosponding to the first character of `{begin() + pos, end())`
4907 that is not within `{s, s + count)` if it exists, and @ref npos otherwise.
4908
4909 @param s The characters to ignore.
4910 @param pos The index to start searching at. The default argument for
4911 this parameter is `0`.
4912 */
4913 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4914 size_type
find_first_not_of(const_pointer s,size_type pos=0) const4915 find_first_not_of(
4916 const_pointer s,
4917 size_type pos = 0) const noexcept
4918 {
4919 return find_first_not_of(s, pos, traits_type::length(s));
4920 }
4921
4922 /** Find the first occurrence of a character not equal to `c`.
4923
4924 Finds the first occurrence of a character that is not equal
4925 to `c`.
4926
4927 @par Complexity
4928
4929 Linear.
4930
4931 @return The index corrosponding to the first character of `{begin() + pos, end())`
4932 that is not equal to `c` if it exists, and @ref npos otherwise.
4933
4934 @param c The character to ignore.
4935 @param pos The index to start searching at. The default argument for
4936 this parameter is `0`.
4937 */
4938 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4939 size_type
find_first_not_of(value_type c,size_type pos=0) const4940 find_first_not_of(
4941 value_type c,
4942 size_type pos = 0) const noexcept
4943 {
4944 return find_first_not_of(&c, pos, 1);
4945 }
4946
4947 /** Find the last occurrence of a character not within the string.
4948
4949 Constructs a temporary `string_view_type` object `sv` from `t`, and finds
4950 the last character that is not within `sv`, starting at the index `pos`.
4951
4952 @par Complexity
4953
4954 Linear.
4955
4956 @tparam T The type of the object to convert.
4957
4958 @par Constraints
4959
4960 `std::is_convertible<const T&, string_view>::value &&
4961 !std::is_convertible<const T&, const CharT*>::value`.
4962
4963 @return The index corrosponding to the last occurrence of
4964 a character that is not in `{sv.begin(), sv.end())` within
4965 `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
4966
4967 @param t The characters to ignore.
4968 @param pos The index to start searching at. The default argument
4969 for this parameter is @ref npos.
4970 */
4971 template<typename T
4972 #ifndef BOOST_STATIC_STRING_DOCS
4973 , typename = detail::enable_if_viewable_t<T, CharT, Traits>
4974 #endif
4975 >
4976 BOOST_STATIC_STRING_CPP14_CONSTEXPR
4977 size_type
find_last_not_of(const T & t,size_type pos=npos) const4978 find_last_not_of(
4979 const T& t,
4980 size_type pos = npos) const
4981 noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
4982 {
4983 const string_view_type sv = t;
4984 return find_last_not_of(sv.data(), pos, sv.size());
4985 }
4986
4987 /** Find the last occurrence of a character not within the string.
4988
4989 Finds the last occurrence of a character that is not within `str`
4990 within the string before or at the index `pos`.
4991
4992 @par Complexity
4993
4994 Linear.
4995
4996 @return The index corrosponding to the last character of `{begin(), begin() + pos}`
4997 that is not within `str` if it exists, and @ref npos otherwise.
4998
4999 @param str The characters to ignore.
5000 @param pos The index to stop searching at. The default argument for
5001 this parameter is @ref npos.
5002 */
5003 template<size_t M>
5004 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5005 size_type
find_last_not_of(const basic_static_string<M,CharT,Traits> & str,size_type pos=npos) const5006 find_last_not_of(
5007 const basic_static_string<M, CharT, Traits>& str,
5008 size_type pos = npos) const noexcept
5009 {
5010 return find_last_not_of(str.data(), pos, str.size());
5011 }
5012
5013 /** Find the last occurrence of a character not within the string.
5014
5015 Finds the last occurrence of a character that is not within the
5016 string pointed to by `s` within the string before or at the index `pos`.
5017
5018 @par Complexity
5019
5020 Linear.
5021
5022 @return The index corrosponding to the last character of `{begin(), begin() + pos}`
5023 that is not within `{s, s + n)` if it exists, and @ref npos otherwise.
5024
5025 @param s The characters to ignore.
5026 @param pos The index to stop searching at. The default argument for
5027 this parameter is @ref npos.
5028 @param n The length of the characters to ignore.
5029 */
5030 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5031 size_type
5032 find_last_not_of(
5033 const_pointer s,
5034 size_type pos,
5035 size_type n) const noexcept;
5036
5037
5038 /** Find the last occurrence of a character not within the string.
5039
5040 Finds the last occurrence of a character that is not within the
5041 string pointed to by `s` of length `count` within the string
5042 before or at the index `pos`, where `count` is `traits_type::length(s)`.
5043
5044 @par Complexity
5045
5046 Linear.
5047
5048 @return The index corrosponding to the last character of `{begin(), begin() + pos}`
5049 that is not within `{s, s + count)` if it exists, and @ref npos otherwise.
5050
5051 @param s The characters to ignore.
5052 @param pos The index to stop searching at. The default argument for
5053 this parameter is @ref npos.
5054 */
5055 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5056 size_type
find_last_not_of(const_pointer s,size_type pos=npos) const5057 find_last_not_of(
5058 const_pointer s,
5059 size_type pos = npos) const noexcept
5060 {
5061 return find_last_not_of(s, pos, traits_type::length(s));
5062 }
5063
5064 /** Find the last occurrence of a character not equal to `c`.
5065
5066 Finds the last occurrence of a character that is not equal
5067 to `c` before or at the index `pos`.
5068
5069 @par Complexity
5070
5071 Linear.
5072
5073 @return The index corrosponding to the last character of `{begin(), begin() + pos}`
5074 that is not equal to `c` if it exists, and @ref npos otherwise.
5075
5076 @param c The character to ignore.
5077 @param pos The index to start searching at. The default argument for
5078 this parameter is @ref npos.
5079 */
5080 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5081 size_type
find_last_not_of(value_type c,size_type pos=npos) const5082 find_last_not_of(
5083 value_type c,
5084 size_type pos = npos) const noexcept
5085 {
5086 return find_last_not_of(&c, pos, 1);
5087 }
5088
5089 /** Return whether the string begins with a string.
5090
5091 Returns `true` if the string begins with `s`, and `false` otherwise.
5092
5093 @par Complexity
5094
5095 Linear.
5096
5097 @param s The string view to check for.
5098 */
5099 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5100 bool
starts_with(string_view_type s) const5101 starts_with(
5102 string_view_type s) const noexcept
5103 {
5104 const size_type len = s.size();
5105 return size() >= len && !traits_type::compare(data(), s.data(), len);
5106 }
5107
5108 /** Return whether the string begins with a character.
5109
5110 Returns `true` if the string begins with `c`, and `false` otherwise.
5111
5112 @par Complexity
5113
5114 Constant.
5115
5116 @param c The character to check for.
5117 */
5118 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5119 bool
starts_with(value_type c) const5120 starts_with(
5121 value_type c) const noexcept
5122 {
5123 return !empty() && traits_type::eq(front(), c);
5124 }
5125
5126 /** Return whether the string begins with a string.
5127
5128 Returns `true` if the string begins with the string
5129 pointed to be `s` of length `traits_type::length(s)`,
5130 and `false` otherwise.
5131
5132 @par Complexity
5133
5134 Linear.
5135
5136 @param s The string to check for.
5137 */
5138 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5139 bool
starts_with(const_pointer s) const5140 starts_with(
5141 const_pointer s) const noexcept
5142 {
5143 const size_type len = traits_type::length(s);
5144 return size() >= len && !traits_type::compare(data(), s, len);
5145 }
5146
5147 /** Return whether the string ends with a string.
5148
5149 Returns `true` if the string ends with `s`, and `false` otherwise.
5150
5151 @par Complexity
5152
5153 Linear.
5154
5155 @param s The string view to check for.
5156 */
5157 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5158 bool
ends_with(string_view_type s) const5159 ends_with(
5160 string_view_type s) const noexcept
5161 {
5162 const size_type len = s.size();
5163 return size() >= len && !traits_type::compare(data() + (size() - len), s.data(), len);
5164 }
5165
5166 /** Return whether the string ends with a character.
5167
5168 Returns `true` if the string ends with `c`, and `false` otherwise.
5169
5170 @par Complexity
5171
5172 Constant.
5173
5174 @param c The character to check for.
5175 */
5176 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5177 bool
ends_with(value_type c) const5178 ends_with(
5179 value_type c) const noexcept
5180 {
5181 return !empty() && traits_type::eq(back(), c);
5182 }
5183
5184 /** Return whether the string ends with a string.
5185
5186 Returns `true` if the string ends with the string
5187 pointed to be `s` of length `traits_type::length(s)`,
5188 and `false` otherwise.
5189
5190 @par Complexity
5191
5192 Linear.
5193
5194 @param s The string to check for.
5195 */
5196 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5197 bool
ends_with(const_pointer s) const5198 ends_with(
5199 const_pointer s) const noexcept
5200 {
5201 const size_type len = traits_type::length(s);
5202 return size() >= len && !traits_type::compare(data() + (size() - len), s, len);
5203 }
5204
5205 private:
5206 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5207 basic_static_string&
term()5208 term() noexcept
5209 {
5210 this->term_impl();
5211 return *this;
5212 }
5213
5214 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5215 basic_static_string&
assign_char(value_type ch,std::true_type)5216 assign_char(value_type ch, std::true_type) noexcept
5217 {
5218 this->set_size(1);
5219 traits_type::assign(data()[0], ch);
5220 return term();
5221 }
5222
5223 BOOST_STATIC_STRING_NORETURN
5224 basic_static_string&
assign_char(value_type,std::false_type)5225 assign_char(value_type, std::false_type)
5226 {
5227 detail::throw_exception<std::length_error>("max_size() == 0");
5228 // This eliminates any potential warnings
5229 #ifdef BOOST_STATIC_STRING_NO_NORETURN
5230 return *this;
5231 #endif
5232 }
5233
5234 // Returns the size of data read from input iterator. Read data begins at data() + size() + 1.
5235 template<typename InputIterator>
5236 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5237 size_type
5238 read_back(
5239 bool overwrite_null,
5240 InputIterator first,
5241 InputIterator last);
5242
5243 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5244 basic_static_string&
replace_unchecked(size_type pos,size_type n1,const_pointer s,size_type n2)5245 replace_unchecked(
5246 size_type pos,
5247 size_type n1,
5248 const_pointer s,
5249 size_type n2)
5250 {
5251 if (pos > size())
5252 detail::throw_exception<std::out_of_range>(
5253 "pos > size()");
5254 return replace_unchecked(data() + pos, data() + pos + capped_length(pos, n1), s, n2);
5255 }
5256
5257 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5258 basic_static_string&
5259 replace_unchecked(
5260 const_iterator i1,
5261 const_iterator i2,
5262 const_pointer s,
5263 size_type n2);
5264
5265 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5266 basic_static_string&
insert_unchecked(size_type index,const_pointer s,size_type count)5267 insert_unchecked(
5268 size_type index,
5269 const_pointer s,
5270 size_type count)
5271 {
5272 if (index > size())
5273 detail::throw_exception<std::out_of_range>(
5274 "index > size()");
5275 insert_unchecked(data() + index, s, count);
5276 return *this;
5277 }
5278
5279 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5280 iterator
5281 insert_unchecked(
5282 const_iterator pos,
5283 const_pointer s,
5284 size_type count);
5285
5286 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5287 basic_static_string&
assign_unchecked(const_pointer s,size_type count)5288 assign_unchecked(
5289 const_pointer s,
5290 size_type count) noexcept
5291 {
5292 this->set_size(count);
5293 traits_type::copy(data(), s, size() + 1);
5294 return *this;
5295 }
5296
5297 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5298 size_type
capped_length(size_type index,size_type length) const5299 capped_length(
5300 size_type index,
5301 size_type length) const
5302 {
5303 if (index > size())
5304 detail::throw_exception<std::out_of_range>(
5305 "index > size()");
5306 return (std::min)(size() - index, length);
5307 }
5308 };
5309
5310 //------------------------------------------------------------------------------
5311 //
5312 // Non-member functions
5313 //
5314 //------------------------------------------------------------------------------
5315
5316 template<
5317 std::size_t N, std::size_t M,
5318 typename CharT, typename Traits>
5319 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5320 inline
5321 bool
operator ==(const basic_static_string<N,CharT,Traits> & lhs,const basic_static_string<M,CharT,Traits> & rhs)5322 operator==(
5323 const basic_static_string<N, CharT, Traits>& lhs,
5324 const basic_static_string<M, CharT, Traits>& rhs)
5325 {
5326 return lhs.compare(rhs) == 0;
5327 }
5328
5329 template<
5330 std::size_t N, std::size_t M,
5331 typename CharT, typename Traits>
5332 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5333 inline
5334 bool
operator !=(const basic_static_string<N,CharT,Traits> & lhs,const basic_static_string<M,CharT,Traits> & rhs)5335 operator!=(
5336 const basic_static_string<N, CharT, Traits>& lhs,
5337 const basic_static_string<M, CharT, Traits>& rhs)
5338 {
5339 return lhs.compare(rhs) != 0;
5340 }
5341
5342 template<
5343 std::size_t N, std::size_t M,
5344 typename CharT, typename Traits>
5345 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5346 inline
5347 bool
operator <(const basic_static_string<N,CharT,Traits> & lhs,const basic_static_string<M,CharT,Traits> & rhs)5348 operator<(
5349 const basic_static_string<N, CharT, Traits>& lhs,
5350 const basic_static_string<M, CharT, Traits>& rhs)
5351 {
5352 return lhs.compare(rhs) < 0;
5353 }
5354
5355 template<
5356 std::size_t N, std::size_t M,
5357 typename CharT, typename Traits>
5358 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5359 inline
5360 bool
operator <=(const basic_static_string<N,CharT,Traits> & lhs,const basic_static_string<M,CharT,Traits> & rhs)5361 operator<=(
5362 const basic_static_string<N, CharT, Traits>& lhs,
5363 const basic_static_string<M, CharT, Traits>& rhs)
5364 {
5365 return lhs.compare(rhs) <= 0;
5366 }
5367
5368 template<
5369 std::size_t N, std::size_t M,
5370 typename CharT, typename Traits>
5371 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5372 inline
5373 bool
operator >(const basic_static_string<N,CharT,Traits> & lhs,const basic_static_string<M,CharT,Traits> & rhs)5374 operator>(
5375 const basic_static_string<N, CharT, Traits>& lhs,
5376 const basic_static_string<M, CharT, Traits>& rhs)
5377 {
5378 return lhs.compare(rhs) > 0;
5379 }
5380
5381 template<
5382 std::size_t N, std::size_t M,
5383 typename CharT, typename Traits>
5384 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5385 inline
5386 bool
operator >=(const basic_static_string<N,CharT,Traits> & lhs,const basic_static_string<M,CharT,Traits> & rhs)5387 operator>=(
5388 const basic_static_string<N, CharT, Traits>& lhs,
5389 const basic_static_string<M, CharT, Traits>& rhs)
5390 {
5391 return lhs.compare(rhs) >= 0;
5392 }
5393
5394 template<std::size_t N, typename CharT, typename Traits>
5395 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5396 inline
5397 bool
operator ==(const CharT * lhs,const basic_static_string<N,CharT,Traits> & rhs)5398 operator==(
5399 const CharT* lhs,
5400 const basic_static_string<N, CharT, Traits>& rhs)
5401 {
5402 return detail::lexicographical_compare<CharT, Traits>(
5403 lhs, Traits::length(lhs),
5404 rhs.data(), rhs.size()) == 0;
5405 }
5406
5407 template<std::size_t N, typename CharT, typename Traits>
5408 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5409 inline
5410 bool
operator ==(const basic_static_string<N,CharT,Traits> & lhs,const CharT * rhs)5411 operator==(
5412 const basic_static_string<N, CharT, Traits>& lhs,
5413 const CharT* rhs)
5414 {
5415 return detail::lexicographical_compare<CharT, Traits>(
5416 lhs.data(), lhs.size(),
5417 rhs, Traits::length(rhs)) == 0;
5418 }
5419
5420 template<std::size_t N, typename CharT, typename Traits>
5421 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5422 inline
5423 bool
operator !=(const CharT * lhs,const basic_static_string<N,CharT,Traits> & rhs)5424 operator!=(
5425 const CharT* lhs,
5426 const basic_static_string<N, CharT, Traits>& rhs)
5427 {
5428 return detail::lexicographical_compare<CharT, Traits>(
5429 lhs, Traits::length(lhs),
5430 rhs.data(), rhs.size()) != 0;
5431 }
5432
5433 template<std::size_t N, typename CharT, typename Traits>
5434 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5435 inline
5436 bool
operator !=(const basic_static_string<N,CharT,Traits> & lhs,const CharT * rhs)5437 operator!=(
5438 const basic_static_string<N, CharT, Traits>& lhs,
5439 const CharT* rhs)
5440 {
5441 return detail::lexicographical_compare<CharT, Traits>(
5442 lhs.data(), lhs.size(),
5443 rhs, Traits::length(rhs)) != 0;
5444 }
5445
5446 template<std::size_t N, typename CharT, typename Traits>
5447 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5448 inline
5449 bool
operator <(const CharT * lhs,const basic_static_string<N,CharT,Traits> & rhs)5450 operator<(
5451 const CharT* lhs,
5452 const basic_static_string<N, CharT, Traits>& rhs)
5453 {
5454 return detail::lexicographical_compare<CharT, Traits>(
5455 lhs, Traits::length(lhs),
5456 rhs.data(), rhs.size()) < 0;
5457 }
5458
5459 template<std::size_t N, typename CharT, typename Traits>
5460 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5461 inline
5462 bool
operator <(const basic_static_string<N,CharT,Traits> & lhs,const CharT * rhs)5463 operator<(
5464 const basic_static_string<N, CharT, Traits>& lhs,
5465 const CharT* rhs)
5466 {
5467 return detail::lexicographical_compare<CharT, Traits>(
5468 lhs.data(), lhs.size(),
5469 rhs, Traits::length(rhs)) < 0;
5470 }
5471
5472 template<std::size_t N, typename CharT, typename Traits>
5473 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5474 inline
5475 bool
operator <=(const CharT * lhs,const basic_static_string<N,CharT,Traits> & rhs)5476 operator<=(
5477 const CharT* lhs,
5478 const basic_static_string<N, CharT, Traits>& rhs)
5479 {
5480 return detail::lexicographical_compare<CharT, Traits>(
5481 lhs, Traits::length(lhs),
5482 rhs.data(), rhs.size()) <= 0;
5483 }
5484
5485 template<std::size_t N, typename CharT, typename Traits>
5486 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5487 inline
5488 bool
operator <=(const basic_static_string<N,CharT,Traits> & lhs,const CharT * rhs)5489 operator<=(
5490 const basic_static_string<N, CharT, Traits>& lhs,
5491 const CharT* rhs)
5492 {
5493 return detail::lexicographical_compare<CharT, Traits>(
5494 lhs.data(), lhs.size(),
5495 rhs, Traits::length(rhs)) <= 0;
5496 }
5497
5498 template<std::size_t N, typename CharT, typename Traits>
5499 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5500 inline
5501 bool
operator >(const CharT * lhs,const basic_static_string<N,CharT,Traits> & rhs)5502 operator>(
5503 const CharT* lhs,
5504 const basic_static_string<N, CharT, Traits>& rhs)
5505 {
5506 return detail::lexicographical_compare<CharT, Traits>(
5507 lhs, Traits::length(lhs),
5508 rhs.data(), rhs.size()) > 0;
5509 }
5510
5511 template<std::size_t N, typename CharT, typename Traits>
5512 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5513 inline
5514 bool
operator >(const basic_static_string<N,CharT,Traits> & lhs,const CharT * rhs)5515 operator>(
5516 const basic_static_string<N, CharT, Traits>& lhs,
5517 const CharT* rhs)
5518 {
5519 return detail::lexicographical_compare<CharT, Traits>(
5520 lhs.data(), lhs.size(),
5521 rhs, Traits::length(rhs)) > 0;
5522 }
5523
5524 template<std::size_t N, typename CharT, typename Traits>
5525 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5526 inline
5527 bool
operator >=(const CharT * lhs,const basic_static_string<N,CharT,Traits> & rhs)5528 operator>=(
5529 const CharT* lhs,
5530 const basic_static_string<N, CharT, Traits>& rhs)
5531 {
5532 return detail::lexicographical_compare<CharT, Traits>(
5533 lhs, Traits::length(lhs),
5534 rhs.data(), rhs.size()) >= 0;
5535 }
5536
5537 template<std::size_t N, typename CharT, typename Traits>
5538 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5539 inline
5540 bool
operator >=(const basic_static_string<N,CharT,Traits> & lhs,const CharT * rhs)5541 operator>=(
5542 const basic_static_string<N, CharT, Traits>& lhs,
5543 const CharT* rhs)
5544 {
5545 return detail::lexicographical_compare<CharT, Traits>(
5546 lhs.data(), lhs.size(),
5547 rhs, Traits::length(rhs)) >= 0;
5548 }
5549
5550 template<
5551 std::size_t N, std::size_t M,
5552 typename CharT, typename Traits>
5553 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5554 inline
5555 basic_static_string<N + M, CharT, Traits>
operator +(const basic_static_string<N,CharT,Traits> & lhs,const basic_static_string<M,CharT,Traits> & rhs)5556 operator+(
5557 const basic_static_string<N, CharT, Traits>& lhs,
5558 const basic_static_string<M, CharT, Traits>& rhs)
5559 {
5560 return basic_static_string<N + M, CharT, Traits>(lhs) += rhs;
5561 }
5562
5563 template<std::size_t N, typename CharT, typename Traits>
5564 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5565 inline
5566 basic_static_string<N + 1, CharT, Traits>
operator +(const basic_static_string<N,CharT,Traits> & lhs,CharT rhs)5567 operator+(
5568 const basic_static_string<N, CharT, Traits>& lhs,
5569 CharT rhs)
5570 {
5571 return basic_static_string<N + 1, CharT, Traits>(lhs) += rhs;
5572 }
5573
5574 template<std::size_t N, typename CharT, typename Traits>
5575 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5576 inline
5577 basic_static_string<N + 1, CharT, Traits>
operator +(CharT lhs,const basic_static_string<N,CharT,Traits> & rhs)5578 operator+(
5579 CharT lhs,
5580 const basic_static_string<N, CharT, Traits>& rhs)
5581 {
5582 // The cast to std::size_t is needed here since 0 is a null pointer constant
5583 return basic_static_string<N + 1, CharT, Traits>(rhs).insert(
5584 std::size_t(0), 1, lhs);
5585 }
5586
5587 // Add a null terminated character array to a string.
5588 template<
5589 std::size_t N, std::size_t M,
5590 typename CharT, typename Traits>
5591 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5592 inline
5593 basic_static_string<N + M, CharT, Traits>
operator +(const basic_static_string<N,CharT,Traits> & lhs,const CharT (& rhs)[M])5594 operator+(
5595 const basic_static_string<N, CharT, Traits>& lhs,
5596 const CharT(&rhs)[M])
5597 {
5598 return basic_static_string<N + M, CharT, Traits>(lhs).append(+rhs);
5599 }
5600
5601 // Add a string to a null terminated character array.
5602 template<
5603 std::size_t N, std::size_t M,
5604 typename CharT, typename Traits>
5605 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5606 inline
5607 basic_static_string<N + M, CharT, Traits>
operator +(const CharT (& lhs)[N],const basic_static_string<M,CharT,Traits> & rhs)5608 operator+(
5609 const CharT(&lhs)[N],
5610 const basic_static_string<M, CharT, Traits>& rhs)
5611 {
5612 // The cast to std::size_t is needed here since 0 is a null pointer constant
5613 return basic_static_string<N + M, CharT, Traits>(rhs).insert(
5614 std::size_t(0), +lhs);
5615 }
5616
5617 //------------------------------------------------------------------------------
5618 //
5619 // swap
5620 //
5621 //------------------------------------------------------------------------------
5622
5623 template<std::size_t N, typename CharT, typename Traits>
5624 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5625 inline
5626 void
swap(basic_static_string<N,CharT,Traits> & lhs,basic_static_string<N,CharT,Traits> & rhs)5627 swap(
5628 basic_static_string<N, CharT, Traits>& lhs,
5629 basic_static_string<N, CharT, Traits>& rhs)
5630 {
5631 lhs.swap(rhs);
5632 }
5633
5634 template<
5635 std::size_t N, std::size_t M,
5636 typename CharT, typename Traits>
5637 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5638 inline
5639 void
swap(basic_static_string<N,CharT,Traits> & lhs,basic_static_string<M,CharT,Traits> & rhs)5640 swap(
5641 basic_static_string<N, CharT, Traits>& lhs,
5642 basic_static_string<M, CharT, Traits>& rhs)
5643 {
5644 lhs.swap(rhs);
5645 }
5646
5647 //------------------------------------------------------------------------------
5648 //
5649 // Input/Output
5650 //
5651 //------------------------------------------------------------------------------
5652
5653 template<std::size_t N, typename CharT, typename Traits>
5654 inline
5655 std::basic_ostream<CharT, Traits>&
operator <<(std::basic_ostream<CharT,Traits> & os,const basic_static_string<N,CharT,Traits> & s)5656 operator<<(
5657 std::basic_ostream<CharT, Traits>& os,
5658 const basic_static_string<N, CharT, Traits>& s)
5659 {
5660 return os << basic_string_view<CharT, Traits>(s.data(), s.size());
5661 }
5662
5663 //------------------------------------------------------------------------------
5664 //
5665 // Numeric conversions
5666 //
5667 //------------------------------------------------------------------------------
5668
5669 // Signed overloads have a + 2, one for the missing digit,
5670 // and one for the sign.
5671
5672 // Unsigned overloads have a + 1, for the missing digit.
5673
5674 // Floating point overloads have a + 4, for the sign
5675 // of the integral part, sign of the exponent, the 'e',
5676 // and the decimal.
5677
5678 /// Converts `value` to a `static_string`
5679 static_string<std::numeric_limits<int>::digits10 + 2>
5680 inline
to_static_string(int value)5681 to_static_string(int value) noexcept
5682 {
5683 return detail::to_static_string_int_impl<
5684 std::numeric_limits<int>::digits10 + 2>(value);
5685 }
5686
5687 /// Converts `value` to a `static_string`
5688 static_string<std::numeric_limits<long>::digits10 + 2>
5689 inline
to_static_string(long value)5690 to_static_string(long value) noexcept
5691 {
5692 return detail::to_static_string_int_impl<
5693 std::numeric_limits<long>::digits10 + 2>(value);
5694 }
5695
5696 /// Converts `value` to a `static_string`
5697 static_string<std::numeric_limits<long long>::digits10 + 2>
5698 inline
to_static_string(long long value)5699 to_static_string(long long value) noexcept
5700 {
5701 return detail::to_static_string_int_impl<
5702 std::numeric_limits<long long>::digits10 + 2>(value);
5703 }
5704
5705 /// Converts `value` to a `static_string`
5706 static_string<std::numeric_limits<unsigned int>::digits10 + 1>
5707 inline
to_static_string(unsigned int value)5708 to_static_string(unsigned int value) noexcept
5709 {
5710 return detail::to_static_string_int_impl<
5711 std::numeric_limits<unsigned int>::digits10 + 1>(value);
5712 }
5713
5714 /// Converts `value` to a `static_string`
5715 static_string<std::numeric_limits<unsigned long>::digits10 + 1>
5716 inline
to_static_string(unsigned long value)5717 to_static_string(unsigned long value) noexcept
5718 {
5719 return detail::to_static_string_int_impl<
5720 std::numeric_limits<unsigned long>::digits10 + 1>(value);
5721 }
5722
5723 /// Converts `value` to a `static_string`
5724 static_string<std::numeric_limits<unsigned long long>::digits10 + 1>
5725 inline
to_static_string(unsigned long long value)5726 to_static_string(unsigned long long value) noexcept
5727 {
5728 return detail::to_static_string_int_impl<
5729 std::numeric_limits<unsigned long long>::digits10 + 1>(value);
5730 }
5731
5732 /// Converts `value` to a `static_string`
5733 static_string<std::numeric_limits<float>::max_digits10 + 4>
5734 inline
to_static_string(float value)5735 to_static_string(float value) noexcept
5736 {
5737 return detail::to_static_string_float_impl<
5738 std::numeric_limits<float>::max_digits10 + 4>(value);
5739 }
5740
5741 /// Converts `value` to a `static_string`
5742 static_string<std::numeric_limits<double>::max_digits10 + 4>
5743 inline
to_static_string(double value)5744 to_static_string(double value) noexcept
5745 {
5746 return detail::to_static_string_float_impl<
5747 std::numeric_limits<double>::max_digits10 + 4>(value);
5748 }
5749
5750 /// Converts `value` to a `static_string`
5751 static_string<std::numeric_limits<long double>::max_digits10 + 4>
5752 inline
to_static_string(long double value)5753 to_static_string(long double value) noexcept
5754 {
5755 return detail::to_static_string_float_impl<
5756 std::numeric_limits<long double>::max_digits10 + 4>(value);
5757 }
5758
5759 /// Converts `value` to a `static_wstring`
5760 static_wstring<std::numeric_limits<int>::digits10 + 2>
5761 inline
to_static_wstring(int value)5762 to_static_wstring(int value) noexcept
5763 {
5764 return detail::to_static_wstring_int_impl<
5765 std::numeric_limits<int>::digits10 + 2>(value);
5766 }
5767
5768 /// Converts `value` to a `static_wstring`
5769 static_wstring<std::numeric_limits<long>::digits10 + 2>
5770 inline
to_static_wstring(long value)5771 to_static_wstring(long value) noexcept
5772 {
5773 return detail::to_static_wstring_int_impl<
5774 std::numeric_limits<long>::digits10 + 2>(value);
5775 }
5776
5777 /// Converts `value` to a `static_wstring`
5778 static_wstring<std::numeric_limits<long long>::digits10 + 2>
5779 inline
to_static_wstring(long long value)5780 to_static_wstring(long long value) noexcept
5781 {
5782 return detail::to_static_wstring_int_impl<
5783 std::numeric_limits<long long>::digits10 + 2>(value);
5784 }
5785
5786 /// Converts `value` to a `static_wstring`
5787 static_wstring<std::numeric_limits<unsigned int>::digits10 + 1>
5788 inline
to_static_wstring(unsigned int value)5789 to_static_wstring(unsigned int value) noexcept
5790 {
5791 return detail::to_static_wstring_int_impl<
5792 std::numeric_limits<unsigned int>::digits10 + 1>(value);
5793 }
5794
5795 /// Converts `value` to a `static_wstring`
5796 static_wstring<std::numeric_limits<unsigned long>::digits10 + 1>
5797 inline
to_static_wstring(unsigned long value)5798 to_static_wstring(unsigned long value) noexcept
5799 {
5800 return detail::to_static_wstring_int_impl<
5801 std::numeric_limits<unsigned long>::digits10 + 1>(value);
5802 }
5803
5804 /// Converts `value` to a `static_wstring`
5805 static_wstring<std::numeric_limits<unsigned long long>::digits10 + 1>
5806 inline
to_static_wstring(unsigned long long value)5807 to_static_wstring(unsigned long long value) noexcept
5808 {
5809 return detail::to_static_wstring_int_impl<
5810 std::numeric_limits<unsigned long long>::digits10 + 1>(value);
5811 }
5812
5813 /// Converts `value` to a `static_wstring`
5814 static_wstring<std::numeric_limits<float>::max_digits10 + 4>
5815 inline
to_static_wstring(float value)5816 to_static_wstring(float value) noexcept
5817 {
5818 return detail::to_static_wstring_float_impl<
5819 std::numeric_limits<float>::max_digits10 + 4>(value);
5820 }
5821
5822 /// Converts `value` to a `static_wstring`
5823 static_wstring<std::numeric_limits<double>::max_digits10 + 4>
5824 inline
to_static_wstring(double value)5825 to_static_wstring(double value) noexcept
5826 {
5827 return detail::to_static_wstring_float_impl<
5828 std::numeric_limits<double>::max_digits10 + 4>(value);
5829 }
5830
5831 /// Converts `value` to a `static_wstring`
5832 static_wstring<std::numeric_limits<long double>::max_digits10 + 4>
5833 inline
to_static_wstring(long double value)5834 to_static_wstring(long double value) noexcept
5835 {
5836 return detail::to_static_wstring_float_impl<
5837 std::numeric_limits<long double>::max_digits10 + 4>(value);
5838 }
5839
5840 //------------------------------------------------------------------------------
5841 //
5842 // Deduction Guides
5843 //
5844 //------------------------------------------------------------------------------
5845
5846 #ifdef BOOST_STATIC_STRING_USE_DEDUCT
5847 template<std::size_t N, typename CharT>
5848 basic_static_string(CharT(&)[N]) ->
5849 basic_static_string<N, CharT, std::char_traits<CharT>>;
5850 #endif
5851
5852 //------------------------------------------------------------------------------
5853 //
5854 // Hashing
5855 //
5856 //------------------------------------------------------------------------------
5857
5858 #ifndef BOOST_STATIC_STRING_STANDALONE
5859 /// hash_value overload for Boost.Container_Hash
5860 template <std::size_t N,
5861 typename CharT,
5862 typename Traits>
5863 std::size_t
hash_value(const basic_static_string<N,CharT,Traits> & str)5864 hash_value(
5865 const basic_static_string<N, CharT, Traits>& str)
5866 {
5867 return boost::hash_range(str.begin(), str.end());
5868 }
5869 #endif
5870 } // static_strings
5871
5872 //------------------------------------------------------------------------------
5873 //
5874 // using Declarations
5875 //
5876 //------------------------------------------------------------------------------
5877
5878 using static_strings::static_string;
5879 using static_strings::static_wstring;
5880 using static_strings::static_u16string;
5881 using static_strings::static_u32string;
5882 } // boost
5883
5884 /// std::hash partial specialization for basic_static_string
5885 namespace std {
5886
5887 template<std::size_t N, typename CharT, typename Traits>
5888 struct hash<
5889 #ifdef BOOST_STATIC_STRING_DOCS
5890 basic_static_string
5891 #else
5892 boost::static_strings::basic_static_string<N, CharT, Traits>
5893 #endif
5894 >
5895 {
5896 std::size_t
operator ()std::hash5897 operator()(
5898 const boost::static_strings::basic_static_string<N, CharT, Traits>& str) const noexcept
5899 {
5900 #ifndef BOOST_STATIC_STRING_STANDALONE
5901 return boost::hash_range(str.begin(), str.end());
5902 #else
5903 using view_type = typename
5904 boost::static_strings::basic_string_view<CharT, Traits>;
5905 return std::hash<view_type>()(view_type(str.data(), str.size()));
5906 #endif
5907 }
5908 };
5909 } // std
5910
5911 //--------------------------------------------------------------------------
5912 //
5913 // Implementation
5914 //
5915 //--------------------------------------------------------------------------
5916
5917 #ifndef BOOST_STATIC_STRING_DOCS
5918 namespace boost {
5919 namespace static_strings {
5920
5921 template<std::size_t N, typename CharT, typename Traits>
5922 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5923 auto
5924 basic_static_string<N, CharT, Traits>::
assign(size_type count,value_type ch)5925 assign(
5926 size_type count,
5927 value_type ch) ->
5928 basic_static_string&
5929 {
5930 if (count > max_size())
5931 detail::throw_exception<std::length_error>(
5932 "count > max_size()");
5933 this->set_size(count);
5934 traits_type::assign(data(), size(), ch);
5935 return term();
5936 }
5937
5938 template<std::size_t N, typename CharT, typename Traits>
5939 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5940 auto
5941 basic_static_string<N, CharT, Traits>::
assign(const_pointer s,size_type count)5942 assign(
5943 const_pointer s,
5944 size_type count) ->
5945 basic_static_string&
5946 {
5947 if (count > max_size())
5948 detail::throw_exception<std::length_error>(
5949 "count > max_size()");
5950 this->set_size(count);
5951 traits_type::move(data(), s, size());
5952 return term();
5953 }
5954
5955 template<std::size_t N, typename CharT, typename Traits>
5956 template<typename InputIterator>
5957 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5958 auto
5959 basic_static_string<N, CharT, Traits>::
assign(InputIterator first,InputIterator last)5960 assign(
5961 InputIterator first,
5962 InputIterator last) ->
5963 typename std::enable_if<
5964 detail::is_input_iterator<InputIterator>::value,
5965 basic_static_string&>::type
5966 {
5967 auto ptr = data();
5968 for (std::size_t i = 0; first != last; ++first, ++ptr, ++i)
5969 {
5970 if (i >= max_size())
5971 {
5972 this->set_size(i);
5973 term();
5974 detail::throw_exception<std::length_error>("n > max_size()");
5975 }
5976 traits_type::assign(*ptr, *first);
5977 }
5978 this->set_size(ptr - data());
5979 return term();
5980 }
5981
5982 template<std::size_t N, typename CharT, typename Traits>
5983 BOOST_STATIC_STRING_CPP14_CONSTEXPR
5984 auto
5985 basic_static_string<N, CharT, Traits>::
insert(const_iterator pos,size_type count,value_type ch)5986 insert(
5987 const_iterator pos,
5988 size_type count,
5989 value_type ch) ->
5990 iterator
5991 {
5992 const auto curr_size = size();
5993 const auto curr_data = data();
5994 if (count > max_size() - curr_size)
5995 detail::throw_exception<std::length_error>(
5996 "count > max_size() - curr_size");
5997 const auto index = pos - curr_data;
5998 traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1);
5999 traits_type::assign(&curr_data[index], count, ch);
6000 this->set_size(curr_size + count);
6001 return &curr_data[index];
6002 }
6003
6004 template<std::size_t N, typename CharT, typename Traits>
6005 template<typename ForwardIterator>
6006 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6007 auto
6008 basic_static_string<N, CharT, Traits>::
insert(const_iterator pos,ForwardIterator first,ForwardIterator last)6009 insert(
6010 const_iterator pos,
6011 ForwardIterator first,
6012 ForwardIterator last) ->
6013 typename std::enable_if<
6014 detail::is_forward_iterator<
6015 ForwardIterator>::value, iterator>::type
6016 {
6017 const auto curr_size = size();
6018 const auto curr_data = data();
6019 const std::size_t count = detail::distance(first, last);
6020 const std::size_t index = pos - curr_data;
6021 const auto first_addr = &*first;
6022 if (count > max_size() - curr_size)
6023 detail::throw_exception<std::length_error>(
6024 "count > max_size() - curr_size");
6025 const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, first_addr);
6026 if (!inside || (inside && (first_addr + count <= pos)))
6027 {
6028 traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1);
6029 detail::copy_with_traits<Traits>(first, last, &curr_data[index]);
6030 }
6031 else
6032 {
6033 const size_type offset = first_addr - curr_data;
6034 traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1);
6035 if (offset < index)
6036 {
6037 const size_type diff = index - offset;
6038 traits_type::copy(&curr_data[index], &curr_data[offset], diff);
6039 traits_type::copy(&curr_data[index + diff], &curr_data[index + count], count - diff);
6040 }
6041 else
6042 {
6043 traits_type::copy(&curr_data[index], &curr_data[offset + count], count);
6044 }
6045 }
6046 this->set_size(curr_size + count);
6047 return curr_data + index;
6048 }
6049
6050 template<std::size_t N, typename CharT, typename Traits>
6051 template<typename InputIterator>
6052 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6053 auto
6054 basic_static_string<N, CharT, Traits>::
insert(const_iterator pos,InputIterator first,InputIterator last)6055 insert(
6056 const_iterator pos,
6057 InputIterator first,
6058 InputIterator last) ->
6059 typename std::enable_if<
6060 detail::is_input_iterator<
6061 InputIterator>::value &&
6062 !detail::is_forward_iterator<
6063 InputIterator>::value, iterator>::type
6064 {
6065 const auto curr_size = size();
6066 const auto curr_data = data();
6067 const auto count = read_back(false, first, last);
6068 const std::size_t index = pos - curr_data;
6069 std::rotate(&curr_data[index], &curr_data[curr_size + 1], &curr_data[curr_size + count + 1]);
6070 this->set_size(curr_size + count);
6071 return curr_data + index;
6072 }
6073
6074 template<std::size_t N, typename CharT, typename Traits>
6075 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6076 auto
6077 basic_static_string<N, CharT, Traits>::
erase(const_iterator first,const_iterator last)6078 erase(
6079 const_iterator first,
6080 const_iterator last) ->
6081 iterator
6082 {
6083 const auto curr_data = data();
6084 const std::size_t index = first - curr_data;
6085 traits_type::move(&curr_data[index], last, (end() - last) + 1);
6086 this->set_size(size() - std::size_t(last - first));
6087 return curr_data + index;
6088 }
6089
6090 template<std::size_t N, typename CharT, typename Traits>
6091 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6092 void
6093 basic_static_string<N, CharT, Traits>::
push_back(value_type ch)6094 push_back(
6095 value_type ch)
6096 {
6097 const auto curr_size = size();
6098 if (curr_size >= max_size())
6099 detail::throw_exception<std::length_error>(
6100 "curr_size >= max_size()");
6101 traits_type::assign(data()[curr_size], ch);
6102 this->set_size(curr_size + 1);
6103 term();
6104 }
6105
6106 template<std::size_t N, typename CharT, typename Traits>
6107 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6108 auto
6109 basic_static_string<N, CharT, Traits>::
append(size_type count,value_type ch)6110 append(
6111 size_type count,
6112 value_type ch) ->
6113 basic_static_string&
6114 {
6115 const auto curr_size = size();
6116 if (count > max_size() - curr_size)
6117 detail::throw_exception<std::length_error>(
6118 "count > max_size() - size()");
6119 traits_type::assign(end(), count, ch);
6120 this->set_size(curr_size + count);
6121 return term();
6122 }
6123
6124 template<std::size_t N, typename CharT, typename Traits>
6125 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6126 auto
6127 basic_static_string<N, CharT, Traits>::
append(const_pointer s,size_type count)6128 append(
6129 const_pointer s,
6130 size_type count) ->
6131 basic_static_string&
6132 {
6133 const auto curr_size = size();
6134 if (count > max_size() - curr_size)
6135 detail::throw_exception<std::length_error>(
6136 "count > max_size() - size()");
6137 traits_type::copy(end(), s, count);
6138 this->set_size(curr_size + count);
6139 return term();
6140 }
6141
6142 template<std::size_t N, typename CharT, typename Traits>
6143 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6144 void
6145 basic_static_string<N, CharT, Traits>::
resize(size_type n,value_type c)6146 resize(size_type n, value_type c)
6147 {
6148 if (n > max_size())
6149 detail::throw_exception<std::length_error>(
6150 "n > max_size()");
6151 const auto curr_size = size();
6152 if(n > curr_size)
6153 traits_type::assign(data() + curr_size, n - curr_size, c);
6154 this->set_size(n);
6155 term();
6156 }
6157
6158 template<std::size_t N, typename CharT, typename Traits>
6159 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6160 void
6161 basic_static_string<N, CharT, Traits>::
swap(basic_static_string & s)6162 swap(basic_static_string& s) noexcept
6163 {
6164 const auto curr_size = size();
6165 basic_static_string tmp(s);
6166 s.set_size(curr_size);
6167 traits_type::copy(&s.data()[0], data(), curr_size + 1);
6168 this->set_size(tmp.size());
6169 traits_type::copy(data(), tmp.data(), size() + 1);
6170 }
6171
6172 template<std::size_t N, typename CharT, typename Traits>
6173 template<std::size_t M>
6174 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6175 void
6176 basic_static_string<N, CharT, Traits>::
swap(basic_static_string<M,CharT,Traits> & s)6177 swap(basic_static_string<M, CharT, Traits>& s)
6178 {
6179 const auto curr_size = size();
6180 if (curr_size > s.max_size())
6181 detail::throw_exception<std::length_error>(
6182 "curr_size > s.max_size()");
6183 if (s.size() > max_size())
6184 detail::throw_exception<std::length_error>(
6185 "s.size() > max_size()");
6186 basic_static_string tmp(s);
6187 s.set_size(curr_size);
6188 traits_type::copy(&s.data()[0], data(), curr_size + 1);
6189 this->set_size(tmp.size());
6190 traits_type::copy(data(), &tmp.data()[0], size() + 1);
6191 }
6192
6193 template<std::size_t N, typename CharT, typename Traits>
6194 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6195 auto
6196 basic_static_string<N, CharT, Traits>::
replace(const_iterator i1,const_iterator i2,size_type n,value_type c)6197 replace(
6198 const_iterator i1,
6199 const_iterator i2,
6200 size_type n,
6201 value_type c) ->
6202 basic_static_string<N, CharT, Traits>&
6203 {
6204 const auto curr_size = size();
6205 const auto curr_data = data();
6206 const std::size_t n1 = i2 - i1;
6207 if (n > max_size() || curr_size - n1 >= max_size() - n)
6208 detail::throw_exception<std::length_error>(
6209 "replaced string exceeds max_size()");
6210 const auto pos = i1 - curr_data;
6211 traits_type::move(&curr_data[pos + n], i2, (end() - i2) + 1);
6212 traits_type::assign(&curr_data[pos], n, c);
6213 this->set_size((curr_size - n1) + n);
6214 return *this;
6215 }
6216
6217 template<std::size_t N, typename CharT, typename Traits>
6218 template<typename ForwardIterator>
6219 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6220 auto
6221 basic_static_string<N, CharT, Traits>::
replace(const_iterator i1,const_iterator i2,ForwardIterator j1,ForwardIterator j2)6222 replace(
6223 const_iterator i1,
6224 const_iterator i2,
6225 ForwardIterator j1,
6226 ForwardIterator j2) ->
6227 typename std::enable_if<
6228 detail::is_forward_iterator<ForwardIterator>::value,
6229 basic_static_string<N, CharT, Traits>&>::type
6230 {
6231 const auto curr_size = size();
6232 const auto curr_data = data();
6233 const auto first_addr = &*j1;
6234 const std::size_t n1 = i2 - i1;
6235 const std::size_t n2 = detail::distance(j1, j2);
6236 const std::size_t pos = i1 - curr_data;
6237 if (n2 > max_size() || curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2)
6238 detail::throw_exception<std::length_error>(
6239 "replaced string exceeds max_size()");
6240 const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, first_addr);
6241 if (inside && first_addr == i1 && n1 == n2)
6242 return *this;
6243 // Short circuit evaluation ensures that the pointer arithmetic is valid
6244 if (!inside || (inside && (first_addr + n2 <= i1)))
6245 {
6246 // source outside
6247 traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
6248 detail::copy_with_traits<Traits>(j1, j2, &curr_data[pos]);
6249 }
6250 else
6251 {
6252 // source inside
6253 const size_type offset = first_addr - curr_data;
6254 if (n2 >= n1)
6255 {
6256 // grow/unchanged
6257 const size_type diff = offset <= pos + n1 ? (std::min)((pos + n1) - offset, n2) : 0;
6258 // shift all right of splice point by n2 - n1 to the right
6259 traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
6260 // copy all before splice point
6261 traits_type::move(&curr_data[pos], &curr_data[offset], diff);
6262 // copy all after splice point
6263 traits_type::move(&curr_data[pos + diff], &curr_data[(offset - n1) + n2 + diff], n2 - diff);
6264 }
6265 else
6266 {
6267 // shrink
6268 // copy all elements into place
6269 traits_type::move(&curr_data[pos], &curr_data[offset], n2);
6270 // shift all elements after splice point left
6271 traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
6272 }
6273 }
6274 this->set_size((curr_size - n1) + n2);
6275 return *this;
6276 }
6277
6278 template<std::size_t N, typename CharT, typename Traits>
6279 template<typename InputIterator>
6280 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6281 auto
6282 basic_static_string<N, CharT, Traits>::
replace(const_iterator i1,const_iterator i2,InputIterator j1,InputIterator j2)6283 replace(
6284 const_iterator i1,
6285 const_iterator i2,
6286 InputIterator j1,
6287 InputIterator j2) ->
6288 typename std::enable_if<
6289 detail::is_input_iterator<
6290 InputIterator>::value &&
6291 !detail::is_forward_iterator<
6292 InputIterator>::value,
6293 basic_static_string<N, CharT, Traits>&>::type
6294 {
6295 const auto curr_size = size();
6296 const auto curr_data = data();
6297 const std::size_t n1 = detail::distance(i1, i2);
6298 const std::size_t n2 = read_back(false, j1, j2);
6299 const std::size_t pos = i1 - curr_data;
6300 // Rotate to the correct order. [i2, end] will now start with the replaced string,
6301 // continue to the existing string not being replaced, and end with a null terminator
6302 std::rotate(&curr_data[pos], &curr_data[curr_size + 1], &curr_data[curr_size + n2 + 1]);
6303 // Move everything from the end of the splice point to the end of the rotated string to
6304 // the begining of the splice point
6305 traits_type::move(&curr_data[pos + n2], &curr_data[pos + n2 + n1], ((curr_size - n1) + n2) - pos);
6306 this->set_size((curr_size - n1) + n2);
6307 return *this;
6308 }
6309
6310 template<std::size_t N, typename CharT, typename Traits>
6311 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6312 auto
6313 basic_static_string<N, CharT, Traits>::
find(const_pointer s,size_type pos,size_type n) const6314 find(
6315 const_pointer s,
6316 size_type pos,
6317 size_type n) const noexcept ->
6318 size_type
6319 {
6320 const auto curr_size = size();
6321 if (pos > curr_size || n > curr_size - pos)
6322 return npos;
6323 if (!n)
6324 return pos;
6325 const auto res = detail::search(data() + pos, data() + curr_size, s, s + n, traits_type::eq);
6326 return res == end() ? npos : detail::distance(data(), res);
6327 }
6328
6329 template<std::size_t N, typename CharT, typename Traits>
6330 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6331 auto
6332 basic_static_string<N, CharT, Traits>::
rfind(const_pointer s,size_type pos,size_type n) const6333 rfind(
6334 const_pointer s,
6335 size_type pos,
6336 size_type n) const noexcept ->
6337 size_type
6338 {
6339 const auto curr_size = size();
6340 const auto curr_data = data();
6341 if (curr_size < n)
6342 return npos;
6343 if (pos > curr_size - n)
6344 pos = curr_size - n;
6345 if (!n)
6346 return pos;
6347 for (auto sub = &curr_data[pos]; sub >= curr_data; --sub)
6348 if (!traits_type::compare(sub, s, n))
6349 return detail::distance(curr_data, sub);
6350 return npos;
6351 }
6352
6353 template<std::size_t N, typename CharT, typename Traits>
6354 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6355 auto
6356 basic_static_string<N, CharT, Traits>::
find_first_of(const_pointer s,size_type pos,size_type n) const6357 find_first_of(
6358 const_pointer s,
6359 size_type pos,
6360 size_type n) const noexcept ->
6361 size_type
6362 {
6363 const auto curr_data = data();
6364 if (pos >= size() || !n)
6365 return npos;
6366 const auto res = detail::find_first_of(&curr_data[pos], &curr_data[size()], s, &s[n], traits_type::eq);
6367 return res == end() ? npos : detail::distance(curr_data, res);
6368 }
6369
6370 template<std::size_t N, typename CharT, typename Traits>
6371 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6372 auto
6373 basic_static_string<N, CharT, Traits>::
find_last_of(const_pointer s,size_type pos,size_type n) const6374 find_last_of(
6375 const_pointer s,
6376 size_type pos,
6377 size_type n) const noexcept ->
6378 size_type
6379 {
6380 const auto curr_size = size();
6381 if (!n)
6382 return npos;
6383 if (pos >= curr_size)
6384 pos = 0;
6385 else
6386 pos = curr_size - (pos + 1);
6387 const auto res = detail::find_first_of(rbegin() + pos, rend(), s, &s[n], traits_type::eq);
6388 return res == rend() ? npos : curr_size - 1 - detail::distance(rbegin(), res);
6389 }
6390
6391 template<std::size_t N, typename CharT, typename Traits>
6392 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6393 auto
6394 basic_static_string<N, CharT, Traits>::
find_first_not_of(const_pointer s,size_type pos,size_type n) const6395 find_first_not_of(
6396 const_pointer s,
6397 size_type pos,
6398 size_type n) const noexcept ->
6399 size_type
6400 {
6401 if (pos >= size())
6402 return npos;
6403 if (!n)
6404 return pos;
6405 const auto res = detail::find_not_of<Traits>(data() + pos, data() + size(), s, n);
6406 return res == end() ? npos : detail::distance(data(), res);
6407 }
6408
6409 template<std::size_t N, typename CharT, typename Traits>
6410 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6411 auto
6412 basic_static_string<N, CharT, Traits>::
find_last_not_of(const_pointer s,size_type pos,size_type n) const6413 find_last_not_of(
6414 const_pointer s,
6415 size_type pos,
6416 size_type n) const noexcept ->
6417 size_type
6418 {
6419 const auto curr_size = size();
6420 if (pos >= curr_size)
6421 pos = curr_size - 1;
6422 if (!n)
6423 return pos;
6424 pos = curr_size - (pos + 1);
6425 const auto res = detail::find_not_of<Traits>(rbegin() + pos, rend(), s, n);
6426 return res == rend() ? npos : curr_size - 1 - detail::distance(rbegin(), res);
6427 }
6428
6429 template<std::size_t N, typename CharT, typename Traits>
6430 template<typename InputIterator>
6431 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6432 auto
6433 basic_static_string<N, CharT, Traits>::
read_back(bool overwrite_null,InputIterator first,InputIterator last)6434 read_back(
6435 bool overwrite_null,
6436 InputIterator first,
6437 InputIterator last) ->
6438 size_type
6439 {
6440 const auto curr_data = data();
6441 auto new_size = size();
6442 for (; first != last; ++first)
6443 {
6444 if (new_size >= max_size())
6445 {
6446 // if we overwrote the null terminator,
6447 // put it back
6448 if (overwrite_null)
6449 term();
6450 detail::throw_exception<std::length_error>(
6451 "count > max_size() - size()");
6452 }
6453 traits_type::assign(curr_data[new_size++ + (!overwrite_null)], *first);
6454 }
6455 return new_size - size();
6456 }
6457
6458 template<std::size_t N, typename CharT, typename Traits>
6459 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6460 auto
6461 basic_static_string<N, CharT, Traits>::
replace_unchecked(const_iterator i1,const_iterator i2,const_pointer s,size_type n2)6462 replace_unchecked(
6463 const_iterator i1,
6464 const_iterator i2,
6465 const_pointer s,
6466 size_type n2) ->
6467 basic_static_string&
6468 {
6469 const auto curr_data = data();
6470 const auto curr_size = size();
6471 const std::size_t pos = i1 - curr_data;
6472 const std::size_t n1 = i2 - i1;
6473 if (n2 > max_size() || curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2)
6474 detail::throw_exception<std::length_error>(
6475 "replaced string exceeds max_size()");
6476 traits_type::move(&curr_data[pos + n2], i2, (end() - i2) + 1);
6477 traits_type::copy(&curr_data[pos], s, n2);
6478 this->set_size((curr_size - n1) + n2);
6479 return *this;
6480 }
6481
6482 template<std::size_t N, typename CharT, typename Traits>
6483 BOOST_STATIC_STRING_CPP14_CONSTEXPR
6484 auto
6485 basic_static_string<N, CharT, Traits>::
insert_unchecked(const_iterator pos,const_pointer s,size_type count)6486 insert_unchecked(
6487 const_iterator pos,
6488 const_pointer s,
6489 size_type count) ->
6490 iterator
6491 {
6492 const auto curr_data = data();
6493 const auto curr_size = size();
6494 if (count > max_size() - curr_size)
6495 detail::throw_exception<std::length_error>(
6496 "count > max_size() - curr_size");
6497 const std::size_t index = pos - curr_data;
6498 traits_type::move(&curr_data[index + count], pos, (end() - pos) + 1);
6499 traits_type::copy(&curr_data[index], s, count);
6500 this->set_size(curr_size + count);
6501 return curr_data + index;
6502 }
6503 } // static_strings
6504 } // boost
6505 #endif
6506 #endif
6507