21#include "pw_assert/assert.h"
23namespace pw::string_impl {
27using size_type =
unsigned short;
31inline constexpr size_t kGeneric = size_type(-1);
34inline constexpr bool kUseStdCharTraits =
35#if !defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L
38 !std::is_same_v<T, std::byte>;
42template <
typename T,
bool = kUseStdCharTraits<T>>
45 using int_type =
unsigned int;
47 static constexpr void assign(T& dest,
const T& source)
noexcept {
51 static constexpr T* assign(T* dest,
size_t count, T value) {
52 for (
size_t i = 0; i < count; ++i) {
58 static constexpr bool eq(T lhs, T rhs) {
return lhs == rhs; }
60 static constexpr T* move(T* dest,
const T* source,
size_t count) {
63 }
else if (source < dest) {
64 for (
size_t i = count; i != 0; --i) {
71 static constexpr T* copy(T* dest,
const T* source,
size_t count) {
72 for (
size_t i = 0; i < count; ++i) {
78 static constexpr int compare(
const T* lhs,
const T* rhs,
size_t count) {
79 for (
size_t i = 0; i < count; ++i) {
80 if (lhs[i] < rhs[i]) {
83 if (rhs[i] < lhs[i]) {
101 using type = std::basic_string_view<T>;
106 using type = std::basic_string_view<std::byte, char_traits<std::byte>>;
110using View =
typename StringViewType<T>::type;
113template <
typename CharType,
typename T>
114using EnableIfNonArrayCharPointer = std::enable_if_t<
115 std::is_pointer<T>::value && !std::is_array<T>::value &&
116 std::is_same<CharType, std::remove_cv_t<std::remove_pointer_t<T>>>::value>;
118template <
typename CharType,
typename T>
119using EnableIfStringViewLike =
120 std::enable_if_t<std::is_convertible<const T&, View<CharType>>() &&
121 !std::is_convertible<const T&, const CharType*>()>;
123template <
typename CharType,
typename T>
124using EnableIfStringViewLikeButNotStringView =
125 std::enable_if_t<!std::is_same<T, View<CharType>>() &&
126 std::is_convertible<
const T&, View<CharType>>() &&
127 !std::is_convertible<const T&, const CharType*>()>;
130constexpr bool NullTerminatedArrayFitsInString(
131 size_t null_terminated_array_size,
size_t capacity) {
132 return null_terminated_array_size > 0u &&
133 null_terminated_array_size - 1 <= capacity &&
134 null_terminated_array_size - 1 < kGeneric;
139constexpr size_type CheckedCastToSize(T num) {
140 static_assert(std::is_unsigned<T>::value,
141 "Attempted to convert signed value to string length, but only "
142 "unsigned types are allowed.");
143 PW_ASSERT(num < std::numeric_limits<size_type>::max());
144 return static_cast<size_type
>(num);
156constexpr size_t BoundedStringLength(
const T*
string,
size_t capacity) {
158 for (; length <= capacity; ++length) {
159 if (char_traits<T>::eq(
string[length], T())) {
170constexpr size_t ArrayStringLength(
const T* array,
171 size_t max_string_length,
173 const size_t max_length = std::min(max_string_length, capacity);
174 const size_t length = BoundedStringLength(array, max_length);
175 PW_ASSERT(length <= max_string_length);
179template <
typename T,
size_t kCharArraySize>
180constexpr size_t ArrayStringLength(
const T (&array)[kCharArraySize],
182 static_assert(kCharArraySize > 0u,
"C arrays cannot have a length of 0");
183 static_assert(kCharArraySize - 1 < kGeneric,
184 "The size of this literal or character array is too large "
185 "for pw::InlineString<>::size_t");
186 return ArrayStringLength(
187 array,
static_cast<size_t>(kCharArraySize - 1), capacity);
192template <
typename InputIterator,
typename T>
193constexpr size_t IteratorCopy(InputIterator begin,
195 T*
const string_begin,
196 const T*
const string_end) {
197 T* current_position = string_begin;
203 typename std::iterator_traits<InputIterator>::iterator_category;
204 if constexpr (std::is_same_v<category, std::random_access_iterator_tag>) {
205 PW_ASSERT(begin <= end);
206 PW_ASSERT(end - begin <= string_end - string_begin);
207 for (InputIterator it = begin; it != end; ++it) {
208 char_traits<T>::assign(*current_position++, *it);
211 for (InputIterator it = begin; it != end; ++it) {
212 PW_ASSERT(current_position != string_end);
213 char_traits<T>::assign(*current_position++, *it);
216 return static_cast<size_t>(current_position - string_begin);
221constexpr int Compare(
const T* lhs,
224 size_t rhs_size)
noexcept {
225 int result = char_traits<T>::compare(lhs, rhs, std::min(lhs_size, rhs_size));
226 if (result != 0 || lhs_size == rhs_size) {
229 return lhs_size < rhs_size ? -1 : 1;
Definition: string_impl.h:100
Definition: string_impl.h:43