-
Notifications
You must be signed in to change notification settings - Fork 3
/
formatter.hh
76 lines (54 loc) · 1.89 KB
/
formatter.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright (c) 2022 Mikael Simonsson <https://mikaelsimonsson.com>.
// SPDX-License-Identifier: BSL-1.0
// # Formatter primary template
#pragma once
#include "snn-core/core.hh"
namespace snn
{
// ## Classes
// ### formatter
// Must be specialized for a type to be formattable.
template <typename T, typename = void>
struct formatter
{
using type = T;
static_assert(meta::always_false<T>,
"Include the required header file or add a snn::formatter<...> "
"specialization to format this type.");
};
// ### formatter_override
// Can be specialized to override formatter<T>.
template <typename, typename = void>
struct formatter_override
{
using type = void;
};
// ## Type traits
// ### formatter_format_as
// Can be specialized to delegate to another formatter.
// The type must be implicitly convertible to the delegated type.
template <typename T>
struct formatter_format_as
{
using type = T;
};
template <typename T>
using formatter_format_as_t = typename formatter_format_as<T>::type;
// ### formatter_select
// Selects the formatter to use for a type. Should never be specialized.
template <typename T>
struct formatter_select_strict
{
using U = formatter_format_as_t<T>;
using type = std::conditional_t<std::is_same_v<U, typename formatter_override<U>::type>,
formatter_override<U>, formatter<U>>;
static_assert(std::is_same_v<typename type::type, U>,
"The selected formatter's type member is incorrect.");
};
template <typename T>
struct formatter_select : public formatter_select_strict<std::remove_cvref_t<T>>
{
};
template <typename T>
using formatter_select_t = typename formatter_select<T>::type;
}