io.hh 14.7 KB
Newer Older
1
2
#pragma once

Philip Trettner's avatar
Philip Trettner committed
3
4
#include <sstream>
#include <string>
5

Philip Trettner's avatar
Philip Trettner committed
6
#include <typed-geometry/types/types.hh>
7

Philip Trettner's avatar
Philip Trettner committed
8
#include <typed-geometry/detail/tg_traits.hh>
Philip Trettner's avatar
Philip Trettner committed
9

10
11
namespace tg
{
12
13
template <class T>
std::string to_string(T const& v)
Philip Trettner's avatar
Philip Trettner committed
14
15
16
17
18
{
    std::ostringstream ss;
    ss << v;
    return ss.str();
}
19

20
21
namespace detail
{
22
23
template <class CharT, class StreamTraits>
std::basic_ostringstream<CharT, StreamTraits> temp_sstream(std::basic_ostream<CharT, StreamTraits> const& out)
24
{
25
    std::basic_ostringstream<CharT, StreamTraits> ss;
26
27
28
29
30
31
32
    ss.flags(out.flags());
    ss.imbue(out.getloc());
    ss.precision(out.precision());
    return ss;
}
}

Philip Trettner's avatar
Philip Trettner committed
33
34
35
36
//
// =============================== Random ===============================
//

37
38
template <class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, xorshift const& val)
Philip Trettner's avatar
Philip Trettner committed
39
40
41
42
43
44
{
    auto ss = detail::temp_sstream(out);
    ss << "rng(" << std::hex << val.state() << ")";
    return out << ss.str();
}

45
46
47
48
//
// =============================== Scalars ===============================
//

49
50
template <class T, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, angle_t<T> const& val)
51
{
52
53
    auto ss = detail::temp_sstream(out);
    ss << val.degree() << "°";
54
    return out << ss.str();
55
56
}

57
58
template <class T, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, fwd_diff<T> const& val)
59
60
61
62
63
64
{
    auto ss = detail::temp_sstream(out);
    ss << "<" << val.value << ", " << val.derivative << ">";
    return out << ss.str();
}

65
66
template <class T, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, interval<T> const& val)
67
68
69
70
{
    auto ss = detail::temp_sstream(out);
    ss << "[" << val.min << ".." << val.max << "]";
    return out << ss.str();
71
72
}

73
74
template <int w, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, fixed_uint<w> const& val)
75
{
Philip Trettner's avatar
Philip Trettner committed
76
    CharT buf[w * 20 + 1];
77
78
79
80
81
82
    auto const end = buf + sizeof(buf);
    auto begin = end;
    *(--begin) = '\0';
    auto u = val;
    while (u > 0)
    {
Philip Trettner's avatar
Philip Trettner committed
83
84
        auto const n = u64(u % 10u);
        u /= 10u;
Philip Trettner's avatar
Philip Trettner committed
85
        *(--begin) = CharT('0' + n);
86
87
    }
    if (begin + 1 == end)
Philip Trettner's avatar
Philip Trettner committed
88
        *(--begin) = CharT('0');
89
    return out << begin;
90
91
}

92
93
template <int w, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, fixed_int<w> const& val)
Julius Nehring-Wirxel's avatar
Julius Nehring-Wirxel committed
94
{
95
96
97
98
99
100
    if (val < 0)
    {
        out << '-';
        return out << fixed_uint<w>(-val);
    }
    return out << fixed_uint<w>(val);
Julius Nehring-Wirxel's avatar
Julius Nehring-Wirxel committed
101
102
}

103
104
105
106
//
// =============================== Comps ===============================
//

107
108
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, comp<D, ScalarT> const& val)
109
110
111
112
113
114
115
116
117
{
    auto ss = detail::temp_sstream(out);
    ss << type_name_prefix<ScalarT> << "comp" << char('0' + D);
    ss << "(";
    for (auto i = 0; i < D; ++i)
        ss << (i > 0 ? ", " : "") << val[i];
    ss << ")";
    return out << ss.str();
}
118
119
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, vec<D, ScalarT> const& val)
Philip Trettner's avatar
Philip Trettner committed
120
{
121
122
    auto ss = detail::temp_sstream(out);
    ss << type_name_prefix<ScalarT> << "vec" << char('0' + D);
123
    ss << "(";
Philip Trettner's avatar
Philip Trettner committed
124
    for (auto i = 0; i < D; ++i)
125
        ss << (i > 0 ? ", " : "") << val[i];
126
127
    ss << ")";
    return out << ss.str();
Philip Trettner's avatar
Philip Trettner committed
128
}
129
130
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, dir<D, ScalarT> const& val)
Philip Trettner's avatar
Philip Trettner committed
131
132
133
134
135
136
137
138
139
{
    auto ss = detail::temp_sstream(out);
    ss << type_name_prefix<ScalarT> << "dir" << char('0' + D);
    ss << "(";
    for (auto i = 0; i < D; ++i)
        ss << (i > 0 ? ", " : "") << val[i];
    ss << ")";
    return out << ss.str();
}
140
141
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, pos<D, ScalarT> const& val)
Philip Trettner's avatar
Philip Trettner committed
142
{
143
144
    auto ss = detail::temp_sstream(out);
    ss << type_name_prefix<ScalarT> << "pos" << char('0' + D);
145
    ss << "(";
Philip Trettner's avatar
Philip Trettner committed
146
    for (auto i = 0; i < D; ++i)
147
        ss << (i > 0 ? ", " : "") << val[i];
148
149
    ss << ")";
    return out << ss.str();
Philip Trettner's avatar
Philip Trettner committed
150
}
151
152
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, size<D, ScalarT> const& val)
Philip Trettner's avatar
Philip Trettner committed
153
{
154
155
    auto ss = detail::temp_sstream(out);
    ss << type_name_prefix<ScalarT> << "size" << char('0' + D);
156
    ss << "(";
Philip Trettner's avatar
Philip Trettner committed
157
    for (auto i = 0; i < D; ++i)
158
        ss << (i > 0 ? ", " : "") << val[i];
159
160
    ss << ")";
    return out << ss.str();
Philip Trettner's avatar
Philip Trettner committed
161
}
162
163
template <class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, color3 const& val)
Jonathan Kunstwald's avatar
Jonathan Kunstwald committed
164
165
166
167
168
{
    auto ss = detail::temp_sstream(out);
    ss << "color3(" << val.r << ", " << val.g << ", " << val.b << ")";
    return out << ss.str();
}
169
170
template <class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, color4 const& val)
Jonathan Kunstwald's avatar
Jonathan Kunstwald committed
171
172
173
174
175
{
    auto ss = detail::temp_sstream(out);
    ss << "color4(" << val.r << ", " << val.g << ", " << val.b << ", " << val.a << ")";
    return out << ss.str();
}
176
177
template <class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, quaternion<ScalarT> const& val)
178
179
180
181
182
183
{
    auto ss = detail::temp_sstream(out);
    ss << type_name_prefix<ScalarT> << "quat";
    ss << "(" << val.x << ", " << val.y << ", " << val.z << ", " << val.w << ")";
    return out << ss.str();
}
Philip Trettner's avatar
Philip Trettner committed
184

185
186
187
188
//
// =============================== Transformations ===============================
//

189
190
template <int C, int R, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, mat<C, R, ScalarT> const& val)
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
{
    auto ss = detail::temp_sstream(out);
    ss << type_name_prefix<ScalarT> << "mat";
    if (C == R)
        ss << char('0' + C);
    else
        ss << char('0' + C) << 'x' << char('0' + R);
    ss << "(";
    for (auto i = 0; i < C; ++i)
        ss << (i > 0 ? ", " : "") << val[i];
    ss << ")";
    return out << ss.str();
}

//
// =============================== Objects ===============================
//

209
210
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, line<D, ScalarT> const& val)
Philip Trettner's avatar
Philip Trettner committed
211
{
212
    auto ss = detail::temp_sstream(out);
213
214
    ss << type_name_prefix<ScalarT> << "line" << char('0' + D);
    ss << "(" << val.pos << ", " << val.dir << ")";
215
    return out << ss.str();
Philip Trettner's avatar
Philip Trettner committed
216
}
Kersten Schuster's avatar
Kersten Schuster committed
217

218
219
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, ray<D, ScalarT> const& val)
220
221
{
    auto ss = detail::temp_sstream(out);
222
223
    ss << type_name_prefix<ScalarT> << "ray" << char('0' + D);
    ss << "(" << val.origin << ", " << val.dir << ")";
224
225
226
    return out << ss.str();
}

227
228
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, segment<D, ScalarT> const& val)
Philip Trettner's avatar
Philip Trettner committed
229
230
{
    auto ss = detail::temp_sstream(out);
231
232
    ss << type_name_prefix<ScalarT> << "segment" << char('0' + D);
    ss << "(" << val.pos0 << ", " << val.pos1 << ")";
Philip Trettner's avatar
Philip Trettner committed
233
234
235
    return out << ss.str();
}

236

237
238
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, halfspace<D, ScalarT> const& val)
239
240
{
    auto ss = detail::temp_sstream(out);
241
242
    ss << type_name_prefix<ScalarT> << "halfspace" << char('0' + D);
    ss << "(" << val.normal << ", " << val.dis << ")";
243
244
    return out << ss.str();
}
245

246
247
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, plane<D, ScalarT> const& val)
248
249
{
    auto ss = detail::temp_sstream(out);
250
251
    ss << type_name_prefix<ScalarT> << (D == 3 ? "plane" : "plane") << char('0' + D);
    ss << "(" << val.normal << ", " << val.dis << ")";
252
253
254
    return out << ss.str();
}

255
256
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, triangle<D, ScalarT> const& val)
257
258
{
    auto ss = detail::temp_sstream(out);
259
260
    ss << type_name_prefix<ScalarT> << "triangle" << char('0' + D);
    ss << "(" << val.pos0 << ", " << val.pos1 << ", " << val.pos2 << ")";
261
262
263
    return out << ss.str();
}

264
265
template <int D, class ScalarT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, quad<D, ScalarT> const& val)
266
267
{
    auto ss = detail::temp_sstream(out);
268
269
    ss << type_name_prefix<ScalarT> << "quad" << char('0' + D);
    ss << "(" << val.pos00 << ", " << val.pos10 << ", " << val.pos11 << ", " << val.pos01 << ")";
270
271
272
273
    return out << ss.str();
}


274
275
template <int D, class ScalarT, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, aabb<D, ScalarT, TraitsT> const& val)
276
277
{
    auto ss = detail::temp_sstream(out);
278
    ss << type_name_prefix<ScalarT> << "aabb" << char('0' + D) << TraitsT::suffix;
279
    ss << "(" << val.min << ", " << val.max << ")";
280
281
282
    return out << ss.str();
}

283
284
template <int ObjectD, class ScalarT, int DomainD, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, box<ObjectD, ScalarT, DomainD, TraitsT> const& val)
285
286
{
    auto ss = detail::temp_sstream(out);
287
    ss << type_name_prefix<ScalarT> << "box" << char('0' + ObjectD);
288
289
    if constexpr (ObjectD != DomainD)
        ss << "in" << char('0' + DomainD);
290
291
    ss << TraitsT::suffix;
    ss << "(" << val.center << ", " << val.half_extents << ")";
292
293
294
    return out << ss.str();
}

Aaron Grabowy's avatar
Aaron Grabowy committed
295
296
297
298
299
300
301
302
303
304
305
306
template <int ObjectD, class ScalarT, int DomainD, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, ellipse<ObjectD, ScalarT, DomainD, TraitsT> const& val)
{
    auto ss = detail::temp_sstream(out);
    ss << type_name_prefix<ScalarT> << "ellipse" << char('0' + ObjectD);
    if constexpr (ObjectD != DomainD)
        ss << "in" << char('0' + DomainD);
    ss << TraitsT::suffix;
    ss << "(" << val.center << ", " << val.semi_axes << ")";
    return out << ss.str();
}

307
308
template <int ObjectD, class ScalarT, int DomainD, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, sphere<ObjectD, ScalarT, DomainD, TraitsT> const& val)
309
310
{
    auto ss = detail::temp_sstream(out);
311
    ss << type_name_prefix<ScalarT> << "sphere" << char('0' + ObjectD);
312
313
    if constexpr (ObjectD != DomainD)
        ss << "in" << char('0' + DomainD);
314
    ss << TraitsT::suffix;
315

316
317
318
319
    if constexpr (ObjectD == 2 && DomainD == 3)
        ss << "(" << val.center << ", " << val.radius << ", " << val.normal << ")";
    else
        ss << "(" << val.center << ", " << val.radius << ")";
320
321
322
    return out << ss.str();
}

323
324
template <int D, class ScalarT, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, capsule<D, ScalarT, TraitsT> const& val)
325
326
{
    auto ss = detail::temp_sstream(out);
327
    ss << type_name_prefix<ScalarT> << "capsule" << char('0' + D) << TraitsT::suffix;
328
    ss << "(" << val.axis << ", " << val.radius << ")";
329
330
331
    return out << ss.str();
}

332
333
template <int D, class ScalarT, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, cylinder<D, ScalarT, TraitsT> const& val)
334
335
{
    auto ss = detail::temp_sstream(out);
336
    ss << type_name_prefix<ScalarT> << "cylinder" << char('0' + D) << TraitsT::suffix;
337
    ss << "(" << val.axis << ", " << val.radius << ")";
338
339
340
    return out << ss.str();
}

341
342
template <int D, class ScalarT, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, hemisphere<D, ScalarT, TraitsT> const& val)
343
344
{
    auto ss = detail::temp_sstream(out);
345
    ss << type_name_prefix<ScalarT> << "hemisphere" << char('0' + D) << TraitsT::suffix;
346
    ss << "(" << val.center << ", " << val.radius << ", " << val.normal << ")";
347
348
349
    return out << ss.str();
}

350
351
template <int D, class ScalarT, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, inf_cone<D, ScalarT, TraitsT> const& val)
352
353
{
    auto ss = detail::temp_sstream(out);
354
    ss << type_name_prefix<ScalarT> << "inf_cone" << char('0' + D) << TraitsT::suffix;
355
    ss << "(" << val.apex << ", " << val.opening_dir << ", " << val.opening_angle << ")";
356
357
358
    return out << ss.str();
}

359
360
template <int D, class ScalarT, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, inf_cylinder<D, ScalarT, TraitsT> const& val)
361
362
{
    auto ss = detail::temp_sstream(out);
363
    ss << type_name_prefix<ScalarT> << "inf_cylinder" << char('0' + D) << TraitsT::suffix;
364
    ss << "(" << val.axis << ", " << val.radius << ")";
365
366
367
    return out << ss.str();
}

368
369
template <class BaseT, class TraitsT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, pyramid<BaseT, TraitsT> const& val)
370
{
371
    using ScalarT = typename BaseT::scalar_t;
372
    auto ss = detail::temp_sstream(out);
373
374
    ss << type_name_prefix<ScalarT> << "pyramid" << TraitsT::suffix;
    ss << "(" << val.base << ", " << val.height << ")";
375
376
377
    return out << ss.str();
}

378
379
380
381
382

//
// =============================== Bezier ===============================
//

383
384
template <int D, class ControlPointT, class CharT, class StreamTraits>
std::basic_ostream<CharT, StreamTraits>& operator<<(std::basic_ostream<CharT, StreamTraits>& out, bezier<D, ControlPointT> const& val)
385
386
387
388
389
390
391
392
393
394
{
    auto ss = detail::temp_sstream(out);
    ss << "bezier" << char('0' + D);
    ss << "(";
    ss << val.control_points[0];
    for (auto i = 1; i <= D; ++i)
        ss << ", " << val.control_points[i];
    ss << ")";
    return out << ss.str();
}
Philip Trettner's avatar
Philip Trettner committed
395
} // namespace tg