Skip to content

Commit 68b0285

Browse files
authored
Merge pull request #28 from rsl-org/feature/stringification
implement constexpr to_string and enum stringification
2 parents 80a15b7 + 9f4d627 commit 68b0285

File tree

18 files changed

+516
-328
lines changed

18 files changed

+516
-328
lines changed

include/rsl/_impl/format/fmt_parser.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
#include <rsl/string_view>
1010
#include <rsl/span>
11+
#include <rsl/serialize>
1112

12-
#include <rsl/_impl/util/to_string.hpp>
1313
#include <rsl/_impl/parser.hpp>
1414

1515
#include "accessor.hpp"
@@ -119,7 +119,7 @@ struct Replacement final : _impl::Parser {
119119
}
120120

121121
out.string += '{';
122-
out.string += util::utos(index);
122+
out.string += to_string(index);
123123
if (!specs.empty()) {
124124
out.string += ":";
125125
out.string += specs;
@@ -189,7 +189,7 @@ struct Replacement final : _impl::Parser {
189189
type = remove_cvref(type);
190190
std::meta::info accessor{};
191191
if (std::ranges::all_of(subfield, _impl::is_digit)) {
192-
index = util::stou(std::string_view{subfield});
192+
index = _serialize_impl::stou(std::string_view{subfield});
193193
if (is_subscriptable(type)) {
194194
// member access by subscript operator
195195
type = substitute(^^subscript_result, {type});
@@ -273,7 +273,7 @@ struct FormatParser : _impl::Parser {
273273
} break;
274274
case ReplacementType::indexed: {
275275
has_positional = true;
276-
index = util::stou(replacement.field);
276+
index = _serialize_impl::stou(replacement.field);
277277
if (direct[index] == -1) {
278278
result.accessors.push_back(get_arg_accessor(index));
279279
direct[index] = int(result.accessors.size() - 1);
@@ -289,7 +289,7 @@ struct FormatParser : _impl::Parser {
289289
throw "implicit 0. not allowed with more than one arg";
290290
}
291291
} else {
292-
index = util::stou(replacement.field.substr(0, dot_pos));
292+
index = _serialize_impl::stou(replacement.field.substr(0, dot_pos));
293293
replacement.field = replacement.field.substr(dot_pos + 1);
294294
}
295295
result.accessors.push_back(replacement.get_accessor(index, arg_types[index]));
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
#include <meta>
3+
#include <ranges>
4+
#include <algorithm>
5+
#include <bit>
6+
7+
namespace rsl::_serialize_impl {
8+
template <typename T>
9+
struct Enumerator {
10+
T value;
11+
char const* name;
12+
};
13+
14+
template <typename T>
15+
consteval auto sorted_enum_pairs() {
16+
auto enumerators =
17+
std::vector(std::from_range, enumerators_of(^^T) | std::views::transform([](auto e) {
18+
return Enumerator(extract<T>(constant_of(e)),
19+
define_static_string(identifier_of(e)));
20+
}));
21+
22+
using sort_t = std::make_unsigned_t<std::underlying_type_t<T>>;
23+
std::ranges::stable_sort(enumerators, std::ranges::greater{}, [](auto const& e) {
24+
return std::popcount(static_cast<sort_t>(e.value));
25+
});
26+
27+
return enumerators;
28+
}
29+
30+
} // namespace rsl::_serialize_impl
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#include <string>
44
#include <rsl/_impl/hash.hpp>
55

6-
namespace rsl::util {
7-
constexpr std::string to_string(std::meta::operators op) {
6+
namespace rsl::_serialize_impl {
7+
constexpr std::string op_to_string(std::meta::operators op) {
88
switch (op) {
99
using enum std::meta::operators;
1010
case op_new: return "new";
@@ -112,4 +112,4 @@ constexpr std::meta::operators to_operator(std::string_view text) {
112112
}
113113
return {};
114114
}
115-
} // namespace rsl::util
115+
} // namespace rsl::_impl
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
#include <string>
3+
#include <cstdint>
4+
5+
namespace rsl::_serialize_impl {
6+
constexpr std::string utos(std::uint64_t value) {
7+
std::string out{};
8+
do {
9+
out += static_cast<char>('0' + (value % 10U));
10+
value /= 10;
11+
} while (value > 0);
12+
return {out.rbegin(), out.rend()};
13+
}
14+
15+
constexpr std::uint64_t stou(std::string_view str) {
16+
unsigned result = 0;
17+
for (char const c : str) {
18+
(result *= 10) += c - '0';
19+
}
20+
return result;
21+
}
22+
} // namespace rsl::_serialize_impl

include/rsl/_impl/traits.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
#include <type_traits>
3+
4+
namespace rsl::_impl {
5+
template <class T>
6+
inline const bool is_signed_integer_v = false;
7+
template <>
8+
inline const bool is_signed_integer_v<signed char> = true;
9+
template <>
10+
inline const bool is_signed_integer_v<signed short> = true;
11+
template <>
12+
inline const bool is_signed_integer_v<signed int> = true;
13+
template <>
14+
inline const bool is_signed_integer_v<signed long> = true;
15+
template <>
16+
inline const bool is_signed_integer_v<signed long long> = true;
17+
18+
template <class T>
19+
inline const bool is_unsigned_integer_v = false;
20+
template <>
21+
inline const bool is_unsigned_integer_v<unsigned char> = true;
22+
template <>
23+
inline const bool is_unsigned_integer_v<unsigned short> = true;
24+
template <>
25+
inline const bool is_unsigned_integer_v<unsigned int> = true;
26+
template <>
27+
inline const bool is_unsigned_integer_v<unsigned long> = true;
28+
template <>
29+
inline const bool is_unsigned_integer_v<unsigned long long> = true;
30+
31+
template <class T>
32+
concept signed_integer = is_signed_integer_v<T>;
33+
34+
template <class T>
35+
concept unsigned_integer = is_unsigned_integer_v<T>;
36+
37+
template <class T>
38+
concept integer_type = signed_integer<T> or unsigned_integer<T>;
39+
} // namespace rsl::_impl

include/rsl/_impl/util/to_string.hpp

Lines changed: 0 additions & 47 deletions
This file was deleted.

include/rsl/assert

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
#include <rsl/source_location>
1212
#include <rsl/expect>
1313
#include <rsl/string_view>
14+
#include <rsl/serialize>
1415

15-
#include <rsl/_impl/util/to_string.hpp>
1616
#include <rsl/_impl/_config.h>
1717

1818
namespace rsl {
@@ -23,8 +23,8 @@ consteval void error() {
2323
}
2424

2525
constexpr std::string format_sloc(std::source_location sloc) {
26-
return std::string(sloc.file_name()) + ":" + util::to_string(sloc.line()) + ":" +
27-
util::to_string(sloc.column());
26+
return std::string(sloc.file_name()) + ":" + to_string(sloc.line()) + ":" +
27+
to_string(sloc.column());
2828
}
2929
} // namespace _error_impl
3030

0 commit comments

Comments
 (0)