Skip to content

Commit 1180eb1

Browse files
committed
✨ Add formatting support for values from ct
Problem: - `CX_VALUE` is fine, but sometimes you have a `std::integral_constant` already. Solution: - Add compile-time formatting support for such values wrapped in types.
1 parent 6ae6338 commit 1180eb1

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

include/stdx/ct_format.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,30 @@ template <typename T>
100100
concept cx_value = requires { typename T::cx_value_t; } or
101101
requires(T t) { ct_string_from_type(t); };
102102

103-
CONSTEVAL auto arg_value(auto a) { return a; }
103+
template <typename T, T V>
104+
CONSTEVAL auto arg_value(std::integral_constant<T, V>) {
105+
if constexpr (std::is_enum_v<T>) {
106+
return enum_as_string<V>();
107+
} else {
108+
return V;
109+
}
110+
}
104111

105112
template <typename T> CONSTEVAL auto arg_value(type_identity<T>) {
106113
return type_as_string<T>();
107114
}
108115

116+
template <ct_string S> CONSTEVAL auto arg_value(cts_t<S>) { return S; }
117+
109118
CONSTEVAL auto arg_value(cx_value auto a) {
110119
if constexpr (requires { ct_string_from_type(a); }) {
111120
return ct_string_from_type(a);
112121
} else if constexpr (std::is_enum_v<decltype(a())>) {
113122
return enum_as_string<a()>();
114-
} else {
123+
} else if constexpr (requires { arg_value(a()); }) {
115124
return arg_value(a());
125+
} else {
126+
return a();
116127
}
117128
}
118129

@@ -156,7 +167,7 @@ CONSTEVAL auto convert_output() {
156167
}
157168

158169
template <ct_string Fmt, typename Arg> constexpr auto format1(Arg arg) {
159-
if constexpr (cx_value<Arg>) {
170+
if constexpr (requires { arg_value(arg); }) {
160171
return [&] {
161172
constexpr auto fmtstr = FMT_COMPILE(std::string_view{Fmt});
162173
constexpr auto a = arg_value(arg);

include/stdx/ct_string.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ operator+(ct_string<N> const &lhs,
114114
return ret;
115115
}
116116

117-
template <stdx::ct_string S> struct cts_t {
117+
template <ct_string S> struct cts_t {
118118
constexpr static auto value = S;
119119
};
120120

test/ct_format.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ TEST_CASE("format a static string", "[ct_format]") {
3434
static_assert(stdx::ct_format<"Hello">() == "Hello"_fmt_res);
3535
}
3636

37-
TEST_CASE("format a compile-time stringish argument", "[ct_format]") {
37+
TEST_CASE("format a compile-time stringish argument (CX_VALUE)",
38+
"[ct_format]") {
3839
using namespace std::string_view_literals;
3940
static_assert(stdx::ct_format<"Hello {}">(CX_VALUE("world"sv)) ==
4041
"Hello world"_fmt_res);
@@ -44,16 +45,34 @@ TEST_CASE("format a compile-time stringish argument", "[ct_format]") {
4445
"Hello world"_fmt_res);
4546
}
4647

47-
TEST_CASE("format a compile-time integral argument", "[ct_format]") {
48+
TEST_CASE("format a compile-time stringish argument (ct)", "[ct_format]") {
49+
using namespace std::string_view_literals;
50+
static_assert(stdx::ct_format<"Hello {}">("world"_ctst) ==
51+
"Hello world"_fmt_res);
52+
static_assert(stdx::ct_format<"Hello {}">(stdx::ct<"world">()) ==
53+
"Hello world"_fmt_res);
54+
}
55+
56+
TEST_CASE("format a compile-time integral argument (CX_VALUE)", "[ct_format]") {
4857
static_assert(stdx::ct_format<"Hello {}">(CX_VALUE(42)) ==
4958
"Hello 42"_fmt_res);
5059
}
5160

52-
TEST_CASE("format a type argument", "[ct_format]") {
61+
TEST_CASE("format a compile-time integral argument (ct)", "[ct_format]") {
62+
static_assert(stdx::ct_format<"Hello {}">(stdx::ct<42>()) ==
63+
"Hello 42"_fmt_res);
64+
}
65+
66+
TEST_CASE("format a type argument (CX_VALUE)", "[ct_format]") {
5367
static_assert(stdx::ct_format<"Hello {}">(CX_VALUE(int)) ==
5468
"Hello int"_fmt_res);
5569
}
5670

71+
TEST_CASE("format a type argument (ct)", "[ct_format]") {
72+
static_assert(stdx::ct_format<"Hello {}">(stdx::ct<int>()) ==
73+
"Hello int"_fmt_res);
74+
}
75+
5776
TEST_CASE("format a compile-time argument with fmt spec", "[ct_format]") {
5877
static_assert(stdx::ct_format<"Hello {:*>#6x}">(CX_VALUE(42)) ==
5978
"Hello **0x2a"_fmt_res);
@@ -63,11 +82,16 @@ namespace {
6382
enum struct E { A };
6483
}
6584

66-
TEST_CASE("format a compile-time enum argument", "[ct_format]") {
85+
TEST_CASE("format a compile-time enum argument (CX_VALUE)", "[ct_format]") {
6786
static_assert(stdx::ct_format<"Hello {}">(CX_VALUE(E::A)) ==
6887
"Hello A"_fmt_res);
6988
}
7089

90+
TEST_CASE("format a compile-time enum argument (ct)", "[ct_format]") {
91+
static_assert(stdx::ct_format<"Hello {}">(stdx::ct<E::A>()) ==
92+
"Hello A"_fmt_res);
93+
}
94+
7195
TEST_CASE("format a runtime argument", "[ct_format]") {
7296
constexpr auto x = 17;
7397
constexpr auto expected =

0 commit comments

Comments
 (0)