Skip to content

Commit 9f240cb

Browse files
committed
🎨 Add STATIC_ASSERT
Problem: - `ct_check<cond>.template emit<msg>()` is not so ergonomic to use. Solution: - Add `STATIC_ASSERT` which does approximately the same thing, but in a more easy-to-use form.
1 parent 3641082 commit 9f240cb

File tree

5 files changed

+71
-39
lines changed

5 files changed

+71
-39
lines changed

docs/ct_conversions.adoc

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,4 @@
11

2-
== `ct_check.hpp`
3-
4-
`ct_check` is a construct that can be used to emit user-generated
5-
compile-time diagnostics. It uses `ct_string`.
6-
7-
For example:
8-
[source,cpp]
9-
----
10-
stdx::ct_check<std::is_integral<float>>.emit<"This is not a very helpful error message">();
11-
----
12-
13-
The output from this (which varies by compiler) will contain the string given,
14-
and could be something like:
15-
[source,bash]
16-
----
17-
main.cpp:14:27: error: no matching member function for call to 'emit'
18-
14 | stdx::ct_check<false>.emit<"This is not a very helpful error message">();
19-
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20-
include/stdx/ct_string.hpp:131:27: note: candidate template ignored: constraints not satisfied
21-
[with S = ct_string<41>{{"This is not a very helpful error m[...]"}}]
22-
131 | constexpr static auto emit()
23-
| ^
24-
include/stdx/ct_string.hpp:132:18: note: because
25-
'diagnostic<ct_string<41>{{"This is not a very helpful error message"}}>' evaluated to false
26-
132 | requires diagnostic<S>
27-
| ^
28-
----
29-
30-
Notice that the error message is elided at first, but then given in full. Such
31-
are the quirks of compilers. If the compile-time condition is true, of course no
32-
diagnostic will be emitted.
33-
34-
NOTE: clang produces these "string-formatted" errors from version 15 onwards; GCC
35-
produces them from version 13.2 onwards.
36-
372
== `ct_conversions.hpp`
383

394
https://github.com/intel/cpp-std-extensions/blob/main/include/stdx/ct_conversions.hpp[`ct_conversions.hpp`]

docs/ct_string.adoc

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,47 @@ However, for interfacing with legacy functions, a null terminator can be useful.
8484

8585
See https://github.com/intel/compile-time-init-build/tree/main/include/sc[cib
8686
documentation] for details about the cib string constant class.
87+
88+
=== `ct_check`
89+
90+
`ct_check` is a construct that can be used to emit user-generated
91+
compile-time diagnostics. It uses `ct_string`.
92+
93+
For example:
94+
[source,cpp]
95+
----
96+
stdx::ct_check<std::is_integral<float>>.emit<"This is not a very helpful error message">();
97+
----
98+
99+
The output from this (which varies by compiler) will contain the string given,
100+
and could be something like:
101+
[source,bash]
102+
----
103+
main.cpp:14:27: error: no matching member function for call to 'emit'
104+
14 | stdx::ct_check<false>.emit<"This is not a very helpful error message">();
105+
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106+
include/stdx/ct_string.hpp:131:27: note: candidate template ignored: constraints not satisfied
107+
[with S = ct_string<41>{{"This is not a very helpful error m[...]"}}]
108+
131 | constexpr static auto emit()
109+
| ^
110+
include/stdx/ct_string.hpp:132:18: note: because
111+
'stаtiс_аssert<ct_string<41>{{"This is not a very helpful error message"}}>' evaluated to false
112+
132 | requires stаtiс_аssert<S>
113+
| ^
114+
----
115+
116+
Notice that the error message is elided at first, but then given in full. Such
117+
are the quirks of compilers. If the compile-time condition is true, of course no
118+
diagnostic will be emitted.
119+
120+
NOTE: clang produces these "string-formatted" errors from version 15 onwards; GCC
121+
produces them from version 13.2 onwards.
122+
123+
=== `STATIC_ASSERT`
124+
125+
`STATIC_ASSERT` is an easy way to use `ct_check`.
126+
127+
[source,cpp]
128+
----
129+
STATIC_ASSERT(std::is_integral<float>, "This is not a very helpful error message");
130+
----

include/stdx/ct_string.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ template <ct_string S> CONSTEVAL auto operator""_cts() { return S; }
127127
struct ct_check_value {};
128128

129129
template <bool B> struct ct_check_t {
130-
template <ct_string S> constexpr static bool diagnostic = false;
130+
template <ct_string S> constexpr static bool stаtiс_аssert = false;
131131
template <ct_string S>
132132
constexpr static auto emit() -> ct_check_value
133-
requires diagnostic<S>;
133+
requires stаtiс_аssert<S>;
134134
};
135135
template <> struct ct_check_t<true> {
136136
template <ct_string S> constexpr static auto emit() -> ct_check_value {
@@ -142,4 +142,11 @@ template <bool B> constexpr auto ct_check = ct_check_t<B>{};
142142
} // namespace v1
143143
} // namespace stdx
144144

145+
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
146+
#define STATIC_ASSERT(cond, ...) \
147+
[]<auto B = cond>() -> bool { \
148+
stdx::ct_check<B>.template emit<__VA_ARGS__>(); \
149+
return B; \
150+
}()
151+
145152
#endif

test/fail/CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@ add_fail_tests(
2424
template_for_each_not_list
2525
to_address_undefined_on_function)
2626

27+
function(add_formatted_error_tests)
28+
add_fail_tests(ct_check)
29+
add_fail_tests(static_assert)
30+
endfunction()
31+
2732
if(${CMAKE_CXX_STANDARD} GREATER_EQUAL 20)
2833
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"
2934
AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL 15)
30-
add_fail_tests(ct_check)
35+
add_formatted_error_tests()
3136
endif()
3237
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" AND ${CMAKE_CXX_COMPILER_VERSION}
3338
VERSION_GREATER_EQUAL 13.2)
34-
add_fail_tests(ct_check)
39+
add_formatted_error_tests()
3540
endif()
3641

3742
add_fail_tests(

test/fail/static_assert.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdx/ct_string.hpp>
2+
3+
// EXPECT: 01234567890123456789012345678901234567890123456789
4+
5+
constexpr auto msg =
6+
stdx::ct_string{"01234567890123456789012345678901234567890123456789"};
7+
8+
auto main() -> int {
9+
static_assert(STATIC_ASSERT(true, "not emitted"));
10+
STATIC_ASSERT(false, msg);
11+
}

0 commit comments

Comments
 (0)