-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcstring.h
121 lines (100 loc) · 2.65 KB
/
cstring.h
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
120
121
#pragma once
#include "sequence.h"
#include "traits.h"
#include <initializer_list>
#include <cstdint>
namespace cstp
{
template<int N>
class cstring
{
public:
using const_pointer = const char*;
using size_type = const std::size_t;
template<int... Is>
constexpr cstring(const_pointer ptr, sequence<Is...>) :
elems_{ ptr[Is]... }
{
}
constexpr cstring(char c) :
elems_{ c }
{
}
template<class... Ts>
constexpr cstring(char c, Ts... args) :
cstring<sizeof...(Ts) + 1>(cstring<1>(c) + cstring<sizeof...(Ts)>(args...))
{
static_assert(is_all_same<char, typename std::decay<Ts>::type...>::value, "all args should be char");
}
template<int M>
constexpr cstring(cstring<M>& cs) :
cstring<M>(cs.data(), generate_sequence<M>{})
{
}
template<int M>
constexpr cstring(const char(&arr)[M]) :
cstring<M - 1>(arr, generate_sequence<M - 1>{})
{
}
template<int M>
constexpr cstring<N + M> operator+(const cstring<M> cs) const
{
return concat_(cs, generate_sequence<N>{}, generate_sequence<M>{});
}
template<int M>
constexpr cstring<N + M - 1> operator+(const char(&arr)[M]) const
{
return *this + cstring<M - 1>(arr);
}
constexpr cstring<N + 1> operator+(char c) const
{
return *this + cstring<1>(c);
}
constexpr size_type size() const
{
return static_cast<size_type>(N);
}
constexpr const_pointer data() const
{
return elems_;
}
private:
const char elems_[N];
template<int M, int... Is, int... Js>
constexpr cstring<N + M> concat_(cstring<M> cs, sequence<Is...>, sequence<Js...>) const
{
const char temp[] = { elems_[Is]..., cs.data()[Js]... };
return { temp, generate_sequence<N + M>{} };
}
};
template<unsigned N>
inline constexpr cstring<N - 1>
to_cstr(const char(&arr)[N])
{
return cstring<N - 1>(arr);
}
inline constexpr cstring<1>
to_cstr(char c)
{
return c;
}
template<class... Ts>
inline constexpr cstring<sizeof...(Ts) + 1>
to_cstr(char c, Ts... args)
{
static_assert(is_all_same<char, typename std::decay<Ts>::type...>::value, "all args should be char");
return cstring<1>(c) + cstring<sizeof...(Ts)>(args...);
}
template<int N, int M>
inline constexpr cstring<N + M - 1>
operator+(const char(&arr)[M], cstring<N> cs)
{
return to_cstr(arr) + cs;
}
template<int N>
inline constexpr cstring<N + 1>
operator+(char c, cstring<N> cs)
{
return to_cstr(c) + cs;
}
} // namespace cstp