HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
fixed_string.hpp
1// Copyright Take Vos 2021-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "utility.hpp"
8#include "cast.hpp"
9#include "assert.hpp"
10#include <string>
11#include <string_view>
12#include <format>
13#include <array>
14#include <ranges>
15
16namespace hi::inline v1 {
17
35template<int N>
37 using value_type = char;
38
39 std::array<char, N> _str = {};
40
41 constexpr fixed_string() noexcept = default;
42 constexpr fixed_string(fixed_string const&) noexcept = default;
43 constexpr fixed_string(fixed_string&&) noexcept = default;
44 constexpr fixed_string& operator=(fixed_string const&) noexcept = default;
45 constexpr fixed_string& operator=(fixed_string&&) noexcept = default;
46
47 template<std::size_t O>
48 constexpr fixed_string(char const (&str)[O]) noexcept
49 requires((O - 1) == N)
50 {
51 for (auto i = 0_uz; i != (O - 1); ++i) {
52 _str[i] = str[i];
53 }
54 }
55
58 template<std::invocable F>
59 constexpr fixed_string(F const& f) noexcept
60 {
61 auto str = f();
62
63 hi_assert(str.size() == N);
64 for (auto i = 0_uz; i != str.size(); ++i) {
65 _str[i] = char_cast<char>(str[i]);
66 }
67 }
68
69 constexpr operator std::string_view() const noexcept
70 {
71 return std::string_view{_str.data(), size()};
72 }
73
74 constexpr operator std::string() const noexcept
75 {
76 return std::string{_str.data(), size()};
77 }
78
79 [[nodiscard]] constexpr std::size_t size() const noexcept
80 {
81 return N;
82 }
83
84 template<size_t I>
85 [[nodiscard]] constexpr friend char& get(fixed_string& a) noexcept
86 {
87 return std::get<I>(a._str);
88 }
89
90 template<size_t I>
91 [[nodiscard]] constexpr friend char const& get(fixed_string const& a) noexcept
92 {
93 return std::get<I>(a._str);
94 }
95
96 [[nodiscard]] constexpr char& operator[](size_t index) noexcept
97 {
98#ifndef NDEBUG
99 if (not(index < N)) {
101 }
102#endif
103 return _str[index];
104 }
105
106 [[nodiscard]] constexpr char const& operator[](size_t index) const noexcept
107 {
108#ifndef NDEBUG
109 if (not(index < N)) {
111 }
112#endif
113 return _str[index];
114 }
115
116 [[nodiscard]] constexpr auto begin() noexcept
117 {
118 return _str.begin();
119 }
120
121 [[nodiscard]] constexpr auto end() noexcept
122 {
123 return _str.begin() + size();
124 }
125
126 [[nodiscard]] constexpr bool operator==(fixed_string const& rhs) const noexcept = default;
127 [[nodiscard]] constexpr auto operator<=>(fixed_string const& rhs) const noexcept = default;
128
129 template<size_t O>
130 [[nodiscard]] constexpr bool operator==(fixed_string<O> const& rhs) const noexcept
131 requires(O != N)
132 {
133 return false;
134 }
135
136 template<size_t O>
137 [[nodiscard]] constexpr auto operator<=>(fixed_string<O> const& rhs) const noexcept
138 requires(O != N)
139 {
140 return static_cast<std::string_view>(*this) <=> static_cast<std::string_view>(rhs);
141 }
142
143 [[nodiscard]] constexpr bool operator==(std::string_view rhs) const noexcept
144 {
145 return static_cast<std::string_view>(*this) == rhs;
146 }
147
148 [[nodiscard]] constexpr auto operator<=>(std::string_view rhs) const noexcept
149 {
150 return static_cast<std::string_view>(*this) <=> rhs;
151 }
152
153 [[nodiscard]] constexpr bool operator==(std::string const& rhs) const noexcept
154 {
155 return static_cast<std::string_view>(*this) == rhs;
156 }
157
158 [[nodiscard]] constexpr auto operator<=>(std::string const& rhs) const noexcept
159 {
160 return static_cast<std::string_view>(*this) <=> rhs;
161 }
162
163 [[nodiscard]] constexpr bool operator==(char const *rhs) const noexcept
164 {
165 return static_cast<std::string_view>(*this) == rhs;
166 }
167
168 [[nodiscard]] constexpr auto operator<=>(char const *rhs) const noexcept
169 {
170 return static_cast<std::string_view>(*this) <=> rhs;
171 }
172
173 template<size_t O>
174 [[nodiscard]] constexpr bool operator==(char const (&rhs)[O]) const noexcept
175 {
176 return *this == fixed_string<O - 1>(rhs);
177 }
178
179 template<size_t O>
180 [[nodiscard]] constexpr auto operator<=>(char const (&rhs)[O]) const noexcept
181 {
182 return *this <=> fixed_string<O - 1>(rhs);
183 }
184
185 template<size_t O>
186 [[nodiscard]] constexpr auto operator+(fixed_string<O> const& rhs) const noexcept
187 {
188 auto r = fixed_string<N + O>{};
189 auto dst_i = 0_uz;
190 for (auto src_i = 0_uz; src_i != N; ++src_i, ++dst_i) {
191 r[dst_i] = (*this)[src_i];
192 }
193 for (auto src_i = 0_uz; src_i != O; ++src_i, ++dst_i) {
194 r[dst_i] = rhs[src_i];
195 }
196
197 return r;
198 }
199};
200
201template<fixed_string Tag>
202[[nodiscard]] consteval uint32_t fourcc() noexcept
203{
204 static_assert(Tag.size() == 4, "fourcc must get a 4 character fixed_string");
205
206 return (static_cast<uint32_t>(get<0>(Tag)) << 24) | (static_cast<uint32_t>(get<1>(Tag)) << 16) |
207 (static_cast<uint32_t>(get<2>(Tag)) << 8) | static_cast<uint32_t>(get<3>(Tag));
208}
209
210template<fixed_string Tag>
211consteval uint32_t operator"" _fcc()
212{
213 return fourcc<Tag>();
214}
215
216template<std::size_t N>
217fixed_string(char const (&str)[N]) -> fixed_string<N - 1>;
218
219template<std::invocable F>
220fixed_string(F const& f) -> fixed_string<std::ranges::size(F{}())>;
221
222#define hi_to_fixed_string(x) \
223 ::hi::fixed_string \
224 { \
225 [] { \
226 return x; \
227 } \
228 }
229
230} // namespace hi::inline v1
231
232template<std::size_t N, typename CharT>
233struct std::formatter<hi::fixed_string<N>, CharT> : std::formatter<std::string_view, CharT> {
234 constexpr auto format(hi::fixed_string<N> const& t, auto& fc)
235 {
236 return std::formatter<std::string_view, CharT>::format(static_cast<std::string_view>(t), fc);
237 }
238};
Utilities to assert and bound check.
#define hi_assert(expression,...)
Assert if expression is true.
Definition assert.hpp:184
Utilities used by the HikoGUI library itself.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
A string which may be used as a none-type template parameter.
Definition fixed_string.hpp:36
constexpr fixed_string(F const &f) noexcept
Create a fixed string from function returning a string-like.
Definition fixed_string.hpp:59
T begin(T... args)
T data(T... args)
T end(T... args)
T terminate(T... args)