File indexing completed on 2025-01-18 09:54:48
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <iomanip>
0011 #include <sstream>
0012 #include <string>
0013 #include <string_view>
0014 #include <utility>
0015 #include <vector>
0016
0017 #include "corecel/OpaqueId.hh"
0018 #include "corecel/cont/Array.hh"
0019 #include "corecel/cont/Span.hh"
0020 #include "corecel/data/Collection.hh"
0021 #include "corecel/math/Quantity.hh"
0022
0023 #include "Join.hh"
0024
0025 #include "detail/ReprImpl.hh"
0026
0027 namespace celeritas
0028 {
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 template<class T>
0044 detail::Repr<T> repr(T const& obj, char const* name = nullptr)
0045 {
0046 return {obj, name};
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template<class T>
0059 struct ReprTraits
0060 {
0061 static void print_type(std::ostream& os, char const* name = nullptr)
0062 {
0063 detail::print_simple_type(os, "UNKNOWN", name);
0064 }
0065 static void init(std::ostream&) {}
0066 static void print_value(std::ostream& os, T const& value) { os << value; }
0067 };
0068
0069 template<>
0070 struct ReprTraits<float>
0071 {
0072 static void print_type(std::ostream& os, char const* name = nullptr)
0073 {
0074 detail::print_simple_type(os, "float", name);
0075 }
0076 static void init(std::ostream& os) { os.precision(7); }
0077 static void print_value(std::ostream& os, float value)
0078 {
0079 os << value << 'f';
0080 }
0081 };
0082
0083 template<>
0084 struct ReprTraits<double>
0085 {
0086 static void print_type(std::ostream& os, char const* name = nullptr)
0087 {
0088 detail::print_simple_type(os, "double", name);
0089 }
0090 static void init(std::ostream& os) { os.precision(14); }
0091 static void print_value(std::ostream& os, double value) { os << value; }
0092 };
0093
0094 template<>
0095 struct ReprTraits<char>
0096 {
0097 static void print_type(std::ostream& os, char const* name = nullptr)
0098 {
0099 detail::print_simple_type(os, "char", name);
0100 }
0101 static void init(std::ostream&) {}
0102 static void print_value(std::ostream& os, char value)
0103 {
0104 os << '\'';
0105 detail::repr_char(os, value);
0106 os << '\'';
0107 }
0108 };
0109
0110 template<>
0111 struct ReprTraits<unsigned char>
0112 {
0113 static void print_type(std::ostream& os, char const* name = nullptr)
0114 {
0115 detail::print_simple_type(os, "unsigned char", name);
0116 }
0117 static void init(std::ostream& os) { os << std::setfill('0') << std::hex; }
0118 static void print_value(std::ostream& os, unsigned char value)
0119 {
0120 os << "'\\x" << detail::char_to_hex_string(value) << '\'';
0121 }
0122 };
0123
0124 template<>
0125 struct ReprTraits<bool>
0126 {
0127 static void print_type(std::ostream& os, char const* name = nullptr)
0128 {
0129 detail::print_simple_type(os, "bool", name);
0130 }
0131 static void init(std::ostream& os) { os << std::boolalpha; }
0132 static void print_value(std::ostream& os, bool value) { os << value; }
0133 };
0134
0135 template<>
0136 struct ReprTraits<int>
0137 {
0138 static void print_type(std::ostream& os, char const* name = nullptr)
0139 {
0140 detail::print_simple_type(os, "int", name);
0141 }
0142 static void init(std::ostream&) {}
0143 static void print_value(std::ostream& os, int value) { os << value; }
0144 };
0145
0146 template<>
0147 struct ReprTraits<unsigned int>
0148 {
0149 static void print_type(std::ostream& os, char const* name = nullptr)
0150 {
0151 detail::print_simple_type(os, "unsigned int", name);
0152 }
0153 static void init(std::ostream&) {}
0154 static void print_value(std::ostream& os, unsigned int value)
0155 {
0156 os << value << 'u';
0157 }
0158 };
0159
0160 template<>
0161 struct ReprTraits<long>
0162 {
0163 static void print_type(std::ostream& os, char const* name = nullptr)
0164 {
0165 detail::print_simple_type(os, "long", name);
0166 }
0167 static void init(std::ostream&) {}
0168 static void print_value(std::ostream& os, long value)
0169 {
0170 os << value << 'l';
0171 }
0172 };
0173
0174 template<>
0175 struct ReprTraits<unsigned long>
0176 {
0177 static void print_type(std::ostream& os, char const* name = nullptr)
0178 {
0179 detail::print_simple_type(os, "unsigned long", name);
0180 }
0181 static void init(std::ostream&) {}
0182 static void print_value(std::ostream& os, unsigned long value)
0183 {
0184 os << value << "ul";
0185 }
0186 };
0187
0188 template<>
0189 struct ReprTraits<long long>
0190 {
0191 static void print_type(std::ostream& os, char const* name = nullptr)
0192 {
0193 detail::print_simple_type(os, "long long", name);
0194 }
0195 static void init(std::ostream&) {}
0196 static void print_value(std::ostream& os, long long value)
0197 {
0198 os << value << "ll";
0199 }
0200 };
0201
0202 template<>
0203 struct ReprTraits<unsigned long long>
0204 {
0205 static void print_type(std::ostream& os, char const* name = nullptr)
0206 {
0207 detail::print_simple_type(os, "unsigned long long", name);
0208 }
0209 static void init(std::ostream&) {}
0210 static void print_value(std::ostream& os, unsigned long long value)
0211 {
0212 os << value << "ull";
0213 }
0214 };
0215
0216 template<>
0217 struct ReprTraits<std::string_view>
0218 {
0219 static void print_type(std::ostream& os, char const* name = nullptr)
0220 {
0221 detail::print_simple_type(os, "std::string_view", name);
0222 }
0223
0224 static void init(std::ostream&) {}
0225 static void print_value(std::ostream& os, std::string_view value)
0226 {
0227 using ssize = std::streamsize;
0228 ssize width = os.width();
0229 os.width(
0230 std::max(width - static_cast<ssize>(value.size()) - 2, ssize{0}));
0231
0232 if (value.size() > 70)
0233 {
0234
0235 os << "R\"(" << value << ")\"";
0236 return;
0237 }
0238
0239 os << '"';
0240 for (char c : value)
0241 {
0242 if (c == '\"')
0243 {
0244 os << '\\';
0245 }
0246 detail::repr_char(os, c);
0247 }
0248 os << '"';
0249 }
0250 };
0251
0252 template<>
0253 struct ReprTraits<std::string>
0254 {
0255 using value_type = std::string::value_type;
0256
0257 static void print_type(std::ostream& os, char const* name = nullptr)
0258 {
0259 detail::print_simple_type(os, "std::string", name);
0260 }
0261
0262 static void init(std::ostream&) {}
0263 static void print_value(std::ostream& os, std::string const& value)
0264 {
0265 ReprTraits<std::string_view>::print_value(os, value);
0266 }
0267 };
0268
0269 template<>
0270 struct ReprTraits<char*>
0271 {
0272 using value_type = char;
0273
0274 static void print_type(std::ostream& os, char const* name = nullptr)
0275 {
0276 detail::print_simple_type(os, "char const*", name);
0277 }
0278
0279 static void init(std::ostream&) {}
0280
0281 static void print_value(std::ostream& os, char const* value)
0282 {
0283 if (value)
0284 {
0285 ReprTraits<std::string_view>::print_value(os, value);
0286 }
0287 else
0288 {
0289 os << "nullptr";
0290 }
0291 }
0292 };
0293
0294 template<std::size_t N>
0295 struct ReprTraits<char[N]> : ReprTraits<char*>
0296 {
0297 };
0298
0299 template<>
0300 struct ReprTraits<char const*> : ReprTraits<char*>
0301 {
0302 };
0303
0304
0305 template<class T1, class T2>
0306 struct ReprTraits<std::pair<T1, T2>>
0307 {
0308 using RT1 = ReprTraits<T1>;
0309 using RT2 = ReprTraits<T2>;
0310
0311 static void print_type(std::ostream& os, char const* name = nullptr)
0312 {
0313 os << "std::pair<";
0314 RT1::print_type(os);
0315 os << ',';
0316 RT2::print_type(os);
0317 os << '>';
0318 if (name)
0319 {
0320 os << ' ' << name;
0321 }
0322 }
0323
0324 static void init(std::ostream& os)
0325 {
0326 RT1::init(os);
0327 RT2::init(os);
0328 }
0329
0330 static void print_value(std::ostream& os, std::pair<T1, T2> const& value)
0331 {
0332 os << '{';
0333 RT1::print_value(os, value.first);
0334 os << ',';
0335 RT2::print_value(os, value.second);
0336 os << '}';
0337 }
0338 };
0339
0340
0341 template<class V, class S>
0342 struct ReprTraits<OpaqueId<V, S>>
0343 {
0344 using RT = ReprTraits<S>;
0345
0346 static void print_type(std::ostream& os, char const* name = nullptr)
0347 {
0348 os << "OpaqueID<?>";
0349 if (name)
0350 {
0351 os << ' ' << name;
0352 }
0353 }
0354
0355 static void init(std::ostream& os) { RT::init(os); }
0356
0357 static void print_value(std::ostream& os, OpaqueId<V, S> const& value)
0358 {
0359 os << '{';
0360 if (value)
0361 {
0362 RT::print_value(os, value.unchecked_get());
0363 }
0364 os << '}';
0365 }
0366 };
0367
0368
0369 template<class U, class V>
0370 struct ReprTraits<Quantity<U, V>>
0371 {
0372 using RT = ReprTraits<V>;
0373
0374 static void print_type(std::ostream& os, char const* name = nullptr)
0375 {
0376 os << "Quantity<?,?>";
0377 if (name)
0378 {
0379 os << ' ' << name;
0380 }
0381 }
0382
0383 static void init(std::ostream& os) { RT::init(os); }
0384
0385 static void print_value(std::ostream& os, Quantity<U, V> const& q)
0386 {
0387 os << '{';
0388 RT::print_value(os, q.value());
0389 os << '}';
0390 }
0391 };
0392
0393
0394
0395
0396 template<class Container>
0397 struct ContTraits
0398 {
0399 using size_type = typename Container::size_type;
0400 using value_type = std::decay_t<typename Container::value_type>;
0401 };
0402
0403 template<class T, std::size_t N>
0404 struct ContTraits<T[N]>
0405 {
0406 using size_type = std::size_t;
0407 using value_type = std::decay_t<T>;
0408 };
0409
0410
0411
0412
0413 template<class Container>
0414 struct ContainerReprTraits
0415 {
0416 using value_type = typename ContTraits<Container>::value_type;
0417 using RT = ReprTraits<value_type>;
0418
0419 static void init(std::ostream& os) { RT::init(os); }
0420
0421 static void print_value(std::ostream& os, Container const& data)
0422 {
0423 os << '{'
0424 << join_stream(
0425 std::begin(data), std::end(data), ", ", RT::print_value);
0426 if (std::size(data) > 8)
0427 {
0428
0429 os << ',';
0430 }
0431 os << '}';
0432 }
0433 };
0434
0435 template<class T, class A>
0436 struct ReprTraits<std::vector<T, A>>
0437 : public ContainerReprTraits<std::vector<T, A>>
0438 {
0439 using value_type = std::decay_t<T>;
0440
0441 static void print_type(std::ostream& os, char const* name = nullptr)
0442 {
0443 detail::print_container_type<value_type>(os, "std::vector", name);
0444 }
0445 };
0446
0447 template<class T, size_type N>
0448 struct ReprTraits<Array<T, N>> : public ContainerReprTraits<Array<T, N>>
0449 {
0450 using value_type = std::decay_t<T>;
0451
0452 static void print_type(std::ostream& os, char const* name = nullptr)
0453 {
0454 os << "Array<";
0455 ReprTraits<value_type>::print_type(os);
0456 os << ',' << N << '>';
0457 if (name)
0458 {
0459 os << ' ' << name;
0460 }
0461 }
0462 };
0463
0464 template<class T, std::size_t N>
0465 struct ReprTraits<T[N]> : public ContainerReprTraits<T[N]>
0466 {
0467 using value_type = std::decay_t<T>;
0468
0469 static void print_type(std::ostream& os, char const* name = nullptr)
0470 {
0471 os << "Array<";
0472 ReprTraits<value_type>::print_type(os);
0473 os << ',' << N << '>';
0474 if (name)
0475 {
0476 os << ' ' << name;
0477 }
0478 }
0479 };
0480
0481 template<class T, std::size_t N>
0482 struct ReprTraits<Span<T, N>> : public ContainerReprTraits<Span<T, N>>
0483 {
0484 using value_type = std::decay_t<T>;
0485
0486 static void print_type(std::ostream& os, char const* name = nullptr)
0487 {
0488 detail::print_container_type<value_type>(os, "Span", name);
0489 }
0490 };
0491
0492
0493 template<class T, Ownership W, class I>
0494 struct ReprTraits<Collection<T, W, MemSpace::host, I>>
0495 {
0496 using ContainerT = Collection<T, W, MemSpace::host, I>;
0497 using value_type = typename ContainerT::value_type;
0498 using RT = ReprTraits<value_type>;
0499
0500 static void init(std::ostream& os) { RT::init(os); }
0501
0502 static void print_value(std::ostream& os, ContainerT const& data)
0503 {
0504 auto view = data[typename ContainerT::AllItemsT{}];
0505 os << '{'
0506 << join_stream(
0507 std::begin(view), std::end(view), ", ", RT::print_value)
0508 << '}';
0509 }
0510
0511 static void print_type(std::ostream& os, char const* name = nullptr)
0512 {
0513 detail::print_container_type<value_type>(os, "Collection", name);
0514 }
0515 };
0516
0517
0518 template<class T, Ownership W, class I>
0519 struct ReprTraits<Collection<T, W, MemSpace::device, I>>
0520 {
0521 using ContainerT = Collection<T, W, MemSpace::device, I>;
0522 using value_type = typename ContainerT::value_type;
0523
0524 static void init(std::ostream&) {}
0525
0526 static void print_value(std::ostream& os, ContainerT const& data)
0527 {
0528 auto view = data[typename ContainerT::AllItemsT{}];
0529 os << "<device collection, size=" << data.size() << '>';
0530 }
0531
0532 static void print_type(std::ostream& os, char const* name = nullptr)
0533 {
0534 detail::print_container_type<value_type>(os, "Collection", name);
0535 }
0536 };
0537
0538
0539 }