Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/rapidyaml/include/c4/std/tuple.hpp
4265 views
1
#ifndef _C4_STD_TUPLE_HPP_
2
#define _C4_STD_TUPLE_HPP_
3
4
/** @file tuple.hpp */
5
6
#ifndef C4CORE_SINGLE_HEADER
7
#include "c4/format.hpp"
8
#endif
9
10
#include <tuple>
11
12
/** this is a work in progress */
13
#undef C4_TUPLE_TO_CHARS
14
15
namespace c4 {
16
17
#ifdef C4_TUPLE_TO_CHARS
18
namespace detail {
19
20
template< size_t Curr, class... Types >
21
struct tuple_helper
22
{
23
static size_t do_cat(substr buf, std::tuple< Types... > const& tp)
24
{
25
size_t num = to_chars(buf, std::get<Curr>(tp));
26
buf = buf.len >= num ? buf.sub(num) : substr{};
27
num += tuple_helper< Curr+1, Types... >::do_cat(buf, tp);
28
return num;
29
}
30
31
static size_t do_uncat(csubstr buf, std::tuple< Types... > & tp)
32
{
33
size_t num = from_str_trim(buf, &std::get<Curr>(tp));
34
if(num == csubstr::npos) return csubstr::npos;
35
buf = buf.len >= num ? buf.sub(num) : substr{};
36
num += tuple_helper< Curr+1, Types... >::do_uncat(buf, tp);
37
return num;
38
}
39
40
template< class Sep >
41
static size_t do_catsep_more(substr buf, Sep const& sep, std::tuple< Types... > const& tp)
42
{
43
size_t ret = to_chars(buf, sep), num = ret;
44
buf = buf.len >= ret ? buf.sub(ret) : substr{};
45
ret = to_chars(buf, std::get<Curr>(tp));
46
num += ret;
47
buf = buf.len >= ret ? buf.sub(ret) : substr{};
48
ret = tuple_helper< Curr+1, Types... >::do_catsep_more(buf, sep, tp);
49
num += ret;
50
return num;
51
}
52
53
template< class Sep >
54
static size_t do_uncatsep_more(csubstr buf, Sep & sep, std::tuple< Types... > & tp)
55
{
56
size_t ret = from_str_trim(buf, &sep), num = ret;
57
if(ret == csubstr::npos) return csubstr::npos;
58
buf = buf.len >= ret ? buf.sub(ret) : substr{};
59
ret = from_str_trim(buf, &std::get<Curr>(tp));
60
if(ret == csubstr::npos) return csubstr::npos;
61
num += ret;
62
buf = buf.len >= ret ? buf.sub(ret) : substr{};
63
ret = tuple_helper< Curr+1, Types... >::do_uncatsep_more(buf, sep, tp);
64
if(ret == csubstr::npos) return csubstr::npos;
65
num += ret;
66
return num;
67
}
68
69
static size_t do_format(substr buf, csubstr fmt, std::tuple< Types... > const& tp)
70
{
71
auto pos = fmt.find("{}");
72
if(pos != csubstr::npos)
73
{
74
size_t num = to_chars(buf, fmt.sub(0, pos));
75
size_t out = num;
76
buf = buf.len >= num ? buf.sub(num) : substr{};
77
num = to_chars(buf, std::get<Curr>(tp));
78
out += num;
79
buf = buf.len >= num ? buf.sub(num) : substr{};
80
num = tuple_helper< Curr+1, Types... >::do_format(buf, fmt.sub(pos + 2), tp);
81
out += num;
82
return out;
83
}
84
else
85
{
86
return format(buf, fmt);
87
}
88
}
89
90
static size_t do_unformat(csubstr buf, csubstr fmt, std::tuple< Types... > & tp)
91
{
92
auto pos = fmt.find("{}");
93
if(pos != csubstr::npos)
94
{
95
size_t num = pos;
96
size_t out = num;
97
buf = buf.len >= num ? buf.sub(num) : substr{};
98
num = from_str_trim(buf, &std::get<Curr>(tp));
99
out += num;
100
buf = buf.len >= num ? buf.sub(num) : substr{};
101
num = tuple_helper< Curr+1, Types... >::do_unformat(buf, fmt.sub(pos + 2), tp);
102
out += num;
103
return out;
104
}
105
else
106
{
107
return tuple_helper< sizeof...(Types), Types... >::do_unformat(buf, fmt, tp);
108
}
109
}
110
111
};
112
113
/** @todo VS compilation fails for this class */
114
template< class... Types >
115
struct tuple_helper< sizeof...(Types), Types... >
116
{
117
static size_t do_cat(substr /*buf*/, std::tuple<Types...> const& /*tp*/) { return 0; }
118
static size_t do_uncat(csubstr /*buf*/, std::tuple<Types...> & /*tp*/) { return 0; }
119
120
template< class Sep > static size_t do_catsep_more(substr /*buf*/, Sep const& /*sep*/, std::tuple<Types...> const& /*tp*/) { return 0; }
121
template< class Sep > static size_t do_uncatsep_more(csubstr /*buf*/, Sep & /*sep*/, std::tuple<Types...> & /*tp*/) { return 0; }
122
123
static size_t do_format(substr buf, csubstr fmt, std::tuple<Types...> const& /*tp*/)
124
{
125
return to_chars(buf, fmt);
126
}
127
128
static size_t do_unformat(csubstr buf, csubstr fmt, std::tuple<Types...> const& /*tp*/)
129
{
130
return 0;
131
}
132
};
133
134
} // namespace detail
135
136
template< class... Types >
137
inline size_t cat(substr buf, std::tuple< Types... > const& tp)
138
{
139
return detail::tuple_helper< 0, Types... >::do_cat(buf, tp);
140
}
141
142
template< class... Types >
143
inline size_t uncat(csubstr buf, std::tuple< Types... > & tp)
144
{
145
return detail::tuple_helper< 0, Types... >::do_uncat(buf, tp);
146
}
147
148
template< class Sep, class... Types >
149
inline size_t catsep(substr buf, Sep const& sep, std::tuple< Types... > const& tp)
150
{
151
size_t num = to_chars(buf, std::cref(std::get<0>(tp)));
152
buf = buf.len >= num ? buf.sub(num) : substr{};
153
num += detail::tuple_helper< 1, Types... >::do_catsep_more(buf, sep, tp);
154
return num;
155
}
156
157
template< class Sep, class... Types >
158
inline size_t uncatsep(csubstr buf, Sep & sep, std::tuple< Types... > & tp)
159
{
160
size_t ret = from_str_trim(buf, &std::get<0>(tp)), num = ret;
161
if(ret == csubstr::npos) return csubstr::npos;
162
buf = buf.len >= ret ? buf.sub(ret) : substr{};
163
ret = detail::tuple_helper< 1, Types... >::do_uncatsep_more(buf, sep, tp);
164
if(ret == csubstr::npos) return csubstr::npos;
165
num += ret;
166
return num;
167
}
168
169
template< class... Types >
170
inline size_t format(substr buf, csubstr fmt, std::tuple< Types... > const& tp)
171
{
172
return detail::tuple_helper< 0, Types... >::do_format(buf, fmt, tp);
173
}
174
175
template< class... Types >
176
inline size_t unformat(csubstr buf, csubstr fmt, std::tuple< Types... > & tp)
177
{
178
return detail::tuple_helper< 0, Types... >::do_unformat(buf, fmt, tp);
179
}
180
#endif // C4_TUPLE_TO_CHARS
181
182
} // namespace c4
183
184
#endif /* _C4_STD_TUPLE_HPP_ */
185
186