proxygen
FixedString.h
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // @author: Eric Niebler (eniebler)
18 // Fixed-size string type, for constexpr string handling.
19 
20 #pragma once
21 
22 #include <cassert>
23 #include <cstddef>
24 #include <initializer_list>
25 #include <iosfwd>
26 #include <stdexcept>
27 #include <string>
28 #include <type_traits>
29 #include <utility>
30 
31 #include <folly/ConstexprMath.h>
32 #include <folly/Portability.h>
33 #include <folly/Range.h>
34 #include <folly/Utility.h>
35 #include <folly/lang/Exception.h>
36 #include <folly/lang/Ordering.h>
38 
39 namespace folly {
40 
41 template <class Char, std::size_t N>
43 
44 template <std::size_t N>
46 
47 namespace detail {
48 namespace fixedstring {
49 
50 // This is a template so that the class static npos can be defined in the
51 // header.
52 template <class = void>
54  static constexpr std::size_t npos = static_cast<std::size_t>(-1);
55 };
56 
57 template <class Void>
58 constexpr std::size_t FixedStringBase_<Void>::npos;
59 
61 
62 // Intentionally NOT constexpr. By making this not constexpr, we make
63 // checkOverflow below ill-formed in a constexpr context when the condition
64 // it's testing for fails. In this way, precondition violations are reported
65 // at compile-time instead of at runtime.
66 [[noreturn]] inline void assertOutOfBounds() {
67  assert(!"Array index out of bounds in BasicFixedString");
68  throw_exception<std::out_of_range>(
69  "Array index out of bounds in BasicFixedString");
70 }
71 
72 constexpr std::size_t checkOverflow(std::size_t i, std::size_t max) {
73  return i <= max ? i : (void(assertOutOfBounds()), max);
74 }
75 
76 constexpr std::size_t checkOverflowOrNpos(std::size_t i, std::size_t max) {
77  return i == FixedStringBase::npos
78  ? max
79  : (i <= max ? i : (void(assertOutOfBounds()), max));
80 }
81 
82 // Intentionally NOT constexpr. See note above for assertOutOfBounds
83 [[noreturn]] inline void assertNotNullTerminated() noexcept {
84  assert(!"Non-null terminated string used to initialize a BasicFixedString");
85  std::terminate(); // Fail hard, fail fast.
86 }
87 
88 // Parsing help for human readers: the following is a constexpr noexcept
89 // function that accepts a reference to an array as a parameter and returns
90 // a reference to the same array.
91 template <class Char, std::size_t N>
92 constexpr const Char (&checkNullTerminated(const Char (&a)[N]) noexcept)[N] {
93  // Strange decltype(a)(a) used to make MSVC happy.
94  return a[N - 1u] == Char(0)
95 #ifndef NDEBUG
96  // In Debug mode, guard against embedded nulls:
98 #endif
99  ? decltype(a)(a)
100  : (assertNotNullTerminated(), decltype(a)(a));
101 }
102 
103 // Rather annoyingly, GCC's -Warray-bounds warning issues false positives for
104 // this code. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61971
105 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
106 #pragma GCC diagnostic push
107 #pragma GCC diagnostic ignored "-Warray-bounds"
108 #endif
109 
110 template <class Left, class Right>
111 constexpr ordering compare_(
112  const Left& left,
113  std::size_t left_pos,
114  std::size_t left_size,
115  const Right& right,
116  std::size_t right_pos,
117  std::size_t right_size) noexcept {
118  return left_pos == left_size
119  ? (right_pos == right_size ? ordering::eq : ordering::lt)
120  : (right_pos == right_size ? ordering::gt
121  : (left[left_pos] < right[right_pos]
122  ? ordering::lt
123  : (left[left_pos] > right[right_pos]
124  ? ordering::gt
126  left,
127  left_pos + 1u,
128  left_size,
129  right,
130  right_pos + 1u,
131  right_size))));
132 }
133 
134 template <class Left, class Right>
135 constexpr bool equal_(
136  const Left& left,
137  std::size_t left_size,
138  const Right& right,
139  std::size_t right_size) noexcept {
140  return left_size == right_size &&
141  ordering::eq == compare_(left, 0u, left_size, right, 0u, right_size);
142 }
143 
144 template <class Char, class Left, class Right>
145 constexpr Char char_at_(
146  const Left& left,
147  std::size_t left_count,
148  const Right& right,
149  std::size_t right_count,
150  std::size_t i) noexcept {
151  return i < left_count
152  ? left[i]
153  : i < (left_count + right_count) ? right[i - left_count] : Char(0);
154 }
155 
156 template <class Char, class Left, class Right>
157 constexpr Char char_at_(
158  const Left& left,
159  std::size_t left_size,
160  std::size_t left_pos,
161  std::size_t left_count,
162  const Right& right,
163  std::size_t right_pos,
164  std::size_t right_count,
165  std::size_t i) noexcept {
166  return i < left_pos
167  ? left[i]
168  : (i < right_count + left_pos ? right[i - left_pos + right_pos]
169  : (i < left_size - left_count + right_count
170  ? left[i - right_count + left_count]
171  : Char(0)));
172 }
173 
174 template <class Left, class Right>
175 constexpr bool find_at_(
176  const Left& left,
177  const Right& right,
178  std::size_t pos,
179  std::size_t count) noexcept {
180  return 0u == count ||
181  (left[pos + count - 1u] == right[count - 1u] &&
182  find_at_(left, right, pos, count - 1u));
183 }
184 
185 template <class Char, class Right>
186 constexpr bool
187 find_one_of_at_(Char ch, const Right& right, std::size_t pos) noexcept {
188  return 0u != pos &&
189  (ch == right[pos - 1u] || find_one_of_at_(ch, right, pos - 1u));
190 }
191 
192 template <class Left, class Right>
193 constexpr std::size_t find_(
194  const Left& left,
195  std::size_t left_size,
196  const Right& right,
197  std::size_t pos,
198  std::size_t count) noexcept {
199  return find_at_(left, right, pos, count) ? pos
200  : left_size <= pos + count
202  : find_(left, left_size, right, pos + 1u, count);
203 }
204 
205 template <class Left, class Right>
206 constexpr std::size_t rfind_(
207  const Left& left,
208  const Right& right,
209  std::size_t pos,
210  std::size_t count) noexcept {
211  return find_at_(left, right, pos, count)
212  ? pos
213  : 0u == pos ? FixedStringBase::npos
214  : rfind_(left, right, pos - 1u, count);
215 }
216 
217 template <class Left, class Right>
218 constexpr std::size_t find_first_of_(
219  const Left& left,
220  std::size_t left_size,
221  const Right& right,
222  std::size_t pos,
223  std::size_t count) noexcept {
224  return find_one_of_at_(left[pos], right, count) ? pos
225  : left_size <= pos + 1u
227  : find_first_of_(left, left_size, right, pos + 1u, count);
228 }
229 
230 template <class Left, class Right>
231 constexpr std::size_t find_first_not_of_(
232  const Left& left,
233  std::size_t left_size,
234  const Right& right,
235  std::size_t pos,
236  std::size_t count) noexcept {
237  return !find_one_of_at_(left[pos], right, count) ? pos
238  : left_size <= pos + 1u
240  : find_first_not_of_(left, left_size, right, pos + 1u, count);
241 }
242 
243 template <class Left, class Right>
244 constexpr std::size_t find_last_of_(
245  const Left& left,
246  const Right& right,
247  std::size_t pos,
248  std::size_t count) noexcept {
249  return find_one_of_at_(left[pos], right, count)
250  ? pos
251  : 0u == pos ? FixedStringBase::npos
252  : find_last_of_(left, right, pos - 1u, count);
253 }
254 
255 template <class Left, class Right>
256 constexpr std::size_t find_last_not_of_(
257  const Left& left,
258  const Right& right,
259  std::size_t pos,
260  std::size_t count) noexcept {
261  return !find_one_of_at_(left[pos], right, count)
262  ? pos
263  : 0u == pos ? FixedStringBase::npos
264  : find_last_not_of_(left, right, pos - 1u, count);
265 }
266 
267 struct Helper {
268  template <class Char, class Left, class Right, std::size_t... Is>
269  static constexpr BasicFixedString<Char, sizeof...(Is)> concat_(
270  const Left& left,
271  std::size_t left_count,
272  const Right& right,
273  std::size_t right_count,
275  return {left, left_count, right, right_count, is};
276  }
277 
278  template <class Char, class Left, class Right, std::size_t... Is>
279  static constexpr BasicFixedString<Char, sizeof...(Is)> replace_(
280  const Left& left,
281  std::size_t left_size,
282  std::size_t left_pos,
283  std::size_t left_count,
284  const Right& right,
285  std::size_t right_pos,
286  std::size_t right_count,
288  return {left,
289  left_size,
290  left_pos,
291  left_count,
292  right,
293  right_pos,
294  right_count,
295  is};
296  }
297 
298  template <class Char, std::size_t N>
299  static constexpr const Char (
300  &data_(const BasicFixedString<Char, N>& that) noexcept)[N + 1u] {
301  return that.data_;
302  }
303 };
304 
305 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 4
306 #pragma GCC diagnostic pop
307 #endif
308 
309 template <class T>
311  noexcept(a = T(std::move(a)))) {
312  T tmp((std::move(a)));
313  a = std::move(b);
314  b = std::move(tmp);
315 }
316 
317 // For constexpr reverse iteration over a BasicFixedString
318 template <class T>
320  private:
321  T* p_ = nullptr;
322  struct dummy_ {
323  T* p_ = nullptr;
324  };
325  using other = typename std::conditional<
329 
330  public:
332  using reference = T&;
333  using pointer = T*;
334  using difference_type = std::ptrdiff_t;
335  using iterator_category = std::random_access_iterator_tag;
336 
337  constexpr ReverseIterator() = default;
338  constexpr ReverseIterator(const ReverseIterator&) = default;
340  default;
341  constexpr explicit ReverseIterator(T* p) noexcept : p_(p) {}
342  constexpr /* implicit */ ReverseIterator(const other& that) noexcept
343  : p_(that.p_) {}
344  friend constexpr bool operator==(
347  return a.p_ == b.p_;
348  }
349  friend constexpr bool operator!=(
352  return !(a == b);
353  }
354  constexpr reference operator*() const {
355  return *(p_ - 1);
356  }
358  --p_;
359  return *this;
360  }
362  auto tmp(*this);
363  --p_;
364  return tmp;
365  }
367  ++p_;
368  return *this;
369  }
371  auto tmp(*this);
372  ++p_;
373  return tmp;
374  }
376  p_ -= i;
377  return *this;
378  }
379  friend constexpr ReverseIterator operator+(
380  std::ptrdiff_t i,
381  ReverseIterator that) noexcept {
382  return ReverseIterator{that.p_ - i};
383  }
384  friend constexpr ReverseIterator operator+(
385  ReverseIterator that,
386  std::ptrdiff_t i) noexcept {
387  return ReverseIterator{that.p_ - i};
388  }
390  p_ += i;
391  return *this;
392  }
393  friend constexpr ReverseIterator operator-(
394  ReverseIterator that,
395  std::ptrdiff_t i) noexcept {
396  return ReverseIterator{that.p_ + i};
397  }
398  friend constexpr std::ptrdiff_t operator-(
401  return b.p_ - a.p_;
402  }
403  constexpr reference operator[](std::ptrdiff_t i) const noexcept {
404  return *(*this + i);
405  }
406 };
407 
408 } // namespace fixedstring
409 } // namespace detail
410 
411 // Defined in folly/hash/Hash.h
412 std::uint32_t hsieh_hash32_buf(const void* buf, std::size_t len);
413 
512 template <class Char, std::size_t N>
514  private:
515  template <class, std::size_t>
516  friend class BasicFixedString;
518 
519  // FUTURE: use constexpr_log2 to fold instantiations of BasicFixedString
520  // together. All BasicFixedString<C, N> instantiations could share the
521  // implementation of BasicFixedString<C, M>, where M is the next highest power
522  // of 2 after N.
523  //
524  // Also, because of alignment of the data_ and size_ members, N should never
525  // be smaller than `(alignof(std::size_t)/sizeof(C))-1` (-1 because of the
526  // null terminator). OR, create a specialization for BasicFixedString<C, 0u>
527  // that does not have a size_ member, since it is unnecessary.
528  Char data_[N + 1u]; // +1 for the null terminator
529  std::size_t size_; // Nbr of chars, not incl. null terminator. size_ <= N.
530 
532 
533  template <class That, std::size_t... Is>
534  constexpr BasicFixedString(
535  const That& that,
536  std::size_t size,
538  std::size_t pos = 0,
539  std::size_t count = npos) noexcept
540  : data_{(Is < (size - pos) && Is < count ? that[Is + pos] : Char(0))...,
541  Char(0)},
542  size_{folly::constexpr_min(size - pos, count)} {}
543 
544  template <std::size_t... Is>
545  constexpr BasicFixedString(
546  std::size_t count,
547  Char ch,
549  : data_{((Is < count) ? ch : Char(0))..., Char(0)}, size_{count} {}
550 
551  // Concatenation constructor
552  template <class Left, class Right, std::size_t... Is>
553  constexpr BasicFixedString(
554  const Left& left,
555  std::size_t left_size,
556  const Right& right,
557  std::size_t right_size,
559  : data_{detail::fixedstring::char_at_<Char>(
560  left,
561  left_size,
562  right,
563  right_size,
564  Is)...,
565  Char(0)},
566  size_{left_size + right_size} {}
567 
568  // Replace constructor
569  template <class Left, class Right, std::size_t... Is>
570  constexpr BasicFixedString(
571  const Left& left,
572  std::size_t left_size,
573  std::size_t left_pos,
574  std::size_t left_count,
575  const Right& right,
576  std::size_t right_pos,
577  std::size_t right_count,
579  : data_{detail::fixedstring::char_at_<Char>(
580  left,
581  left_size,
582  left_pos,
583  left_count,
584  right,
585  right_pos,
586  right_count,
587  Is)...,
588  Char(0)},
589  size_{left_size - left_count + right_count} {}
590 
591  public:
592  using size_type = std::size_t;
593  using difference_type = std::ptrdiff_t;
594  using reference = Char&;
595  using const_reference = const Char&;
596  using pointer = Char*;
597  using const_pointer = const Char*;
598  using iterator = Char*;
599  using const_iterator = const Char*;
601  using const_reverse_iterator =
603 
605 
611  constexpr BasicFixedString() : data_{}, size_{} {}
612 
619  constexpr BasicFixedString(const BasicFixedString& /*that*/) = default;
620 
633  template <std::size_t M>
634  constexpr /* implicit */ BasicFixedString(
635  const BasicFixedString<Char, M>& that) noexcept(M <= N)
636  : BasicFixedString{that, 0u, that.size_} {}
637 
638  // Why is this deleted? To avoid confusion with the constructor that takes
639  // a const Char* and a count.
640  template <std::size_t M>
641  constexpr BasicFixedString(
642  const BasicFixedString<Char, M>& that,
643  std::size_t pos) noexcept(false) = delete;
644 
659  template <std::size_t M>
660  constexpr BasicFixedString(
661  const BasicFixedString<Char, M>& that,
662  std::size_t pos,
663  std::size_t count) noexcept(false)
665  that.data_,
666  that.size_,
668  pos,
671  count,
672  that.size_ -
674  N)} {}
675 
684  template <std::size_t M, class = typename std::enable_if<(M - 1u <= N)>::type>
685  constexpr /* implicit */ BasicFixedString(const Char (&that)[M]) noexcept
687  M - 1u,
688  folly::make_index_sequence<M - 1u>{}} {}
689 
699  constexpr BasicFixedString(const Char* that, std::size_t count) noexcept(
700  false)
701  : BasicFixedString{that,
703  Indices{}} {}
704 
714  constexpr BasicFixedString(std::size_t count, Char ch) noexcept(false)
716  ch,
717  Indices{}} {}
718 
728  constexpr BasicFixedString(std::initializer_list<Char> il) noexcept(false)
729  : BasicFixedString{il.begin(), il.size()} {}
730 
732  const BasicFixedString&) noexcept = default;
733 
747  template <std::size_t M>
749  const BasicFixedString<Char, M>& that) noexcept(M <= N) {
751  size_ = that.copy(data_, that.size_);
752  data_[size_] = Char(0);
753  return *this;
754  }
755 
766  template <std::size_t M, class = typename std::enable_if<(M - 1u <= N)>::type>
768  const Char (&that)[M]) noexcept {
769  return assign(detail::fixedstring::checkNullTerminated(that), M - 1u);
770  }
771 
782  std::initializer_list<Char> il) noexcept(false) {
784  for (std::size_t i = 0u; i < il.size(); ++i) {
785  data_[i] = il.begin()[i];
786  }
787  size_ = il.size();
788  data_[size_] = Char(0);
789  return *this;
790  }
791 
797  return {begin(), end()};
798  }
799 
803  constexpr Range<const Char*> toRange() const noexcept {
804  return {begin(), end()};
805  }
806 
811  /* implicit */ operator std::basic_string<Char>() const noexcept(false) {
812  return std::basic_string<Char>{begin(), end()};
813  }
814 
815  std::basic_string<Char> toStdString() const noexcept(false) {
816  return std::basic_string<Char>{begin(), end()};
817  }
818 
819  // Think hard about whether this is a good idea. It's certainly better than
820  // an implicit conversion to `const Char*` since `delete "hi"_fs` will fail
821  // to compile. But it creates ambiguities when passing a FixedString to an
822  // API that has overloads for `const char*` and `folly::Range`, for instance.
823  // using ArrayType = Char[N];
824  // FOLLY_CPP14_CONSTEXPR /* implicit */ operator ArrayType&() noexcept {
825  // return data_;
826  // }
827 
828  // using ConstArrayType = const Char[N];
829  // constexpr /* implicit */ operator ConstArrayType&() const noexcept {
830  // return data_;
831  // }
832 
845  std::size_t count,
846  Char ch) noexcept(false) {
848  for (std::size_t i = 0u; i < count; ++i) {
849  data_[i] = ch;
850  }
851  size_ = count;
852  data_[size_] = Char(0);
853  return *this;
854  }
855 
860  template <std::size_t M>
862  const BasicFixedString<Char, M>& that) noexcept(M <= N) {
863  return *this = that;
864  }
865 
866  // Why is this overload deleted? So users aren't confused by the difference
867  // between str.assign("foo", N) and str.assign("foo"_fs, N). In the former,
868  // N is a count of characters. In the latter, it would be a position, which
869  // totally changes the meaning of the code.
870  template <std::size_t M>
872  const BasicFixedString<Char, M>& that,
873  std::size_t pos) noexcept(false) = delete;
874 
892  template <std::size_t M>
894  const BasicFixedString<Char, M>& that,
895  std::size_t pos,
896  std::size_t count) noexcept(false) {
898  return assign(
899  that.data_ + pos,
901  }
902 
909  template <std::size_t M, class = typename std::enable_if<(M - 1u <= N)>::type>
911  const Char (&that)[M]) noexcept {
912  return assign(detail::fixedstring::checkNullTerminated(that), M - 1u);
913  }
914 
928  const Char* that,
929  std::size_t count) noexcept(false) {
931  for (std::size_t i = 0u; i < count; ++i) {
932  data_[i] = that[i];
933  }
934  size_ = count;
935  data_[size_] = Char(0);
936  return *this;
937  }
938 
943  // less-than-or-equal here to copy the null terminator:
944  for (std::size_t i = 0u; i <= folly::constexpr_max(size_, that.size_);
945  ++i) {
947  }
949  }
950 
955  FOLLY_CPP14_CONSTEXPR Char* data() noexcept {
956  return data_;
957  }
958 
962  constexpr const Char* data() const noexcept {
963  return data_;
964  }
965 
969  constexpr const Char* c_str() const noexcept {
970  return data_;
971  }
972 
976  FOLLY_CPP14_CONSTEXPR Char* begin() noexcept {
977  return data_;
978  }
979 
983  constexpr const Char* begin() const noexcept {
984  return data_;
985  }
986 
990  constexpr const Char* cbegin() const noexcept {
991  return begin();
992  }
993 
997  FOLLY_CPP14_CONSTEXPR Char* end() noexcept {
998  return data_ + size_;
999  }
1000 
1004  constexpr const Char* end() const noexcept {
1005  return data_ + size_;
1006  }
1007 
1011  constexpr const Char* cend() const noexcept {
1012  return end();
1013  }
1014 
1020  return reverse_iterator{data_ + size_};
1021  }
1022 
1026  constexpr const_reverse_iterator rbegin() const noexcept {
1027  return const_reverse_iterator{data_ + size_};
1028  }
1029 
1033  constexpr const_reverse_iterator crbegin() const noexcept {
1034  return rbegin();
1035  }
1036 
1042  return reverse_iterator{data_};
1043  }
1044 
1048  constexpr const_reverse_iterator rend() const noexcept {
1049  return const_reverse_iterator{data_};
1050  }
1051 
1055  constexpr const_reverse_iterator crend() const noexcept {
1056  return rend();
1057  }
1058 
1062  constexpr std::size_t size() const noexcept {
1063  return size_;
1064  }
1065 
1069  constexpr std::size_t length() const noexcept {
1070  return size_;
1071  }
1072 
1076  constexpr bool empty() const noexcept {
1077  return 0u == size_;
1078  }
1079 
1083  static constexpr std::size_t capacity() noexcept {
1084  return N;
1085  }
1086 
1090  static constexpr std::size_t max_size() noexcept {
1091  return N;
1092  }
1093 
1094  // We would need to reimplement folly::Hash to make this
1095  // constexpr. :-(
1096  std::uint32_t hash() const noexcept {
1097  return folly::hsieh_hash32_buf(data_, size_);
1098  }
1099 
1105  FOLLY_CPP14_CONSTEXPR Char& at(std::size_t i) noexcept(false) {
1106  return i <= size_ ? data_[i]
1107  : (throw_exception<std::out_of_range>(
1108  "Out of range in BasicFixedString::at"),
1109  data_[size_]);
1110  }
1111 
1115  constexpr const Char& at(std::size_t i) const noexcept(false) {
1116  return i <= size_ ? data_[i]
1117  : (throw_exception<std::out_of_range>(
1118  "Out of range in BasicFixedString::at"),
1119  data_[size_]);
1120  }
1121 
1127  FOLLY_CPP14_CONSTEXPR Char& operator[](std::size_t i) noexcept {
1128 #ifdef NDEBUG
1129  return data_[i];
1130 #else
1131  return data_[detail::fixedstring::checkOverflow(i, size_)];
1132 #endif
1133  }
1134 
1138  constexpr const Char& operator[](std::size_t i) const noexcept {
1139 #ifdef NDEBUG
1140  return data_[i];
1141 #else
1142  return data_[detail::fixedstring::checkOverflow(i, size_)];
1143 #endif
1144  }
1145 
1149  FOLLY_CPP14_CONSTEXPR Char& front() noexcept {
1150  return (*this)[0u];
1151  }
1152 
1156  constexpr const Char& front() const noexcept {
1157  return (*this)[0u];
1158  }
1159 
1164  FOLLY_CPP14_CONSTEXPR Char& back() noexcept {
1165 #ifdef NDEBUG
1166  return data_[size_ - 1u];
1167 #else
1168  return data_[size_ - detail::fixedstring::checkOverflow(1u, size_)];
1169 #endif
1170  }
1171 
1175  constexpr const Char& back() const noexcept {
1176 #ifdef NDEBUG
1177  return data_[size_ - 1u];
1178 #else
1179  return data_[size_ - detail::fixedstring::checkOverflow(1u, size_)];
1180 #endif
1181  }
1182 
1188  FOLLY_CPP14_CONSTEXPR void clear() noexcept {
1189  data_[0u] = Char(0);
1190  size_ = 0u;
1191  }
1192 
1197  detail::fixedstring::checkOverflow(1u, N - size_);
1198  data_[size_] = ch;
1199  data_[++size_] = Char(0);
1200  }
1201 
1205  constexpr BasicFixedString<Char, N + 1u> cpush_back(Char ch) const noexcept {
1206  return cappend(ch);
1207  }
1208 
1217  FOLLY_CPP14_CONSTEXPR void pop_back() noexcept(false) {
1219  --size_;
1220  data_[size_] = Char(0);
1221  }
1222 
1229  constexpr BasicFixedString<Char, N - 1u> cpop_back() const noexcept(false) {
1230  return {*this, 0u, size_ - detail::fixedstring::checkOverflow(1u, size_)};
1231  }
1232 
1241  std::size_t count,
1242  Char ch) noexcept(false) {
1244  for (std::size_t i = 0u; i < count; ++i) {
1245  data_[size_ + i] = ch;
1246  }
1247  size_ += count;
1248  data_[size_] = Char(0);
1249  return *this;
1250  }
1251 
1255  template <std::size_t M>
1257  const BasicFixedString<Char, M>& that) noexcept(false) {
1258  return append(that, 0u, that.size_);
1259  }
1260 
1261  // Why is this overload deleted? So as not to get confused with
1262  // append("null-terminated", N), where N would be a count instead
1263  // of a position.
1264  template <std::size_t M>
1266  const BasicFixedString<Char, M>& that,
1267  std::size_t pos) noexcept(false) = delete;
1268 
1285  template <std::size_t M>
1287  const BasicFixedString<Char, M>& that,
1288  std::size_t pos,
1289  std::size_t count) noexcept(false) {
1293  for (std::size_t i = 0u; i < count; ++i) {
1294  data_[size_ + i] = that.data_[pos + i];
1295  }
1296  size_ += count;
1297  data_[size_] = Char(0);
1298  return *this;
1299  }
1300 
1305  false) {
1306  return append(that, folly::constexpr_strlen(that));
1307  }
1308 
1319  const Char* that,
1320  std::size_t count) noexcept(false) {
1322  for (std::size_t i = 0u; i < count; ++i) {
1323  data_[size_ + i] = that[i];
1324  }
1325  size_ += count;
1326  data_[size_] = Char(0);
1327  return *this;
1328  }
1329 
1335  constexpr BasicFixedString<Char, N + 1u> cappend(Char ch) const noexcept {
1336  return *this + ch;
1337  }
1338 
1344  template <std::size_t M>
1346  const BasicFixedString<Char, M>& that) const noexcept {
1347  return *this + that;
1348  }
1349 
1350  // Deleted to avoid confusion with append("char*", N), where N is a count
1351  // instead of a position.
1352  template <std::size_t M>
1353  constexpr BasicFixedString<Char, N + M> cappend(
1354  const BasicFixedString<Char, M>& that,
1355  std::size_t pos) const noexcept(false) = delete;
1356 
1362  template <std::size_t M>
1364  const BasicFixedString<Char, M>& that,
1365  std::size_t pos,
1366  std::size_t count) const noexcept(false) {
1367  return creplace(size_, 0u, that, pos, count);
1368  }
1369 
1375  template <std::size_t M>
1376  constexpr BasicFixedString<Char, N + M - 1u> cappend(
1377  const Char (&that)[M]) const noexcept {
1378  return creplace(size_, 0u, that);
1379  }
1380 
1381  // Deleted to avoid confusion with append("char*", N), where N is a count
1382  // instead of a position
1383  template <std::size_t M>
1384  constexpr BasicFixedString<Char, N + M - 1u> cappend(
1385  const Char (&that)[M],
1386  std::size_t pos) const noexcept(false) = delete;
1387 
1393  template <std::size_t M>
1394  constexpr BasicFixedString<Char, N + M - 1u>
1395  cappend(const Char (&that)[M], std::size_t pos, std::size_t count) const
1396  noexcept(false) {
1397  return creplace(size_, 0u, that, pos, count);
1398  }
1399 
1405  false) {
1406  return append(that);
1407  }
1408 
1413  template <std::size_t M>
1415  const BasicFixedString<Char, M>& that) noexcept(false) {
1416  return append(that, 0u, that.size_);
1417  }
1418 
1424  push_back(ch);
1425  return *this;
1426  }
1427 
1433  std::initializer_list<Char> il) noexcept(false) {
1434  return append(il.begin(), il.size());
1435  }
1436 
1443  clear();
1444  return *this;
1445  }
1446 
1458  std::size_t pos,
1459  std::size_t count = npos) noexcept(false) {
1460  using A = const Char[1];
1461  return replace(
1462  pos,
1464  count, size_ - detail::fixedstring::checkOverflow(pos, size_)),
1465  A{Char(0)},
1466  0u);
1467  }
1468 
1473  FOLLY_CPP14_CONSTEXPR Char* erase(const Char* first) noexcept(false) {
1474  erase(first - data_, 1u);
1475  return data_ + (first - data_);
1476  }
1477 
1483  const Char* first,
1484  const Char* last) noexcept(false) {
1485  erase(first - data_, last - first);
1486  return data_ + (first - data_);
1487  }
1488 
1493  constexpr BasicFixedString<Char, 0u> cerase() const noexcept {
1494  return {};
1495  }
1496 
1502  constexpr BasicFixedString cerase(std::size_t pos, std::size_t count = npos)
1503  const noexcept(false) {
1504  using A = const Char[1];
1505  return creplace(
1506  pos,
1508  count, size_ - detail::fixedstring::checkOverflow(pos, size_)),
1509  A{Char(0)});
1510  }
1511 
1517  template <std::size_t M>
1518  constexpr int compare(const BasicFixedString<Char, M>& that) const noexcept {
1519  return compare(0u, size_, that, 0u, that.size_);
1520  }
1521 
1527  template <std::size_t M>
1528  constexpr int compare(
1529  std::size_t this_pos,
1530  std::size_t this_count,
1531  const BasicFixedString<Char, M>& that) const noexcept(false) {
1532  return compare(this_pos, this_count, that, 0u, that.size_);
1533  }
1534 
1540  template <std::size_t M>
1541  constexpr int compare(
1542  std::size_t this_pos,
1543  std::size_t this_count,
1544  const BasicFixedString<Char, M>& that,
1545  std::size_t that_pos,
1546  std::size_t that_count) const noexcept(false) {
1547  return static_cast<int>(detail::fixedstring::compare_(
1548  data_,
1549  detail::fixedstring::checkOverflow(this_pos, size_),
1550  detail::fixedstring::checkOverflow(this_count, size_ - this_pos) +
1551  this_pos,
1552  that.data_,
1553  detail::fixedstring::checkOverflow(that_pos, that.size_),
1554  detail::fixedstring::checkOverflow(that_count, that.size_ - that_pos) +
1555  that_pos));
1556  }
1557 
1562  constexpr int compare(const Char* that) const noexcept {
1563  return compare(0u, size_, that, folly::constexpr_strlen(that));
1564  }
1565 
1569  constexpr int compare(Range<const Char*> that) const noexcept {
1570  return compare(0u, size_, that.begin(), that.size());
1571  }
1572 
1578  constexpr int compare(
1579  std::size_t this_pos,
1580  std::size_t this_count,
1581  const Char* that) const noexcept(false) {
1582  return compare(this_pos, this_count, that, folly::constexpr_strlen(that));
1583  }
1584 
1588  constexpr int compare(
1589  std::size_t this_pos,
1590  std::size_t this_count,
1591  Range<const Char*> that) const noexcept(false) {
1592  return compare(this_pos, this_count, that.begin(), that.size());
1593  }
1594 
1610  constexpr int compare(
1611  std::size_t this_pos,
1612  std::size_t this_count,
1613  const Char* that,
1614  std::size_t that_count) const noexcept(false) {
1615  return static_cast<int>(detail::fixedstring::compare_(
1616  data_,
1617  detail::fixedstring::checkOverflow(this_pos, size_),
1618  detail::fixedstring::checkOverflowOrNpos(this_count, size_ - this_pos) +
1619  this_pos,
1620  that,
1621  0u,
1622  that_count));
1623  }
1624 
1625  constexpr int compare(
1626  std::size_t this_pos,
1627  std::size_t this_count,
1628  Range<const Char*> that,
1629  std::size_t that_count) const noexcept(false) {
1630  return compare(
1631  this_pos,
1632  this_count,
1633  that.begin(),
1634  detail::fixedstring::checkOverflow(that_count, that.size()));
1635  }
1636 
1641  constexpr BasicFixedString substr(std::size_t pos) const noexcept(false) {
1642  return {*this, pos};
1643  }
1644 
1649  constexpr BasicFixedString substr(std::size_t pos, std::size_t count) const
1650  noexcept(false) {
1651  return {*this, pos, count};
1652  }
1653 
1662  template <std::size_t M>
1664  const Char* first,
1665  const Char* last,
1666  const BasicFixedString<Char, M>& that) noexcept(false) {
1667  return replace(first - data_, last - first, that, 0u, that.size_);
1668  }
1669 
1678  template <std::size_t M>
1680  std::size_t this_pos,
1681  std::size_t this_count,
1682  const BasicFixedString<Char, M>& that,
1683  std::size_t that_pos = 0u) noexcept(false) {
1684  return replace(this_pos, this_count, that, that_pos, that.size_ - that_pos);
1685  }
1686 
1695  template <std::size_t M>
1697  std::size_t this_pos,
1698  std::size_t this_count,
1699  const BasicFixedString<Char, M>& that,
1700  std::size_t that_pos,
1701  std::size_t that_count) noexcept(false) {
1702  return *this = creplace(this_pos, this_count, that, that_pos, that_count);
1703  }
1704 
1712  std::size_t this_pos,
1713  std::size_t this_count,
1714  const Char* that) noexcept(false) {
1715  return replace(this_pos, this_count, that, folly::constexpr_strlen(that));
1716  }
1717 
1727  const Char* first,
1728  const Char* last,
1729  const Char* that) noexcept(false) {
1730  return replace(
1731  first - data_, last - first, that, folly::constexpr_strlen(that));
1732  }
1733 
1752  std::size_t this_pos,
1753  std::size_t this_count,
1754  const Char* that,
1755  std::size_t that_count) noexcept(false) {
1756  return *this = detail::fixedstring::Helper::replace_<Char>(
1757  data_,
1758  size_,
1759  detail::fixedstring::checkOverflow(this_pos, size_),
1761  this_count, size_ - this_pos),
1762  that,
1763  0u,
1764  that_count,
1765  Indices{});
1766  }
1767 
1775  std::size_t this_pos,
1776  std::size_t this_count,
1777  std::size_t that_count,
1778  Char ch) noexcept(false) {
1779  return replace(this_pos, this_count, BasicFixedString{that_count, ch});
1780  }
1781 
1789  const Char* first,
1790  const Char* last,
1791  std::size_t that_count,
1792  Char ch) noexcept(false) {
1793  return replace(
1794  first - data_, last - first, BasicFixedString{that_count, ch});
1795  }
1796 
1806  const Char* first,
1807  const Char* last,
1808  std::initializer_list<Char> il) noexcept(false) {
1809  return replace(first - data_, last - first, il.begin(), il.size());
1810  }
1811 
1821  template <std::size_t M>
1823  std::size_t this_pos,
1824  std::size_t this_count,
1825  const BasicFixedString<Char, M>& that,
1826  std::size_t that_pos = 0u) const noexcept(false) {
1827  return creplace(
1828  this_pos,
1829  this_count,
1830  that,
1831  that_pos,
1832  that.size_ - detail::fixedstring::checkOverflow(that_pos, that.size_));
1833  }
1834 
1858  template <std::size_t M>
1860  std::size_t this_pos,
1861  std::size_t this_count,
1862  const BasicFixedString<Char, M>& that,
1863  std::size_t that_pos,
1864  std::size_t that_count) const noexcept(false) {
1865  return detail::fixedstring::Helper::replace_<Char>(
1866  data_,
1867  size_,
1868  detail::fixedstring::checkOverflow(this_pos, size_),
1869  detail::fixedstring::checkOverflowOrNpos(this_count, size_ - this_pos),
1870  that.data_,
1871  detail::fixedstring::checkOverflow(that_pos, that.size_),
1873  that_count, that.size_ - that_pos),
1875  }
1876 
1886  template <std::size_t M>
1888  const Char* first,
1889  const Char* last,
1890  const BasicFixedString<Char, M>& that,
1891  std::size_t that_pos = 0u) const noexcept(false) {
1892  return creplace(
1893  first - data_,
1894  last - first,
1895  that,
1896  that_pos,
1897  that.size_ - detail::fixedstring::checkOverflow(that_pos, that.size_));
1898  }
1899 
1908  template <std::size_t M>
1910  const Char* first,
1911  const Char* last,
1912  const BasicFixedString<Char, M>& that,
1913  std::size_t that_pos,
1914  std::size_t that_count) const noexcept(false) {
1915  return creplace(first - data_, last - first, that, that_pos, that_count);
1916  }
1917 
1926  template <std::size_t M>
1927  constexpr BasicFixedString<Char, N + M - 1u> creplace(
1928  std::size_t this_pos,
1929  std::size_t this_count,
1930  const Char (&that)[M]) const noexcept(false) {
1931  return creplace(this_pos, this_count, that, 0u, M - 1u);
1932  }
1933 
1959  template <std::size_t M>
1960  constexpr BasicFixedString<Char, N + M - 1u> creplace(
1961  std::size_t this_pos,
1962  std::size_t this_count,
1963  const Char (&that)[M],
1964  std::size_t that_pos,
1965  std::size_t that_count) const noexcept(false) {
1966  return detail::fixedstring::Helper::replace_<Char>(
1967  data_,
1968  size_,
1969  detail::fixedstring::checkOverflow(this_pos, size_),
1970  detail::fixedstring::checkOverflowOrNpos(this_count, size_ - this_pos),
1972  detail::fixedstring::checkOverflow(that_pos, M - 1u),
1973  detail::fixedstring::checkOverflowOrNpos(that_count, M - 1u - that_pos),
1974  folly::make_index_sequence<N + M - 1u>{});
1975  }
1976 
1985  template <std::size_t M>
1986  constexpr BasicFixedString<Char, N + M - 1u>
1987  creplace(const Char* first, const Char* last, const Char (&that)[M]) const
1988  noexcept(false) {
1989  return creplace(first - data_, last - first, that, 0u, M - 1u);
1990  }
1991 
2001  template <std::size_t M>
2002  constexpr BasicFixedString<Char, N + M - 1u> creplace(
2003  const Char* first,
2004  const Char* last,
2005  const Char (&that)[M],
2006  std::size_t that_pos,
2007  std::size_t that_count) const noexcept(false) {
2008  return creplace(first - data_, last - first, that, that_pos, that_count);
2009  }
2010 
2016  FOLLY_CPP14_CONSTEXPR std::size_t copy(Char* dest, std::size_t count) const
2017  noexcept {
2018  return copy(dest, count, 0u);
2019  }
2020 
2028  FOLLY_CPP14_CONSTEXPR std::size_t
2029  copy(Char* dest, std::size_t count, std::size_t pos) const noexcept(false) {
2031  for (std::size_t i = 0u; i < count; ++i) {
2032  if (i + pos == size_) {
2033  return size_;
2034  }
2035  dest[i] = data_[i + pos];
2036  }
2037  return count;
2038  }
2039 
2044  FOLLY_CPP14_CONSTEXPR void resize(std::size_t count) noexcept(false) {
2045  resize(count, Char(0));
2046  }
2047 
2053  FOLLY_CPP14_CONSTEXPR void resize(std::size_t count, Char ch) noexcept(
2054  false) {
2056  if (count == size_) {
2057  } else if (count < size_) {
2058  size_ = count;
2059  data_[size_] = Char(0);
2060  } else {
2061  for (; size_ < count; ++size_) {
2062  data_[size_] = ch;
2063  }
2064  data_[size_] = Char(0);
2065  }
2066  }
2067 
2072  template <std::size_t M>
2073  constexpr std::size_t find(const BasicFixedString<Char, M>& that) const
2074  noexcept {
2075  return find(that, 0u);
2076  }
2077 
2084  template <std::size_t M>
2085  constexpr std::size_t find(
2086  const BasicFixedString<Char, M>& that,
2087  std::size_t pos) const noexcept(false) {
2088  return that.size_ <= size_ - detail::fixedstring::checkOverflow(pos, size_)
2089  ? detail::fixedstring::find_(data_, size_, that.data_, pos, that.size_)
2090  : npos;
2091  }
2092 
2097  constexpr std::size_t find(const Char* that) const noexcept {
2098  return find(that, 0u, folly::constexpr_strlen(that));
2099  }
2100 
2107  constexpr std::size_t find(const Char* that, std::size_t pos) const
2108  noexcept(false) {
2109  return find(that, pos, folly::constexpr_strlen(that));
2110  }
2111 
2123  constexpr std::size_t find(
2124  const Char* that,
2125  std::size_t pos,
2126  std::size_t count) const noexcept(false) {
2127  return count <= size_ - detail::fixedstring::checkOverflow(pos, size_)
2128  ? detail::fixedstring::find_(data_, size_, that, pos, count)
2129  : npos;
2130  }
2131 
2136  constexpr std::size_t find(Char ch) const noexcept {
2137  return find(ch, 0u);
2138  }
2139 
2146  constexpr std::size_t find(Char ch, std::size_t pos) const noexcept(false) {
2147  using A = const Char[1u];
2148  return 0u == size_ - detail::fixedstring::checkOverflow(pos, size_)
2149  ? npos
2150  : detail::fixedstring::find_(data_, size_, A{ch}, pos, 1u);
2151  }
2152 
2158  template <std::size_t M>
2159  constexpr std::size_t rfind(const BasicFixedString<Char, M>& that) const
2160  noexcept {
2161  return rfind(that, size_);
2162  }
2163 
2169  template <std::size_t M>
2170  constexpr std::size_t rfind(
2171  const BasicFixedString<Char, M>& that,
2172  std::size_t pos) const noexcept(false) {
2173  return that.size_ <= size_
2175  data_,
2176  that.data_,
2179  size_ - that.size_),
2180  that.size_)
2181  : npos;
2182  }
2183 
2189  constexpr std::size_t rfind(const Char* that) const noexcept {
2190  return rfind(that, size_, folly::constexpr_strlen(that));
2191  }
2192 
2198  constexpr std::size_t rfind(const Char* that, std::size_t pos) const
2199  noexcept(false) {
2200  return rfind(that, pos, folly::constexpr_strlen(that));
2201  }
2202 
2214  constexpr std::size_t rfind(
2215  const Char* that,
2216  std::size_t pos,
2217  std::size_t count) const noexcept(false) {
2218  return count <= size_
2220  data_,
2221  that,
2224  size_ - count),
2225  count)
2226  : npos;
2227  }
2228 
2233  constexpr std::size_t rfind(Char ch) const noexcept {
2234  return rfind(ch, size_);
2235  }
2236 
2243  constexpr std::size_t rfind(Char ch, std::size_t pos) const noexcept(false) {
2244  using A = const Char[1u];
2245  return 0u == size_
2246  ? npos
2248  data_,
2249  A{ch},
2251  detail::fixedstring::checkOverflow(pos, size_), size_ - 1u),
2252  1u);
2253  }
2254 
2259  template <std::size_t M>
2260  constexpr std::size_t find_first_of(
2261  const BasicFixedString<Char, M>& that) const noexcept {
2262  return find_first_of(that, 0u);
2263  }
2264 
2270  template <std::size_t M>
2271  constexpr std::size_t find_first_of(
2272  const BasicFixedString<Char, M>& that,
2273  std::size_t pos) const noexcept(false) {
2274  return size_ == detail::fixedstring::checkOverflow(pos, size_)
2275  ? npos
2277  data_, size_, that.data_, pos, that.size_);
2278  }
2279 
2285  constexpr std::size_t find_first_of(const Char* that) const noexcept {
2286  return find_first_of(that, 0u, folly::constexpr_strlen(that));
2287  }
2288 
2295  constexpr std::size_t find_first_of(const Char* that, std::size_t pos) const
2296  noexcept(false) {
2297  return find_first_of(that, pos, folly::constexpr_strlen(that));
2298  }
2299 
2312  constexpr std::size_t find_first_of(
2313  const Char* that,
2314  std::size_t pos,
2315  std::size_t count) const noexcept(false) {
2316  return size_ == detail::fixedstring::checkOverflow(pos, size_)
2317  ? npos
2318  : detail::fixedstring::find_first_of_(data_, size_, that, pos, count);
2319  }
2320 
2325  constexpr std::size_t find_first_of(Char ch) const noexcept {
2326  return find_first_of(ch, 0u);
2327  }
2328 
2334  constexpr std::size_t find_first_of(Char ch, std::size_t pos) const
2335  noexcept(false) {
2336  using A = const Char[1u];
2337  return size_ == detail::fixedstring::checkOverflow(pos, size_)
2338  ? npos
2339  : detail::fixedstring::find_first_of_(data_, size_, A{ch}, pos, 1u);
2340  }
2341 
2346  template <std::size_t M>
2347  constexpr std::size_t find_first_not_of(
2348  const BasicFixedString<Char, M>& that) const noexcept {
2349  return find_first_not_of(that, 0u);
2350  }
2351 
2356  template <std::size_t M>
2357  constexpr std::size_t find_first_not_of(
2358  const BasicFixedString<Char, M>& that,
2359  std::size_t pos) const noexcept(false) {
2360  return size_ == detail::fixedstring::checkOverflow(pos, size_)
2361  ? npos
2363  data_, size_, that.data_, pos, that.size_);
2364  }
2365 
2371  constexpr std::size_t find_first_not_of(const Char* that) const noexcept {
2372  return find_first_not_of(that, 0u, folly::constexpr_strlen(that));
2373  }
2374 
2381  constexpr std::size_t find_first_not_of(const Char* that, std::size_t pos)
2382  const noexcept(false) {
2383  return find_first_not_of(that, pos, folly::constexpr_strlen(that));
2384  }
2385 
2398  constexpr std::size_t find_first_not_of(
2399  const Char* that,
2400  std::size_t pos,
2401  std::size_t count) const noexcept(false) {
2402  return size_ == detail::fixedstring::checkOverflow(pos, size_)
2403  ? npos
2405  data_, size_, that, pos, count);
2406  }
2407 
2412  constexpr std::size_t find_first_not_of(Char ch) const noexcept {
2413  return find_first_not_of(ch, 0u);
2414  }
2415 
2421  constexpr std::size_t find_first_not_of(Char ch, std::size_t pos) const
2422  noexcept(false) {
2423  using A = const Char[1u];
2424  return 1u <= size_ - detail::fixedstring::checkOverflow(pos, size_)
2425  ? detail::fixedstring::find_first_not_of_(data_, size_, A{ch}, pos, 1u)
2426  : npos;
2427  }
2428 
2433  template <std::size_t M>
2434  constexpr std::size_t find_last_of(
2435  const BasicFixedString<Char, M>& that) const noexcept {
2436  return find_last_of(that, size_);
2437  }
2438 
2444  template <std::size_t M>
2445  constexpr std::size_t find_last_of(
2446  const BasicFixedString<Char, M>& that,
2447  std::size_t pos) const noexcept(false) {
2448  return 0u == size_
2449  ? npos
2451  data_,
2452  that.data_,
2454  detail::fixedstring::checkOverflow(pos, size_), size_ - 1u),
2455  that.size_);
2456  }
2457 
2463  constexpr std::size_t find_last_of(const Char* that) const noexcept {
2464  return find_last_of(that, size_, folly::constexpr_strlen(that));
2465  }
2466 
2473  constexpr std::size_t find_last_of(const Char* that, std::size_t pos) const
2474  noexcept(false) {
2475  return find_last_of(that, pos, folly::constexpr_strlen(that));
2476  }
2477 
2490  constexpr std::size_t find_last_of(
2491  const Char* that,
2492  std::size_t pos,
2493  std::size_t count) const noexcept(false) {
2494  return 0u == size_
2495  ? npos
2497  data_,
2498  that,
2500  detail::fixedstring::checkOverflow(pos, size_), size_ - 1u),
2501  count);
2502  }
2503 
2508  constexpr std::size_t find_last_of(Char ch) const noexcept {
2509  return find_last_of(ch, size_);
2510  }
2511 
2517  constexpr std::size_t find_last_of(Char ch, std::size_t pos) const
2518  noexcept(false) {
2519  using A = const Char[1u];
2520  return 0u == size_
2521  ? npos
2523  data_,
2524  A{ch},
2526  detail::fixedstring::checkOverflow(pos, size_), size_ - 1u),
2527  1u);
2528  }
2529 
2534  template <std::size_t M>
2535  constexpr std::size_t find_last_not_of(
2536  const BasicFixedString<Char, M>& that) const noexcept {
2537  return find_last_not_of(that, size_);
2538  }
2539 
2545  template <std::size_t M>
2546  constexpr std::size_t find_last_not_of(
2547  const BasicFixedString<Char, M>& that,
2548  std::size_t pos) const noexcept(false) {
2549  return 0u == size_
2550  ? npos
2552  data_,
2553  that.data_,
2555  detail::fixedstring::checkOverflow(pos, size_), size_ - 1u),
2556  that.size_);
2557  }
2558 
2564  constexpr std::size_t find_last_not_of(const Char* that) const noexcept {
2565  return find_last_not_of(that, size_, folly::constexpr_strlen(that));
2566  }
2567 
2574  constexpr std::size_t find_last_not_of(const Char* that, std::size_t pos)
2575  const noexcept(false) {
2576  return find_last_not_of(that, pos, folly::constexpr_strlen(that));
2577  }
2578 
2591  constexpr std::size_t find_last_not_of(
2592  const Char* that,
2593  std::size_t pos,
2594  std::size_t count) const noexcept(false) {
2595  return 0u == size_
2596  ? npos
2598  data_,
2599  that,
2601  detail::fixedstring::checkOverflow(pos, size_), size_ - 1u),
2602  count);
2603  }
2604 
2609  constexpr std::size_t find_last_not_of(Char ch) const noexcept {
2610  return find_last_not_of(ch, size_);
2611  }
2612 
2618  constexpr std::size_t find_last_not_of(Char ch, std::size_t pos) const
2619  noexcept(false) {
2620  using A = const Char[1u];
2621  return 0u == size_
2622  ? npos
2624  data_,
2625  A{ch},
2627  detail::fixedstring::checkOverflow(pos, size_), size_ - 1u),
2628  1u);
2629  }
2630 
2634  friend constexpr bool operator==(
2635  const Char* a,
2636  const BasicFixedString& b) noexcept {
2638  a, folly::constexpr_strlen(a), b.data_, b.size_);
2639  }
2640 
2644  friend constexpr bool operator==(
2645  const BasicFixedString& a,
2646  const Char* b) noexcept {
2647  return b == a;
2648  }
2649 
2653  friend constexpr bool operator==(
2655  const BasicFixedString& b) noexcept {
2656  return detail::fixedstring::equal_(a.begin(), a.size(), b.data_, b.size_);
2657  }
2658 
2662  friend constexpr bool operator==(
2663  const BasicFixedString& a,
2664  Range<const Char*> b) noexcept {
2665  return b == a;
2666  }
2667 
2668  friend constexpr bool operator!=(
2669  const Char* a,
2670  const BasicFixedString& b) noexcept {
2671  return !(a == b);
2672  }
2673 
2677  friend constexpr bool operator!=(
2678  const BasicFixedString& a,
2679  const Char* b) noexcept {
2680  return !(b == a);
2681  }
2682 
2686  friend constexpr bool operator!=(
2688  const BasicFixedString& b) noexcept {
2689  return !(a == b);
2690  }
2691 
2695  friend constexpr bool operator!=(
2696  const BasicFixedString& a,
2697  Range<const Char*> b) noexcept {
2698  return !(a == b);
2699  }
2700 
2701  friend constexpr bool operator<(
2702  const Char* a,
2703  const BasicFixedString& b) noexcept {
2704  return ordering::lt ==
2706  a, 0u, folly::constexpr_strlen(a), b.data_, 0u, b.size_);
2707  }
2708 
2712  friend constexpr bool operator<(
2713  const BasicFixedString& a,
2714  const Char* b) noexcept {
2715  return ordering::lt ==
2717  a.data_, 0u, a.size_, b, 0u, folly::constexpr_strlen(b));
2718  }
2719 
2723  friend constexpr bool operator<(
2725  const BasicFixedString& b) noexcept {
2726  return ordering::lt ==
2728  a.begin(), 0u, a.size(), b.data_, 0u, b.size_);
2729  }
2730 
2734  friend constexpr bool operator<(
2735  const BasicFixedString& a,
2736  Range<const Char*> b) noexcept {
2737  return ordering::lt ==
2739  a.data_, 0u, a.size_, b.begin(), 0u, b.size());
2740  }
2741 
2742  friend constexpr bool operator>(
2743  const Char* a,
2744  const BasicFixedString& b) noexcept {
2745  return b < a;
2746  }
2747 
2751  friend constexpr bool operator>(
2752  const BasicFixedString& a,
2753  const Char* b) noexcept {
2754  return b < a;
2755  }
2756 
2760  friend constexpr bool operator>(
2762  const BasicFixedString& b) noexcept {
2763  return b < a;
2764  }
2765 
2769  friend constexpr bool operator>(
2770  const BasicFixedString& a,
2771  Range<const Char*> b) noexcept {
2772  return b < a;
2773  }
2774 
2775  friend constexpr bool operator<=(
2776  const Char* a,
2777  const BasicFixedString& b) noexcept {
2778  return !(b < a);
2779  }
2780 
2784  friend constexpr bool operator<=(
2785  const BasicFixedString& a,
2786  const Char* b) noexcept {
2787  return !(b < a);
2788  }
2789 
2793  friend constexpr bool operator<=(
2794  Range<const Char*> const& a,
2795  const BasicFixedString& b) noexcept {
2796  return !(b < a);
2797  }
2798 
2802  friend constexpr bool operator<=(
2803  const BasicFixedString& a,
2804  Range<const Char*> b) noexcept {
2805  return !(b < a);
2806  }
2807 
2808  friend constexpr bool operator>=(
2809  const Char* a,
2810  const BasicFixedString& b) noexcept {
2811  return !(a < b);
2812  }
2813 
2817  friend constexpr bool operator>=(
2818  const BasicFixedString& a,
2819  const Char* b) noexcept {
2820  return !(a < b);
2821  }
2822 
2826  friend constexpr bool operator>=(
2828  const BasicFixedString& b) noexcept {
2829  return !(a < b);
2830  }
2831 
2835  friend constexpr bool operator>=(
2836  const BasicFixedString& a,
2837  Range<const Char*> const& b) noexcept {
2838  return !(a < b);
2839  }
2840 
2844  template <std::size_t M>
2845  friend constexpr BasicFixedString<Char, N + M - 1u> operator+(
2846  const Char (&a)[M],
2847  const BasicFixedString& b) noexcept {
2848  return detail::fixedstring::Helper::concat_<Char>(
2850  M - 1u,
2851  b.data_,
2852  b.size_,
2853  folly::make_index_sequence<N + M - 1u>{});
2854  }
2855 
2859  template <std::size_t M>
2860  friend constexpr BasicFixedString<Char, N + M - 1u> operator+(
2861  const BasicFixedString& a,
2862  const Char (&b)[M]) noexcept {
2863  return detail::fixedstring::Helper::concat_<Char>(
2864  a.data_,
2865  a.size_,
2867  M - 1u,
2868  folly::make_index_sequence<N + M - 1u>{});
2869  }
2870 
2875  Char a,
2876  const BasicFixedString& b) noexcept {
2877  using A = const Char[2u];
2878  return detail::fixedstring::Helper::concat_<Char>(
2879  A{a, Char(0)},
2880  1u,
2881  b.data_,
2882  b.size_,
2884  }
2885 
2890  const BasicFixedString& a,
2891  Char b) noexcept {
2892  using A = const Char[2u];
2893  return detail::fixedstring::Helper::concat_<Char>(
2894  a.data_,
2895  a.size_,
2896  A{b, Char(0)},
2897  1u,
2899  }
2900 };
2901 
2902 template <class C, std::size_t N>
2903 inline std::basic_ostream<C>& operator<<(
2904  std::basic_ostream<C>& os,
2905  const BasicFixedString<C, N>& string) {
2906  using StreamSize = decltype(os.width());
2907  os.write(string.begin(), static_cast<StreamSize>(string.size()));
2908  return os;
2909 }
2910 
2914 template <class Char, std::size_t A, std::size_t B>
2915 constexpr bool operator==(
2917  const BasicFixedString<Char, B>& b) noexcept {
2920  a.size(),
2922  b.size());
2923 }
2924 
2925 template <class Char, std::size_t A, std::size_t B>
2926 constexpr bool operator!=(
2928  const BasicFixedString<Char, B>& b) {
2929  return !(a == b);
2930 }
2931 
2932 template <class Char, std::size_t A, std::size_t B>
2933 constexpr bool operator<(
2935  const BasicFixedString<Char, B>& b) noexcept {
2936  return ordering::lt ==
2939  0u,
2940  a.size(),
2942  0u,
2943  b.size());
2944 }
2945 
2946 template <class Char, std::size_t A, std::size_t B>
2947 constexpr bool operator>(
2949  const BasicFixedString<Char, B>& b) noexcept {
2950  return b < a;
2951 }
2952 
2953 template <class Char, std::size_t A, std::size_t B>
2954 constexpr bool operator<=(
2956  const BasicFixedString<Char, B>& b) noexcept {
2957  return !(b < a);
2958 }
2959 
2960 template <class Char, std::size_t A, std::size_t B>
2961 constexpr bool operator>=(
2963  const BasicFixedString<Char, B>& b) noexcept {
2964  return !(a < b);
2965 }
2966 
2970 template <class Char, std::size_t N, std::size_t M>
2973  const BasicFixedString<Char, M>& b) noexcept {
2974  return detail::fixedstring::Helper::concat_<Char>(
2976  a.size(),
2978  b.size(),
2980 }
2981 
2990 template <class Char, std::size_t N>
2992  const Char (&a)[N]) noexcept {
2993  return {a};
2994 }
2995 
2999 template <class Char, std::size_t N>
3002  BasicFixedString<Char, N>& b) noexcept {
3003  a.swap(b);
3004 }
3005 
3006 inline namespace literals {
3007 inline namespace string_literals {
3008 inline namespace {
3009 // "const std::size_t&" is so that folly::npos has the same address in every
3010 // translation unit. This is to avoid potential violations of the ODR.
3011 constexpr const std::size_t& npos = detail::fixedstring::FixedStringBase::npos;
3012 } // namespace
3013 
3014 #if defined(__GNUC__) && !defined(__ICC)
3015 #pragma GCC diagnostic push
3016 #pragma GCC diagnostic ignored "-Wpragmas"
3017 #pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template"
3018 
3039 template <class Char, Char... Cs>
3040 constexpr BasicFixedString<Char, sizeof...(Cs)> operator"" _fs() noexcept {
3041 #if __cplusplus >= 201402L
3042  const Char a[] = {Cs..., Char(0)};
3043  return {+a, sizeof...(Cs)};
3044 #else
3045  using A = const Char[sizeof...(Cs) + 1u];
3046  // The `+` in `+A{etc}` forces the array type to decay to a pointer
3047  return {+A{Cs..., Char(0)}, sizeof...(Cs)};
3048 #endif
3049 }
3050 
3051 #pragma GCC diagnostic pop
3052 #endif
3053 
3054 #define FOLLY_DEFINE_FIXED_STRING_UDL(N) \
3055  constexpr FixedString<N> operator"" _fs##N( \
3056  const char* that, std::size_t count) noexcept(false) { \
3057  return {that, count}; \
3058  } \
3059 
3060 
3061 // Define UDLs _fs4, _fs8, _fs16, etc for FixedString<[4, 8, 16, ...]>
3068 
3069 #undef FOLLY_DEFINE_FIXED_STRING_UDL
3070 } // namespace string_literals
3071 } // namespace literals
3072 
3073 // TODO:
3074 // // numeric conversions:
3075 // template <std::size_t N>
3076 // constexpr int stoi(const FixedString<N>& str, int base = 10);
3077 // template <std::size_t N>
3078 // constexpr unsigned stou(const FixedString<N>& str, int base = 10);
3079 // template <std::size_t N>
3080 // constexpr long stol(const FixedString<N>& str, int base = 10);
3081 // template <std::size_t N>
3082 // constexpr unsigned long stoul(const FixedString<N>& str, int base = 10;
3083 // template <std::size_t N>
3084 // constexpr long long stoll(const FixedString<N>& str, int base = 10);
3085 // template <std::size_t N>
3086 // constexpr unsigned long long stoull(const FixedString<N>& str,
3087 // int base = 10);
3088 // template <std::size_t N>
3089 // constexpr float stof(const FixedString<N>& str);
3090 // template <std::size_t N>
3091 // constexpr double stod(const FixedString<N>& str);
3092 // template <std::size_t N>
3093 // constexpr long double stold(const FixedString<N>& str);
3094 // template <int val>
3095 // constexpr FixedString</*...*/> to_fixed_string_i() noexcept;
3096 // template <unsigned val>
3097 // constexpr FixedString</*...*/> to_fixed_string_u() noexcept;
3098 // template <long val>
3099 // constexpr FixedString</*...*/> to_fixed_string_l() noexcept;
3100 // template <unsigned long val>
3101 // constexpr FixedString</*...*/> to_fixed_string_ul() noexcept;
3102 // template <long long val>
3103 // constexpr FixedString</*...*/> to_fixed_string_ll() noexcept
3104 // template <unsigned long long val>
3105 // constexpr FixedString</*...*/> to_fixed_string_ull() noexcept;
3106 } // namespace folly
constexpr BasicFixedString cerase(std::size_t pos, std::size_t count=npos) const noexcept(false)
Definition: FixedString.h:1502
constexpr BasicFixedString< Char, N+M-1u > cappend(const Char(&that)[M]) const noexcept
Definition: FixedString.h:1376
friend constexpr ReverseIterator operator+(ReverseIterator that, std::ptrdiff_t i) noexcept
Definition: FixedString.h:384
friend constexpr bool operator>=(const BasicFixedString &a, Range< const Char * > const &b) noexcept
Definition: FixedString.h:2835
bool operator>(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
Definition: Expected.h:1349
FOLLY_CPP14_CONSTEXPR BasicFixedString & operator+=(Char ch) noexcept(false)
Definition: FixedString.h:1423
constexpr std::size_t find_first_of(const BasicFixedString< Char, M > &that) const noexcept
Definition: FixedString.h:2260
static constexpr std::size_t capacity() noexcept
Definition: FixedString.h:1083
void BENCHFUN() resize(size_t iters, size_t arg)
friend constexpr std::ptrdiff_t operator-(ReverseIterator a, ReverseIterator b) noexcept
Definition: FixedString.h:398
friend constexpr bool operator>(const BasicFixedString &a, Range< const Char * > b) noexcept
Definition: FixedString.h:2769
constexpr const_reverse_iterator crend() const noexcept
Definition: FixedString.h:1055
constexpr int compare(std::size_t this_pos, std::size_t this_count, const BasicFixedString< Char, M > &that) const noexcept(false)
Definition: FixedString.h:1528
constexpr std::size_t find_first_of(const Char *that) const noexcept
Definition: FixedString.h:2285
constexpr BasicFixedString substr(std::size_t pos) const noexcept(false)
Definition: FixedString.h:1641
friend constexpr ReverseIterator operator-(ReverseIterator that, std::ptrdiff_t i) noexcept
Definition: FixedString.h:393
constexpr std::size_t find_last_of(const BasicFixedString< Char, M > &that) const noexcept
Definition: FixedString.h:2434
constexpr const_reverse_iterator rbegin() const noexcept
Definition: FixedString.h:1026
FOLLY_CPP14_CONSTEXPR Range< Char * > toRange() noexcept
Definition: FixedString.h:796
constexpr BasicFixedString(const BasicFixedString< Char, M > &that) noexcept(M<=N)
Definition: FixedString.h:634
constexpr BasicFixedString< Char, N+M-1u > creplace(const Char *first, const Char *last, const Char(&that)[M]) const noexcept(false)
Definition: FixedString.h:1987
constexpr std::size_t find_first_not_of(const Char *that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2381
FOLLY_CPP14_CONSTEXPR Char & at(std::size_t i) noexcept(false)
Definition: FixedString.h:1105
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(std::size_t this_pos, std::size_t this_count, const Char *that) noexcept(false)
Definition: FixedString.h:1711
std::unique_ptr< int > A
constexpr BasicFixedString< Char, N+1u > cpush_back(Char ch) const noexcept
Definition: FixedString.h:1205
constexpr Range< const Char * > toRange() const noexcept
Definition: FixedString.h:803
FOLLY_CPP14_CONSTEXPR std::size_t copy(Char *dest, std::size_t count) const noexcept
Definition: FixedString.h:2016
FOLLY_CPP14_CONSTEXPR BasicFixedString & operator+=(std::initializer_list< Char > il) noexcept(false)
Definition: FixedString.h:1432
constexpr const Char(& checkNullTerminated(const Char(&a)[N]) noexcept)[N]
Definition: FixedString.h:92
FOLLY_CPP14_CONSTEXPR Char * erase(const Char *first, const Char *last) noexcept(false)
Definition: FixedString.h:1482
std::uint32_t hash() const noexcept
Definition: FixedString.h:1096
constexpr BasicFixedString(const Left &left, std::size_t left_size, const Right &right, std::size_t right_size, folly::index_sequence< Is... >) noexcept
Definition: FixedString.h:553
FOLLY_CPP14_CONSTEXPR BasicFixedString & operator=(const BasicFixedString< Char, M > &that) noexcept(M<=N)
Definition: FixedString.h:748
constexpr BasicFixedString< Char, N-1u > cpop_back() const noexcept(false)
Definition: FixedString.h:1229
constexpr std::size_t rfind(Char ch, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2243
char b
LogLevel max
Definition: LogLevel.cpp:31
constexpr BasicFixedString< Char, 0u > cerase() const noexcept
Definition: FixedString.h:1493
FOLLY_CPP14_CONSTEXPR BasicFixedString & operator+=(const Char *that) noexcept(false)
Definition: FixedString.h:1404
FOLLY_CPP14_CONSTEXPR Char & operator[](std::size_t i) noexcept
Definition: FixedString.h:1127
constexpr int compare(std::size_t this_pos, std::size_t this_count, Range< const Char * > that, std::size_t that_count) const noexcept(false)
Definition: FixedString.h:1625
friend constexpr BasicFixedString< Char, N+1u > operator+(Char a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2874
FOLLY_CPP14_CONSTEXPR Char * end() noexcept
Definition: FixedString.h:997
constexpr BasicFixedString< Char, N+M > cappend(const BasicFixedString< Char, M > &that, std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:1363
friend constexpr bool operator==(const BasicFixedString &a, const Char *b) noexcept
Definition: FixedString.h:2644
PskType type
constexpr BasicFixedString< Char, N+M-1u > creplace(std::size_t this_pos, std::size_t this_count, const Char(&that)[M]) const noexcept(false)
Definition: FixedString.h:1927
constexpr std::size_t checkOverflow(std::size_t i, std::size_t max)
Definition: FixedString.h:72
#define FOLLY_CPP14_CONSTEXPR
Definition: Portability.h:424
constexpr std::size_t find(const Char *that) const noexcept
Definition: FixedString.h:2097
constexpr T constexpr_min(T a)
Definition: ConstexprMath.h:79
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
FOLLY_CPP14_CONSTEXPR void clear() noexcept
Definition: FixedString.h:1188
friend constexpr bool operator<=(const BasicFixedString &a, const Char *b) noexcept
Definition: FixedString.h:2784
friend constexpr bool operator<(const BasicFixedString &a, const Char *b) noexcept
Definition: FixedString.h:2712
constexpr const Char & front() const noexcept
Definition: FixedString.h:1156
folly::make_index_sequence< N > Indices
Definition: FixedString.h:531
FOLLY_CPP14_CONSTEXPR BasicFixedString & operator=(std::initializer_list< Char > il) noexcept(false)
Definition: FixedString.h:781
constexpr std::size_t rfind(Char ch) const noexcept
Definition: FixedString.h:2233
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(std::size_t this_pos, std::size_t this_count, const BasicFixedString< Char, M > &that, std::size_t that_pos, std::size_t that_count) noexcept(false)
Definition: FixedString.h:1696
constexpr const Char & operator[](std::size_t i) const noexcept
Definition: FixedString.h:1138
dest
Definition: upload.py:394
void append(std::unique_ptr< IOBuf > &buf, StringPiece str)
Definition: IOBufTest.cpp:37
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
FOLLY_CPP14_CONSTEXPR BasicFixedString & erase() noexcept
Definition: FixedString.h:1442
constexpr BasicFixedString< Char, N+M > cappend(const BasicFixedString< Char, M > &that) const noexcept
Definition: FixedString.h:1345
constexpr std::size_t find_first_not_of(const Char *that, std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:2398
constexpr std::size_t find_last_of(const Char *that) const noexcept
Definition: FixedString.h:2463
constexpr bool find_at_(const Left &left, const Right &right, std::size_t pos, std::size_t count) noexcept
Definition: FixedString.h:175
friend constexpr bool operator!=(Range< const Char * > a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2686
const Char * const_iterator
Definition: FixedString.h:599
constexpr BasicFixedString< Char, N+M > creplace(std::size_t this_pos, std::size_t this_count, const BasicFixedString< Char, M > &that, std::size_t that_pos=0u) const noexcept(false)
Definition: FixedString.h:1822
constexpr BasicFixedString(const Char *that, std::size_t count) noexcept(false)
Definition: FixedString.h:699
folly::std T
constexpr std::size_t find_first_of(Char ch) const noexcept
Definition: FixedString.h:2325
FOLLY_CPP14_CONSTEXPR void resize(std::size_t count) noexcept(false)
Definition: FixedString.h:2044
FOLLY_CPP14_CONSTEXPR ReverseIterator operator--(int) noexcept
Definition: FixedString.h:370
static constexpr BasicFixedString< Char, sizeof...(Is)> replace_(const Left &left, std::size_t left_size, std::size_t left_pos, std::size_t left_count, const Right &right, std::size_t right_pos, std::size_t right_count, folly::index_sequence< Is... > is) noexcept
Definition: FixedString.h:279
FOLLY_CPP14_CONSTEXPR BasicFixedString & assign(const BasicFixedString< Char, M > &that, std::size_t pos, std::size_t count) noexcept(false)
Definition: FixedString.h:893
constexpr BasicFixedString substr(std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:1649
constexpr bool equal_(const Left &left, std::size_t left_size, const Right &right, std::size_t right_size) noexcept
Definition: FixedString.h:135
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
friend constexpr bool operator>=(const BasicFixedString &a, const Char *b) noexcept
Definition: FixedString.h:2817
constexpr BasicFixedString< Char, N+M > creplace(const Char *first, const Char *last, const BasicFixedString< Char, M > &that, std::size_t that_pos=0u) const noexcept(false)
Definition: FixedString.h:1887
constexpr size_t constexpr_strlen_internal(const Char *s, size_t len)
Definition: Constexpr.h:30
FOLLY_CPP14_CONSTEXPR BasicFixedString & assign(const Char(&that)[M]) noexcept
Definition: FixedString.h:910
constexpr std::size_t checkOverflowOrNpos(std::size_t i, std::size_t max)
Definition: FixedString.h:76
requires E e noexcept(noexcept(s.error(std::move(e))))
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(std::size_t this_pos, std::size_t this_count, std::size_t that_count, Char ch) noexcept(false)
Definition: FixedString.h:1774
constexpr std::size_t find_last_of(const Char *that, std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:2490
constexpr std::size_t rfind(const Char *that) const noexcept
Definition: FixedString.h:2189
constexpr std::size_t find_first_not_of(Char ch, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2421
constexpr Char char_at_(const Left &left, std::size_t left_count, const Right &right, std::size_t right_count, std::size_t i) noexcept
Definition: FixedString.h:145
constexpr std::size_t find(const Char *that, std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:2123
FOLLY_CPP14_CONSTEXPR Char * erase(const Char *first) noexcept(false)
Definition: FixedString.h:1473
constexpr std::size_t find_first_of(const BasicFixedString< Char, M > &that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2271
FOLLY_CPP14_CONSTEXPR BasicFixedString & assign(std::size_t count, Char ch) noexcept(false)
Definition: FixedString.h:844
constexpr int compare(std::size_t this_pos, std::size_t this_count, const Char *that, std::size_t that_count) const noexcept(false)
Definition: FixedString.h:1610
FOLLY_CPP14_CONSTEXPR void pop_back() noexcept(false)
Definition: FixedString.h:1217
FOLLY_CPP14_CONSTEXPR void swap(BasicFixedString &that) noexcept
Definition: FixedString.h:942
FOLLY_CPP14_CONSTEXPR BasicFixedString & append(const Char *that, std::size_t count) noexcept(false)
Definition: FixedString.h:1318
auto ch
constexpr std::size_t find(const Char *that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2107
ScopeGuardImpl< typename std::decay< FunctionType >::type, true > operator+(detail::ScopeGuardOnExit, FunctionType &&fn)
Definition: ScopeGuard.h:264
constexpr T constexpr_max(T a)
Definition: ConstexprMath.h:68
constexpr std::size_t find_first_of(const Char *that, std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:2312
void BENCHFUN() replace(size_t iters, size_t arg)
constexpr ReverseIterator(T *p) noexcept
Definition: FixedString.h:341
void BENCHFUN() push_back(size_t iters, size_t arg)
constexpr std::size_t find(Char ch, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2146
constexpr reference operator*() const
Definition: FixedString.h:354
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(const Char *first, const Char *last, const Char *that) noexcept(false)
Definition: FixedString.h:1726
friend constexpr bool operator>=(Range< const Char * > a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2826
constexpr BasicFixedString< Char, N+M > creplace(const Char *first, const Char *last, const BasicFixedString< Char, M > &that, std::size_t that_pos, std::size_t that_count) const noexcept(false)
Definition: FixedString.h:1909
typename std::remove_const< T >::type value_type
Definition: FixedString.h:331
static constexpr const Char(& data_(const BasicFixedString< Char, N > &that) noexcept)[N+1u]
Definition: FixedString.h:300
friend constexpr bool operator!=(const BasicFixedString &a, const Char *b) noexcept
Definition: FixedString.h:2677
bool operator!=(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
Definition: Expected.h:766
typename std::conditional< std::is_const< T >::value, ReverseIterator< typename std::remove_const< T >::type >, dummy_ >::type other
Definition: FixedString.h:328
static constexpr BasicFixedString< Char, sizeof...(Is)> concat_(const Left &left, std::size_t left_count, const Right &right, std::size_t right_count, folly::index_sequence< Is... > is) noexcept
Definition: FixedString.h:269
constexpr bool find_one_of_at_(Char ch, const Right &right, std::size_t pos) noexcept
Definition: FixedString.h:187
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
FOLLY_CPP14_CONSTEXPR Char * data() noexcept
Definition: FixedString.h:955
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
friend constexpr BasicFixedString< Char, N+1u > operator+(const BasicFixedString &a, Char b) noexcept
Definition: FixedString.h:2889
constexpr std::size_t find_last_not_of(const Char *that, std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:2591
constexpr int compare(std::size_t this_pos, std::size_t this_count, const Char *that) const noexcept(false)
Definition: FixedString.h:1578
constexpr BasicFixedString(const Left &left, std::size_t left_size, std::size_t left_pos, std::size_t left_count, const Right &right, std::size_t right_pos, std::size_t right_count, folly::index_sequence< Is... >) noexcept
Definition: FixedString.h:570
#define FOLLY_DEFINE_FIXED_STRING_UDL(N)
Definition: FixedString.h:3054
friend constexpr bool operator<(const Char *a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2701
constexpr const Char & at(std::size_t i) const noexcept(false)
Definition: FixedString.h:1115
constexpr const Char * cbegin() const noexcept
Definition: FixedString.h:990
ordering
Definition: Ordering.h:21
FOLLY_CPP14_CONSTEXPR BasicFixedString & append(const BasicFixedString< Char, M > &that, std::size_t pos, std::size_t count) noexcept(false)
Definition: FixedString.h:1286
constexpr BasicFixedString(std::size_t count, Char ch, folly::index_sequence< Is... >) noexcept
Definition: FixedString.h:545
constexpr std::size_t find_(const Left &left, std::size_t left_size, const Right &right, std::size_t pos, std::size_t count) noexcept
Definition: FixedString.h:193
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
FOLLY_CPP14_CONSTEXPR void push_back(Char ch) noexcept(false)
Definition: FixedString.h:1196
constexpr std::size_t find(const BasicFixedString< Char, M > &that) const noexcept
Definition: FixedString.h:2073
constexpr const Char * c_str() const noexcept
Definition: FixedString.h:969
FOLLY_CPP14_CONSTEXPR std::size_t copy(Char *dest, std::size_t count, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2029
FOLLY_CPP14_CONSTEXPR ReverseIterator & operator--() noexcept
Definition: FixedString.h:366
size_t rfind(const Range< Iter > &haystack, const typename Range< Iter >::value_type &needle)
Definition: Range.h:1404
constexpr std::size_t find_last_not_of(const BasicFixedString< Char, M > &that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2546
constexpr std::size_t find_last_not_of(const Char *that) const noexcept
Definition: FixedString.h:2564
make_integer_sequence< std::size_t, Size > make_index_sequence
Definition: Utility.h:209
A class for holding up to N characters of type Char that is amenable to constexpr string manipulation...
Definition: FixedString.h:42
FOLLY_CPP14_CONSTEXPR Char & back() noexcept
Definition: FixedString.h:1164
constexpr std::size_t rfind(const BasicFixedString< Char, M > &that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2170
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(const Char *first, const Char *last, std::initializer_list< Char > il) noexcept(false)
Definition: FixedString.h:1805
friend constexpr bool operator>(Range< const Char * > a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2760
constexpr BasicFixedString()
Definition: FixedString.h:611
constexpr std::size_t find_first_of(const Char *that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2295
char a
friend constexpr bool operator!=(const Char *a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2668
std::random_access_iterator_tag iterator_category
Definition: FixedString.h:335
FOLLY_CPP14_CONSTEXPR Char & front() noexcept
Definition: FixedString.h:1149
friend constexpr bool operator==(const Char *a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2634
constexpr BasicFixedString< Char, N+M-1u > cappend(const Char(&that)[M], std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:1395
constexpr std::size_t find_first_not_of(Char ch) const noexcept
Definition: FixedString.h:2412
FOLLY_CPP14_CONSTEXPR BasicFixedString & operator+=(const BasicFixedString< Char, M > &that) noexcept(false)
Definition: FixedString.h:1414
constexpr std::size_t find_first_of_(const Left &left, std::size_t left_size, const Right &right, std::size_t pos, std::size_t count) noexcept
Definition: FixedString.h:218
constexpr std::size_t find_last_of(Char ch, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2517
constexpr int compare(const Char *that) const noexcept
Definition: FixedString.h:1562
constexpr std::size_t rfind_(const Left &left, const Right &right, std::size_t pos, std::size_t count) noexcept
Definition: FixedString.h:206
static const char *const value
Definition: Conv.cpp:50
constexpr std::size_t find_last_not_of_(const Left &left, const Right &right, std::size_t pos, std::size_t count) noexcept
Definition: FixedString.h:256
constexpr std::size_t find_last_of_(const Left &left, const Right &right, std::size_t pos, std::size_t count) noexcept
Definition: FixedString.h:244
constexpr int compare(const BasicFixedString< Char, M > &that) const noexcept
Definition: FixedString.h:1518
constexpr BasicFixedString(std::initializer_list< Char > il) noexcept(false)
Definition: FixedString.h:728
FOLLY_CPP14_CONSTEXPR ReverseIterator operator++(int) noexcept
Definition: FixedString.h:361
constexpr std::size_t find_last_not_of(const Char *that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2574
**Optimized Holders **The template hazptr_array< M > provides most of the functionality *of M hazptr_holder s but with faster construction destruction *for M
Definition: Hazptr.h:104
constexpr int compare(Range< const Char * > that) const noexcept
Definition: FixedString.h:1569
friend constexpr bool operator<=(const BasicFixedString &a, Range< const Char * > b) noexcept
Definition: FixedString.h:2802
friend constexpr bool operator!=(ReverseIterator a, ReverseIterator b) noexcept
Definition: FixedString.h:349
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(std::size_t this_pos, std::size_t this_count, const Char *that, std::size_t that_count) noexcept(false)
Definition: FixedString.h:1751
constexpr std::size_t find_first_not_of(const BasicFixedString< Char, M > &that) const noexcept
Definition: FixedString.h:2347
int * count
bool operator>=(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
Definition: Expected.h:1358
constexpr const_reverse_iterator rend() const noexcept
Definition: FixedString.h:1048
const Char * const_pointer
Definition: FixedString.h:597
FOLLY_CPP14_CONSTEXPR void constexpr_swap(T &a, T &b) noexcept(noexcept(a=T(std::move(a))))
Definition: FixedString.h:310
friend constexpr bool operator>=(const Char *a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2808
void swap(exception_wrapper &a, exception_wrapper &b) noexcept
constexpr std::size_t find(Char ch) const noexcept
Definition: FixedString.h:2136
FOLLY_CPP14_CONSTEXPR ReverseIterator & operator++() noexcept
Definition: FixedString.h:357
FOLLY_CPP14_CONSTEXPR BasicFixedString & operator=(const Char(&that)[M]) noexcept
Definition: FixedString.h:767
FOLLY_CPP14_CONSTEXPR BasicFixedString & append(const Char *that) noexcept(false)
Definition: FixedString.h:1304
constexpr std::size_t find_last_not_of(Char ch) const noexcept
Definition: FixedString.h:2609
FOLLY_CPP14_CONSTEXPR reverse_iterator rend() noexcept
Definition: FixedString.h:1041
constexpr std::size_t find_last_not_of(const BasicFixedString< Char, M > &that) const noexcept
Definition: FixedString.h:2535
constexpr size_t constexpr_strlen(const Char *s)
Definition: Constexpr.h:57
bool operator==(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
Definition: Expected.h:758
constexpr const Char & back() const noexcept
Definition: FixedString.h:1175
FOLLY_CPP14_CONSTEXPR void resize(std::size_t count, Char ch) noexcept(false)
Definition: FixedString.h:2053
std::ptrdiff_t difference_type
Definition: FixedString.h:593
constexpr std::size_t rfind(const BasicFixedString< Char, M > &that) const noexcept
Definition: FixedString.h:2159
FOLLY_CPP14_CONSTEXPR Char * begin() noexcept
Definition: FixedString.h:976
friend constexpr bool operator<=(Range< const Char * > const &a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2793
constexpr int compare(std::size_t this_pos, std::size_t this_count, Range< const Char * > that) const noexcept(false)
Definition: FixedString.h:1588
FOLLY_CPP14_CONSTEXPR BasicFixedString & assign(const Char *that, std::size_t count) noexcept(false)
Definition: FixedString.h:927
constexpr std::size_t size() const noexcept
Definition: FixedString.h:1062
bool operator<=(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
Definition: Expected.h:1340
constexpr std::size_t find_last_not_of(Char ch, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2618
constexpr int compare(std::size_t this_pos, std::size_t this_count, const BasicFixedString< Char, M > &that, std::size_t that_pos, std::size_t that_count) const noexcept(false)
Definition: FixedString.h:1541
constexpr std::size_t rfind(const Char *that, std::size_t pos, std::size_t count) const noexcept(false)
Definition: FixedString.h:2214
FOLLY_CPP14_CONSTEXPR BasicFixedString & append(std::size_t count, Char ch) noexcept(false)
Definition: FixedString.h:1240
const
Definition: upload.py:398
constexpr const Char * begin() const noexcept
Definition: FixedString.h:983
FOLLY_CPP14_CONSTEXPR BasicFixedString & append(const BasicFixedString< Char, M > &that) noexcept(false)
Definition: FixedString.h:1256
constexpr std::size_t find_first_not_of(const BasicFixedString< Char, M > &that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2357
friend constexpr bool operator<(const BasicFixedString &a, Range< const Char * > b) noexcept
Definition: FixedString.h:2734
friend constexpr bool operator<(Range< const Char * > a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2723
constexpr ReverseIterator(const other &that) noexcept
Definition: FixedString.h:342
FOLLY_CPP14_CONSTEXPR ReverseIterator & operator-=(std::ptrdiff_t i) noexcept
Definition: FixedString.h:389
friend constexpr BasicFixedString< Char, N+M-1u > operator+(const Char(&a)[M], const BasicFixedString &b) noexcept
Definition: FixedString.h:2845
FOLLY_CPP14_CONSTEXPR BasicFixedString & assign(const BasicFixedString< Char, M > &that) noexcept(M<=N)
Definition: FixedString.h:861
constexpr std::size_t find(const BasicFixedString< Char, M > &that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2085
constexpr std::size_t find_last_of(const BasicFixedString< Char, M > &that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2445
constexpr const Char * data() const noexcept
Definition: FixedString.h:962
static constexpr std::size_t npos
Definition: FixedString.h:54
friend constexpr bool operator==(const BasicFixedString &a, Range< const Char * > b) noexcept
Definition: FixedString.h:2662
constexpr const Char * cend() const noexcept
Definition: FixedString.h:1011
friend constexpr BasicFixedString< Char, N+M-1u > operator+(const BasicFixedString &a, const Char(&b)[M]) noexcept
Definition: FixedString.h:2860
constexpr BasicFixedString< Char, N+M > creplace(std::size_t this_pos, std::size_t this_count, const BasicFixedString< Char, M > &that, std::size_t that_pos, std::size_t that_count) const noexcept(false)
Definition: FixedString.h:1859
std::basic_string< Char > toStdString() const noexcept(false)
Definition: FixedString.h:815
constexpr std::size_t find_last_of(Char ch) const noexcept
Definition: FixedString.h:2508
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(const Char *first, const Char *last, std::size_t that_count, Char ch) noexcept(false)
Definition: FixedString.h:1788
void assertNotNullTerminated() noexcept
Definition: FixedString.h:83
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(const Char *first, const Char *last, const BasicFixedString< Char, M > &that) noexcept(false)
Definition: FixedString.h:1663
constexpr BasicFixedString< Char, N+M-1u > creplace(std::size_t this_pos, std::size_t this_count, const Char(&that)[M], std::size_t that_pos, std::size_t that_count) const noexcept(false)
Definition: FixedString.h:1960
constexpr std::size_t rfind(const Char *that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2198
constexpr BasicFixedString(const Char(&that)[M]) noexcept
Definition: FixedString.h:685
friend constexpr ReverseIterator operator+(std::ptrdiff_t i, ReverseIterator that) noexcept
Definition: FixedString.h:379
constexpr bool empty() const noexcept
Definition: FixedString.h:1076
FOLLY_CPP14_CONSTEXPR BasicFixedString & erase(std::size_t pos, std::size_t count=npos) noexcept(false)
Definition: FixedString.h:1457
std::uint32_t hsieh_hash32_buf(const void *buf, std::size_t len)
constexpr ordering compare_(const Left &left, std::size_t left_pos, std::size_t left_size, const Right &right, std::size_t right_pos, std::size_t right_size) noexcept
Definition: FixedString.h:111
friend constexpr bool operator!=(const BasicFixedString &a, Range< const Char * > b) noexcept
Definition: FixedString.h:2695
friend constexpr bool operator==(Range< const Char * > a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2653
static constexpr std::size_t max_size() noexcept
Definition: FixedString.h:1090
constexpr const Char * end() const noexcept
Definition: FixedString.h:1004
friend constexpr bool operator<=(const Char *a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2775
constexpr BasicFixedString(std::size_t count, Char ch) noexcept(false)
Definition: FixedString.h:714
constexpr BasicFixedString(const That &that, std::size_t size, folly::index_sequence< Is... >, std::size_t pos=0, std::size_t count=npos) noexcept
Definition: FixedString.h:534
constexpr reference operator[](std::ptrdiff_t i) const noexcept
Definition: FixedString.h:403
constexpr BasicFixedString< Char, N+M-1u > creplace(const Char *first, const Char *last, const Char(&that)[M], std::size_t that_pos, std::size_t that_count) const noexcept(false)
Definition: FixedString.h:2002
friend constexpr bool operator>(const Char *a, const BasicFixedString &b) noexcept
Definition: FixedString.h:2742
FOLLY_CPP14_CONSTEXPR reverse_iterator rbegin() noexcept
Definition: FixedString.h:1019
StringPiece data_
friend constexpr bool operator==(ReverseIterator a, ReverseIterator b) noexcept
Definition: FixedString.h:344
FOLLY_CPP14_CONSTEXPR BasicFixedString & replace(std::size_t this_pos, std::size_t this_count, const BasicFixedString< Char, M > &that, std::size_t that_pos=0u) noexcept(false)
Definition: FixedString.h:1679
constexpr std::size_t find_last_of(const Char *that, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2473
const Char & const_reference
Definition: FixedString.h:595
std::enable_if< IsLessThanComparable< Value >::value, bool >::type operator<(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
Definition: Expected.h:1321
friend constexpr bool operator>(const BasicFixedString &a, const Char *b) noexcept
Definition: FixedString.h:2751
FOLLY_CPP14_CONSTEXPR ReverseIterator & operator+=(std::ptrdiff_t i) noexcept
Definition: FixedString.h:375
constexpr std::size_t find_first_not_of_(const Left &left, std::size_t left_size, const Right &right, std::size_t pos, std::size_t count) noexcept
Definition: FixedString.h:231
constexpr detail::First first
Definition: Base-inl.h:2553
constexpr std::size_t length() const noexcept
Definition: FixedString.h:1069
constexpr BasicFixedString< Char, N+1u > cappend(Char ch) const noexcept
Definition: FixedString.h:1335
constexpr BasicFixedString< Char, N-1u > makeFixedString(const Char(&a)[N]) noexcept
Definition: FixedString.h:2991
constexpr const_reverse_iterator crbegin() const noexcept
Definition: FixedString.h:1033
constexpr std::size_t find_first_of(Char ch, std::size_t pos) const noexcept(false)
Definition: FixedString.h:2334
constexpr BasicFixedString(const BasicFixedString< Char, M > &that, std::size_t pos, std::size_t count) noexcept(false)
Definition: FixedString.h:660
constexpr std::size_t find_first_not_of(const Char *that) const noexcept
Definition: FixedString.h:2371
std::ostream & operator<<(std::ostream &out, dynamic const &d)
Definition: dynamic-inl.h:1158