morph
0.1.0
Asynchronous bridge between GUI thread and business models
Toggle main menu visibility
Loading...
Searching...
No Matches
fixed_string.hpp
Go to the documentation of this file.
1
// SPDX-License-Identifier: Apache-2.0
2
3
#pragma once
4
5
/// @file detail/fixed_string.hpp
6
/// @brief Shared compile-time, NTTP-capable fixed string.
7
8
#include <array>
9
#include <concepts>
10
#include <cstddef>
11
#include <string>
12
#include <string_view>
13
14
namespace
morph::detail {
15
16
/// @brief A structural, NTTP-capable compile-time string.
17
///
18
/// A literal type with public array storage, so it satisfies the rules for a
19
/// non-type template parameter. Two `FixedString` values of the same length
20
/// with the same characters compare equal as template arguments, so a type
21
/// parameterised on a `FixedString` written identically in two translation
22
/// units is one and the same type.
23
///
24
/// This is the single canonical definition. The forms layer aliases it twice —
25
/// as `morph::forms::FixedString` (used by `Choice`) and as
26
/// `morph::forms::detail::LiteralString` (which captures an `equals` rule
27
/// literal) — and the units layer once, as
28
/// `morph::units::detail::FixedString` (used by `NamedQuantity`). None of them
29
/// redefine their own copy.
30
///
31
/// @tparam N Storage size including the terminating null.
32
template
<std::
size_t
N>
33
struct
FixedString
{
34
/// @brief Character storage (null-terminated).
35
std::array<char, N>
data
{};
36
37
/// @brief Captures a string literal.
38
///
39
/// `constexpr`, not `consteval`: as an NTTP this is still only ever
40
/// evaluated at compile time (that context demands it regardless), but
41
/// `constexpr` additionally lets a *function parameter* of type
42
/// `const char (&)[N]` be captured — `morph::forms::equals(&A::code, "X")`
43
/// forwards its literal exactly that way, and a `consteval` constructor
44
/// cannot be called with a reference parameter, which is not itself a
45
/// constant expression.
46
///
47
/// @param literal The literal to copy, e.g. `"ListSamples"`.
48
// A NOLINTNEXTLINE directive must sit on ONE physical line to apply to the
49
// next one; wrapped, it silently annotates the comment instead. Hence the
50
// long lines below, and the clang-format guard around them.
51
// String literals ARE C arrays — that is the whole point of this type.
52
// clang-format off
53
// NOLINTNEXTLINE(modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays, cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-pro-bounds-avoid-unchecked-container-access)
54
constexpr
FixedString
(
const
char
(&literal)[N])
noexcept
{
55
for
(std::size_t index = 0; index < N; ++index) {
56
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-pro-bounds-avoid-unchecked-container-access)
57
data
[index] = literal[index];
58
}
59
}
60
// clang-format on
61
62
/// @brief A view of the string (without the terminating null).
63
/// @return The string contents.
64
[[nodiscard]]
constexpr
std::string_view
view
() const noexcept {
return
{
data
.data(), N - 1}; }
65
66
/// @brief Compares against any string-like value.
67
///
68
/// A hidden friend, so it is reachable by ADL from wherever a
69
/// `FixedString` is compared without polluting ordinary name lookup. Being
70
/// declared here rather than in an aliasing namespace matters: ADL keys on
71
/// the *type's* namespace (`morph::detail`), which an alias such as
72
/// `morph::forms::LiteralString` does not change.
73
///
74
/// @tparam S String-like operand type (`std::string` or `std::string_view`).
75
/// @param lhs Value to compare.
76
/// @param rhs Captured literal to compare against.
77
/// @return `true` if both hold the same characters.
78
template
<
typename
S>
79
requires
std::same_as<S, std::string> || std::same_as<S, std::string_view>
80
[[nodiscard]]
friend
constexpr
bool
operator==
(
const
S& lhs,
const
FixedString
& rhs)
noexcept
{
81
return
std::string_view{lhs} == rhs.view();
82
}
83
};
84
85
}
// namespace morph::detail
morph::detail::FixedString::operator==
friend constexpr bool operator==(const S &lhs, const FixedString &rhs) noexcept
Compares against any string-like value.
Definition
fixed_string.hpp:80
morph::detail::FixedString::FixedString
constexpr FixedString(const char(&literal)[N]) noexcept
Captures a string literal.
Definition
fixed_string.hpp:54
morph::detail::FixedString::view
constexpr std::string_view view() const noexcept
A view of the string (without the terminating null).
Definition
fixed_string.hpp:64
morph::detail::FixedString::data
std::array< char, N > data
Character storage (null-terminated).
Definition
fixed_string.hpp:35
morph
detail
fixed_string.hpp
Generated by
1.17.0