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

source code of boost/libs/static_string/include/boost/static_string/static_string.hpp