mimic++ v9.2.1
Loading...
Searching...
No Matches
String.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2024 - 2025.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_STRING_HPP
7#define MIMICPP_STRING_HPP
8
9#pragma once
10
11#include "mimic++/Fwd.hpp"
14
15#ifndef MIMICPP_DETAIL_IS_MODULE
16 #include <concepts>
17 #include <functional>
18 #include <ranges>
19 #include <string>
20 #include <string_view>
21 #include <type_traits>
22#endif
23
25{
89
100
105 template <typename T>
107 : public std::false_type
108 {
109 };
110
115 template <typename T>
117
121 template <>
122 struct is_character<char>
123 : public std::true_type
124 {
125 };
126
130 template <>
131 struct is_character<signed char>
132 : public std::true_type
133 {
134 };
135
139 template <>
140 struct is_character<unsigned char>
141 : public std::true_type
142 {
143 };
144
148 template <>
149 struct is_character<wchar_t>
150 : public std::true_type
151 {
152 };
153
157 template <>
158 struct is_character<char8_t>
159 : public std::true_type
160 {
161 };
162
166 template <>
167 struct is_character<char16_t>
168 : public std::true_type
169 {
170 };
171
175 template <>
176 struct is_character<char32_t>
177 : public std::true_type
178 {
179 };
180
184
194
199 template <util::satisfies<is_character> Char>
200 [[maybe_unused]]
202
206 template <>
207 [[maybe_unused]]
209
213 template <>
214 [[maybe_unused]]
216
220 template <>
221 [[maybe_unused]]
223
227 template <>
228 [[maybe_unused]]
230
234 template <>
235 [[maybe_unused]]
237
241
250
255 template <typename T>
256 using string_view_t = decltype(string_traits<std::remove_cvref_t<T>>::view(std::declval<T&>()));
257
262 template <typename T>
264
269 template <typename T>
270 requires std::is_pointer_v<T>
273 {
274 using char_t = std::remove_const_t<std::remove_pointer_t<T>>;
275 using view_t = std::basic_string_view<char_t>;
276
277 [[nodiscard]]
278 static constexpr view_t view(const std::remove_pointer_t<T>* str) noexcept
279 {
280 return view_t{str};
281 }
282 };
283
288 template <typename T>
289 requires std::is_array_v<T>
290 struct string_traits<T>
291 : public string_traits<std::remove_extent_t<T>*>
292 {
293 };
294
298 template <typename Char, typename Traits, typename Allocator>
299 struct string_traits<std::basic_string<Char, Traits, Allocator>>
300 {
301 using char_t = Char;
302 using string_t = std::basic_string<Char, Traits, Allocator>;
303 using view_t = std::basic_string_view<Char, Traits>;
304
305 [[nodiscard]]
306 static constexpr view_t view(const string_t& str) noexcept
307 {
308 return view_t{str};
309 }
310 };
311
315 template <typename Char, typename Traits>
316 struct string_traits<std::basic_string_view<Char, Traits>>
317 {
318 using char_t = Char;
319 using view_t = std::basic_string_view<Char, Traits>;
320
321 [[nodiscard]]
322 static constexpr view_t view(view_t str) noexcept
323 {
324 return str;
325 }
326 };
327
331
337 template <typename T>
338 concept string = requires {
340 requires std::regular<string_char_t<T>>;
341 requires std::ranges::contiguous_range<string_view_t<T>>;
342 requires std::ranges::sized_range<string_view_t<T>>;
343 requires std::ranges::borrowed_range<string_view_t<T>>;
344 requires std::same_as<
346 std::ranges::range_value_t<string_view_t<T>>>;
347 };
348
364
370 template <util::satisfies<is_character> Char>
372
378 template <typename String>
382 { std::invoke(converter, std::move(view)) } -> std::ranges::forward_range;
383 } && requires(std::invoke_result_t<string_case_fold_converter<string_char_t<String>>, string_view_t<String>> normalized) {
384 requires std::same_as<
386 std::ranges::range_value_t<decltype(normalized)>>;
387 };
388}
389
390namespace mimicpp::detail
391{
392 template <typename View, typename Char>
393 concept compatible_string_view_with = is_character_v<Char>
394 && std::ranges::borrowed_range<View>
395 && std::ranges::contiguous_range<View>
396 && std::ranges::sized_range<View>
397 && std::same_as<Char, std::ranges::range_value_t<View>>;
398}
399
400#ifndef MIMICPP_CONFIG_EXPERIMENTAL_UNICODE_STR_MATCHER
401
406template <>
408{
409 template <detail::compatible_string_view_with<char> String>
410 [[nodiscard]]
411 constexpr auto operator()(String&& str) const
412 {
413 return std::views::all(std::forward<String>(str))
414 | std::views::transform(
415 [](const char c) noexcept {
416 // see notes of https://en.cppreference.com/w/cpp/string/byte/toupper
417 // This approach will fail, if str actually contains an utf8-encoded string.
418 return static_cast<char>(
419 static_cast<unsigned char>(std::toupper(c)));
420 });
421 }
422};
423
424#else
425
426 #ifndef MIMICPP_DETAIL_IS_MODULE
427 #if __has_include(<uni_algo/case.h>) \
428 && __has_include(<uni_algo/conv.h>)
429 #include <uni_algo/case.h>
430 #include <uni_algo/conv.h>
431 #else
432 #error "Unable to find uni_algo includes."
433 #endif
434 #endif
435
440template <>
442{
443 template <detail::compatible_string_view_with<char> String>
444 [[nodiscard]]
445 constexpr auto operator()(String&& str) const
446 {
447 return una::cases::to_casefold_utf8(
448 std::string_view{
449 std::ranges::data(str),
450 std::ranges::size(str)});
451 }
452};
453
458template <>
460{
461 template <detail::compatible_string_view_with<wchar_t> String>
462 [[nodiscard]]
463 constexpr auto operator()(String&& str) const
464 {
465 return una::cases::to_casefold_utf16(
466 std::wstring_view{
467 std::ranges::data(str),
468 std::ranges::size(str)});
469 }
470};
471
476template <>
478{
479 template <detail::compatible_string_view_with<char8_t> String>
480 [[nodiscard]]
481 constexpr auto operator()(String&& str) const
482 {
483 return una::cases::to_casefold_utf8(
484 std::u8string_view{
485 std::ranges::data(str),
486 std::ranges::size(str)});
487 }
488};
489
494template <>
496{
497 template <detail::compatible_string_view_with<char16_t> String>
498 [[nodiscard]]
499 constexpr auto operator()(String&& str) const
500 {
501 return una::cases::to_casefold_utf16(
502 std::u16string_view{
503 std::ranges::data(str),
504 std::ranges::size(str)});
505 }
506};
507
512template <>
514{
515 template <detail::compatible_string_view_with<char32_t> String>
516 [[nodiscard]]
517 constexpr auto operator()(String&& str) const
518 {
519 return una::utf8to32<char8_t, char32_t>(
520 una::cases::to_casefold_utf8(
521 una::utf32to8u(
522 std::u32string_view{
523 std::ranges::data(str),
524 std::ranges::size(str)})));
525 }
526};
527
528#endif
529
530#endif
#define MIMICPP_DETAIL_MODULE_EXPORT
Definition Config.hpp:19
Determines, whether the given type supports string normalization.
Definition String.hpp:379
Determines, whether the given type can be used as a string-type.
Definition String.hpp:338
constexpr bool is_character_v
Convenience boolean-constant to the result of is_character trait.
Definition String.hpp:116
constexpr StringViewT string_literal_prefix
Primary template, yielding an empty string.
Definition String.hpp:201
decltype(string_traits< std::remove_cvref_t< T > >::view(std::declval< T & >())) string_view_t
Computes the view type for the given string.
Definition String.hpp:256
typename string_traits< std::remove_cvref_t< T > >::char_t string_char_t
Computes the character type for the given string.
Definition String.hpp:263
Definition Call.hpp:24
std::basic_string_view< CharT, CharTraitsT > StringViewT
Definition Fwd.hpp:392
Primary template, which always yields false.
Definition String.hpp:108
constexpr auto operator()(String &&str) const
Definition String.hpp:411
Primary template, purposely undefined.
Definition String.hpp:371
std::remove_const_t< std::remove_pointer_t< T > > char_t
Definition String.hpp:274
std::basic_string_view< char_t > view_t
Definition String.hpp:275
static constexpr view_t view(const std::remove_pointer_t< T > *str) noexcept
Definition String.hpp:278
std::basic_string_view< Char, Traits > view_t
Definition String.hpp:303
std::basic_string< Char, Traits, Allocator > string_t
Definition String.hpp:302
static constexpr view_t view(const string_t &str) noexcept
Definition String.hpp:306
static constexpr view_t view(view_t str) noexcept
Definition String.hpp:322
std::basic_string_view< Char, Traits > view_t
Definition String.hpp:319
Definition Fwd.hpp:377