-
Notifications
You must be signed in to change notification settings - Fork 0
/
ic.cc
119 lines (94 loc) · 2.98 KB
/
ic.cc
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <type_traits>
#include <cstddef>
#include <cstdint>
#include <tuple>
#include <utility>
template <class Int, Int v>
struct integral_constant : std::integral_constant<Int, v> {
// backport from C++14
constexpr Int operator()() const
{
return v;
}
};
template <char x>
using char_constant = integral_constant<char, x>;
template <size_t x>
using index_constant = integral_constant<size_t, x>;
template <bool x>
using bool_constant = integral_constant<bool, x>;
// utilities on extended integral_literal
template <class Tuple, class Int, Int index>
constexpr auto operator()(Tuple&& tuple, integral_constant<Int, index>)
-> decltype(std::get<index>(std::forward<Tuple>(tuple)))
{
return std::get<index>(std::forward<Tuple>(tuple));
}
template <class Int, Int base, size_t exp>
struct static_pow
: integral_constant<Int, base * static_pow<Int, base, exp-1>()>
{};
template <class Int, Int base>
struct static_pow<Int, base, 0>
: integral_constant<Int, 1>
{};
template <char ch, class=void>
struct digit_from_char : integral_constant<char, ch-'0'> {
static_assert('0'<=ch && ch<='9', "non-digit given");
};
template <char ch>
struct digit_from_char<ch, typename std::enable_if<('A'<=ch && ch<='F')>::type>
: integral_constant<char, ch-'A'+10>
{};
template <char ch>
struct digit_from_char<ch, typename std::enable_if<('a'<=ch && ch<='f')>::type>
: integral_constant<char, ch-'a'+10>
{};
template <class Int, Int base, Int... digits>
struct number_from_digits;
template <class Int, Int base, Int v>
struct number_from_digits<Int, base, v> {
static constexpr Int value = v;
};
template <class Int, Int base, Int first, Int... rest>
struct number_from_digits<Int, base, first, rest...> {
static constexpr Int value =
first*static_pow<Int, base, sizeof...(rest)>::value
+ number_from_digits<Int, base, rest...>::value;
};
template <class Int, char... ch>
struct number_from_chars
: number_from_digits<Int, 10, Int(digit_from_char<ch>::value)...>
{};
template <class Int>
struct number_from_chars<Int, '0'>
: integral_constant<Int, 0>
{};
template <class Int, char... ch>
struct number_from_chars<Int, '0', ch...>
: number_from_digits<Int, 8, Int(digit_from_char<ch>::value)...>
{};
template <class Int, char... ch>
struct number_from_chars<Int, '0', 'x', ch...>
: number_from_digits<Int, 16, Int(digit_from_char<ch>::value)...>
{};
template <class Int, char... ch>
struct number_from_chars<Int, '0', 'X', ch...>
: number_from_digits<Int, 16, Int(digit_from_char<ch>::value)...>
{};
template <char... ch>
integral_constant<uintmax_t, number_from_chars<uintmax_t, ch...>::value>
constexpr operator""_ic()
{
return {};
}
int main(int argc, char *argv[])
{
static_assert(123_ic==123, "dec");
static_assert(0123_ic==0123, "oct");
static_assert(0x123abc_ic==0x123abc, "hex lower");
static_assert(0X123ABC_ic==0X123ABC, "hex upper");
static_assert(std::make_tuple(1, 2, 3)(1_ic) == 2, "get tuple");
static_assert(std::make_pair(1, 2)(0_ic) == 1, "get pair");
return 0;
}