1template <std::size_t N>
2struct string_literal {
3 constexpr string_literal(char const (&str)[N]) {
4 std::copy_n(str, N, value);
5 }
6
7 friend bool operator==(string_literal const& s, char const* cause) {
8 return std::strncmp(s.value, cause, N) == 0;
9 }
10
11 operator char const*() const {
12 return value;
13 }
14
15 char value[N];
16};
17
18// default implementation
19template <string_literal C>
20inline constexpr auto handler = [] { std::cout << "default effect\n"; };
21
22#define _(name) template<> inline constexpr auto handler<#name>
23
24// opt-in customization points
25_(cause 1) = [] { std::cout << "customization points effect 1\n"; };
26_(cause 2) = [] { std::cout << "customization points effect 2\n"; };
27
28
29template <string_literal... Cs>
30struct dispatcher {
31 template <string_literal C>
32 constexpr auto execute_if(char const* cause) const {
33 if (C == cause) handler<C>();
34 }
35
36 constexpr auto execute(char const* cause) const {
37 (execute_if<Cs>(cause), ...);
38 }
39};
40
41int main() {
42 constexpr string_literal cause_1{ "cause 1" };
43 constexpr dispatcher<cause_1, "cause 2", "cause 3"> dispatch;
44 dispatch.execute(cause_1);
45 dispatch.execute("cause 2");
46 dispatch.execute("cause 3");
47}
1friend bool operator==(string_literal const& s, char const* cause) {
2 // return std::strncmp(s.value, cause, N) == 0;
3 return std::string_view(s.value) == cause;
4}
1template <auto> struct compile_time_param {};
2template <string_literal Data> inline auto compile_time_arg = compile_time_param<Data>{};
3
4template <string_literal... Cs>
5struct dispatcher {
6 // ...
7
8 template<string_literal s>
9 constexpr auto execute(compile_time_param<s>) const {
10 handler<s>();
11 }
12
13};
14
15_(cause 4) = [] { std::cout << "customization points effect 4\n"; };
16_(cause 5) = [] { std::cout << "customization points effect 5\n"; };
17
18
19int main() {
20 constexpr string_literal cause_1{ "cause 1" };
21 constexpr dispatcher<cause_1, "cause 2", "cause 3"> dispatch;
22 dispatch.execute(cause_1);
23 dispatch.execute("cause 2");
24 dispatch.execute("cause 3");
25
26
27 const char cause_5[] = "cause 5";
28
29 dispatch.execute(compile_time_arg<cause_1>); // OK
30 dispatch.execute(compile_time_arg<"cause 4">); // OK
31 dispatch.execute(compile_time_arg<cause_5>); // Error
32}