From 38783b8907b02fd952aeba9445173bebceb9cb53 Mon Sep 17 00:00:00 2001 From: hazby2002 <1094501217@qq.com> Date: Mon, 25 Dec 2023 23:56:35 +0800 Subject: [PATCH 01/17] Fix num_fields to support c-style arrays. --- include/rfl/internal/bind_to_tuple.hpp | 1559 +++++++++--------------- include/rfl/internal/has_n_fields.hpp | 41 - include/rfl/internal/num_fields.hpp | 73 +- 3 files changed, 623 insertions(+), 1050 deletions(-) delete mode 100644 include/rfl/internal/has_n_fields.hpp diff --git a/include/rfl/internal/bind_to_tuple.hpp b/include/rfl/internal/bind_to_tuple.hpp index bd973891..7bb5970e 100644 --- a/include/rfl/internal/bind_to_tuple.hpp +++ b/include/rfl/internal/bind_to_tuple.hpp @@ -8,7 +8,6 @@ #include #include "../always_false.hpp" -#include "has_n_fields.hpp" #include "is_named_tuple.hpp" namespace rfl { @@ -22,1006 +21,13 @@ constexpr auto bind_to_tuple(T& _t, const F& _f) { auto view = tuple_view(_t); return [&](std::index_sequence) { return std::make_tuple(_f(std::get(view))...); - } - (std::make_index_sequence>()); + }(std::make_index_sequence>()); } -/*The following boilerplate code was generated using a Python script: -def make_field_template(num: int) -> str: - fields = ", ".join([f"f{i+1}" for i in range(num)]) - ref_fields = ", ".join([f"f{i+1}" for i in range(num)]) - return ( - """ - } else if constexpr (has_n_fields) {""" - + ("auto& [" + fields + "] = _t;" if num > 0 else "") - + """ - return std::tie(""" - + ref_fields - + ");" - ) - -code = "".join((make_field_template(i) for i in range(101))) - -with open("generated_code4.cpp", "w", encoding="utf-8") as codefile: - codefile.write(code) -*/ - -template -constexpr auto tuple_view(T& _t) { - if constexpr (has_n_fields) { - return std::tie(); - } else if constexpr (has_n_fields) { - auto& [f1] = _t; - return std::tie(f1); - } else if constexpr (has_n_fields) { - auto& [f1, f2] = _t; - return std::tie(f1, f2); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3] = _t; - return std::tie(f1, f2, f3); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4] = _t; - return std::tie(f1, f2, f3, f4); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5] = _t; - return std::tie(f1, f2, f3, f4, f5); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6] = _t; - return std::tie(f1, f2, f3, f4, f5, f6); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, - f14); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15] = - _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28] = - _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, - f29] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42] = - _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, - f43] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56] = - _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, - f57] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70] = - _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, - f71] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84] = - _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, - f85] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92, f93] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92, f93); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92, f93, f94] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92, f93, f94); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92, f93, f94, f95] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92, f93, f94, f95); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92, f93, f94, f95, f96] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92, f93, f94, f95, f96); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, f97] = _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, f97); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, f97, f98] = - _t; - return std::tie(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, - f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, - f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, - f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, - f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, - f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, - f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, f97, f98); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, f97, f98, - f99] = _t; - return std::tie( - f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, - f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, - f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, - f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, - f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, - f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, f97, f98, f99); - } else if constexpr (has_n_fields) { - auto& [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, - f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, - f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, - f58, f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, - f72, f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, - f86, f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, f97, f98, f99, - f100] = _t; - return std::tie( - f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, - f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, - f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, - f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, - f59, f60, f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, - f73, f74, f75, f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, - f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, f97, f98, f99, f100); - - // --------------------------------- - // End of generated boilerplate code - // --------------------------------- - } else { +template +struct tuple_view_helper { + template + static constexpr auto tuple_view(T&) { static_assert( rfl::always_false_v, "\n\nThis error occurs for one of two reasons:\n\n" @@ -1035,6 +41,561 @@ constexpr auto tuple_view(T& _t) { "classes or custom parsers in the documentation " "for solutions to this problem.\n\n"); } +}; + +template <> +struct tuple_view_helper<0> { + static constexpr auto tuple_view(auto&) { return std::tie(); } +}; + +#define RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(n, ...) \ + template <> \ + struct tuple_view_helper { \ + static constexpr auto tuple_view(auto& t) { \ + auto& [__VA_ARGS__] = t; \ + return std::tie(__VA_ARGS__); \ + } \ + } + +/*The following boilerplate code was generated using a Python script: +macro = "RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER" +with open("generated_code4.cpp", "w", encoding="utf-8") as codefile: + codefile.write( + "\n".join( + [ + f"{macro}({i}, {', '.join([f'f{j}' for j in range(i)])});" + for i in range(1, 101) + ] + ) + ) +*/ + +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(1, f0); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(2, f0, f1); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(3, f0, f1, f2); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(4, f0, f1, f2, f3); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(5, f0, f1, f2, f3, f4); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(6, f0, f1, f2, f3, f4, f5); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(7, f0, f1, f2, f3, f4, f5, f6); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(8, f0, f1, f2, f3, f4, f5, f6, f7); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(9, f0, f1, f2, f3, f4, f5, f6, f7, f8); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(10, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(11, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(12, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(13, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(14, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(15, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(16, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(17, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(18, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(19, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(20, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(21, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(22, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(23, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(24, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(25, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(26, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(27, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(28, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(29, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(30, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(31, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(32, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(33, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(34, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(35, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(36, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(37, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(38, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(39, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(40, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(41, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(42, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(43, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(44, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(45, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(46, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(47, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(48, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(49, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(50, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(51, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(52, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(53, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(54, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52, f53); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(55, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52, f53, f54); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(56, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52, f53, f54, f55); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(57, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52, f53, f54, f55, f56); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 58, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 59, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 60, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 61, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(62, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52, f53, f54, f55, f56, + f57, f58, f59, f60, f61); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(63, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52, f53, f54, f55, f56, + f57, f58, f59, f60, f61, f62); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(64, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52, f53, f54, f55, f56, + f57, f58, f59, f60, f61, f62, f63); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(65, f0, f1, f2, f3, f4, f5, f6, f7, f8, + f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, + f25, f26, f27, f28, f29, f30, f31, f32, + f33, f34, f35, f36, f37, f38, f39, f40, + f41, f42, f43, f44, f45, f46, f47, f48, + f49, f50, f51, f52, f53, f54, f55, f56, + f57, f58, f59, f60, f61, f62, f63, f64); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 66, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 67, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 68, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 69, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 70, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 71, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 72, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 73, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 74, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 75, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 76, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 77, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 78, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 79, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 80, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 81, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 82, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 83, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 84, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 85, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 86, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 87, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 88, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 89, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 90, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 91, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 92, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 93, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91, f92); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 94, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91, f92, f93); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 95, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91, f92, f93, f94); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 96, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91, f92, f93, f94, f95); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 97, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91, f92, f93, f94, f95, f96); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 98, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91, f92, f93, f94, f95, f96, f97); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 99, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91, f92, f93, f94, f95, f96, f97, f98); +RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER( + 100, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, + f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, + f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, + f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, + f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, + f91, f92, f93, f94, f95, f96, f97, f98, f99); + +#undef RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER + +template +constexpr auto tuple_view(T& t) { + return tuple_view_helper>::tuple_view(t); } } // namespace internal diff --git a/include/rfl/internal/has_n_fields.hpp b/include/rfl/internal/has_n_fields.hpp deleted file mode 100644 index 453802c6..00000000 --- a/include/rfl/internal/has_n_fields.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef RFL_INTERNAL_HAS_N_FIELDS_HPP_ -#define RFL_INTERNAL_HAS_N_FIELDS_HPP_ - -#include -#include -#include - -#if __GNUC__ -#ifndef __clang__ -#pragma GCC system_header -#endif -#endif - -namespace rfl { -namespace internal { - -struct any { - template - constexpr operator T() const noexcept; -}; - -template -struct constructible_with_n_fields_impl : std::false_type {}; - -template -struct constructible_with_n_fields_impl< - T, std::index_sequence, - std::void_t> : std::true_type {}; - -template -using constructible_with_n_fields = - constructible_with_n_fields_impl>; - -template -constexpr bool has_n_fields = constructible_with_n_fields::value && - !constructible_with_n_fields::value; - -} // namespace internal -} // namespace rfl - -#endif diff --git a/include/rfl/internal/num_fields.hpp b/include/rfl/internal/num_fields.hpp index 8ec113d7..64d234f5 100644 --- a/include/rfl/internal/num_fields.hpp +++ b/include/rfl/internal/num_fields.hpp @@ -2,25 +2,78 @@ #define RFL_INTERNAL_NUM_FIELDS_HPP_ #include - -#include "has_n_fields.hpp" +#include +#include namespace rfl { namespace internal { -template -struct num_fields_impl { - static constexpr std::size_t value = num_fields_impl::value; +struct any { + any(std::size_t); + template + constexpr operator T() const noexcept; }; -template - requires has_n_fields -struct num_fields_impl { - static constexpr std::size_t value = _n; +template +struct count_fields_helper { + template + static consteval bool constructible() { + return [](std::index_sequence) { + return requires { T{any(is)...}; }; + }(std::make_index_sequence()); + } + + template + static consteval bool constructible_with_nested() { + return []( + std::index_sequence, std::index_sequence, + std::index_sequence) { + return requires { T{any(i)..., {any(j)...}, any(k)...}; }; + }(std::make_index_sequence(), std::make_index_sequence(), + std::make_index_sequence()); + } + + template + static consteval std::size_t count_max_fields() { + static_assert(n <= static_cast(sizeof(T))); + if constexpr (constructible() && !constructible()) { + return n; + } else { + return count_max_fields(); + } + } + + template + static consteval std::size_t get_nested_array_size() { + if constexpr (size < 1) { + return 1; + } else if constexpr (constructible_with_nested() && + !constructible_with_nested()) { + return size; + } else { + return get_nested_array_size(); + } + } + + template + static consteval std::size_t count_fields_impl() { + static_assert(index <= max); + if constexpr (index == max) { + return 0; + } else { + return 1 + + count_fields_impl< + index + get_nested_array_size(), max>(); + } + } + + static consteval std::size_t count_fields() { + return count_fields_impl<0, count_max_fields()>(); + } }; template -constexpr std::size_t num_fields = num_fields_impl::value; +constexpr std::size_t num_fields = count_fields_helper::count_fields(); } // namespace internal } // namespace rfl From 2d45ddfdc8a243f409a0e431e6149ab46faa555d Mon Sep 17 00:00:00 2001 From: hazby2002 <1094501217@qq.com> Date: Wed, 27 Dec 2023 01:24:23 +0800 Subject: [PATCH 02/17] Change all decay to remove_cvref. --- include/rfl/Flatten.hpp | 2 +- include/rfl/NamedTuple.hpp | 31 +- include/rfl/Result.hpp | 9 +- include/rfl/field_names_t.hpp | 2 +- include/rfl/flexbuf/OutputValue.hpp | 8 +- include/rfl/flexbuf/Reader.hpp | 8 +- include/rfl/from_named_tuple.hpp | 10 +- include/rfl/internal/Getter.hpp | 340 +++++++++--------- .../copy_flattened_tuple_to_named_tuple.hpp | 8 +- .../rfl/internal/extract_discriminators.hpp | 4 +- include/rfl/internal/find_index.hpp | 3 +- include/rfl/internal/get_field_names.hpp | 6 +- include/rfl/internal/has_fields.hpp | 4 +- include/rfl/internal/has_flatten_fields.hpp | 2 +- include/rfl/internal/is_attribute.hpp | 2 +- include/rfl/internal/is_basic_type.hpp | 9 +- .../internal/move_and_flatten_field_tuple.hpp | 28 +- .../move_field_tuple_to_named_tuple.hpp | 20 +- .../rfl/internal/move_from_named_tuple.hpp | 26 +- include/rfl/internal/move_from_tuple.hpp | 14 +- include/rfl/internal/move_to_field_tuple.hpp | 2 +- .../rfl/internal/no_duplicate_field_names.hpp | 48 ++- .../rfl/internal/nt_to_ptr_named_tuple.hpp | 4 +- include/rfl/internal/remove_fields.hpp | 8 +- include/rfl/internal/remove_ptrs_tup.hpp | 3 +- .../rfl/internal/to_flattened_ptr_tuple.hpp | 4 +- include/rfl/internal/to_ptr_field_tuple.hpp | 2 +- include/rfl/internal/to_ptr_named_tuple.hpp | 12 +- include/rfl/internal/to_ptr_tuple.hpp | 2 +- include/rfl/internal/wrap_in_fields.hpp | 13 +- include/rfl/json/Reader.hpp | 8 +- include/rfl/json/Writer.hpp | 8 +- include/rfl/make_named_tuple.hpp | 6 +- include/rfl/name_t.hpp | 2 +- include/rfl/named_tuple_t.hpp | 2 +- include/rfl/parsing/FieldVariantParser.hpp | 8 +- include/rfl/parsing/MapParser.hpp | 12 +- include/rfl/parsing/NamedTupleParser.hpp | 10 +- include/rfl/parsing/Parser_array.hpp | 4 +- include/rfl/parsing/Parser_box.hpp | 7 +- include/rfl/parsing/Parser_default.hpp | 10 +- include/rfl/parsing/Parser_optional.hpp | 7 +- include/rfl/parsing/Parser_ptr.hpp | 4 +- include/rfl/parsing/Parser_ref.hpp | 7 +- .../rfl/parsing/Parser_reference_wrapper.hpp | 4 +- include/rfl/parsing/Parser_rename.hpp | 7 +- include/rfl/parsing/Parser_result.hpp | 10 +- include/rfl/parsing/Parser_shared_ptr.hpp | 7 +- include/rfl/parsing/Parser_tagged_union.hpp | 10 +- include/rfl/parsing/Parser_unique_ptr.hpp | 7 +- include/rfl/parsing/Parser_variant.hpp | 6 +- include/rfl/parsing/TupleParser.hpp | 8 +- include/rfl/parsing/VectorParser.hpp | 15 +- include/rfl/parsing/is_map_like.hpp | 2 +- include/rfl/parsing/is_required.hpp | 2 +- include/rfl/parsing/is_vector_like.hpp | 2 +- include/rfl/remove_fields.hpp | 2 +- include/rfl/to_named_tuple.hpp | 8 +- include/rfl/xml/OutputValue.hpp | 8 +- include/rfl/xml/Reader.hpp | 12 +- include/rfl/xml/is_required_for_xml.hpp | 2 +- include/rfl/xml/write.hpp | 2 +- 62 files changed, 429 insertions(+), 414 deletions(-) diff --git a/include/rfl/Flatten.hpp b/include/rfl/Flatten.hpp index b5234436..3cd022fe 100644 --- a/include/rfl/Flatten.hpp +++ b/include/rfl/Flatten.hpp @@ -13,7 +13,7 @@ namespace rfl { template struct Flatten { /// The underlying type. - using Type = std::decay_t; + using Type = std::remove_cvref_t; Flatten(const Type& _value) : value_(_value) {} diff --git a/include/rfl/NamedTuple.hpp b/include/rfl/NamedTuple.hpp index ec98d36b..3a4cbfec 100644 --- a/include/rfl/NamedTuple.hpp +++ b/include/rfl/NamedTuple.hpp @@ -21,20 +21,23 @@ namespace rfl { template class NamedTuple { public: - using Fields = std::tuple...>; - using Values = std::tuple::type::Type...>; + using Fields = std::tuple...>; + using Values = + std::tuple::type::Type...>; public: /// Construct from the values. - NamedTuple(typename std::decay::type::Type&&... _values) - : values_(std::forward::type::Type>( - _values)...) { + NamedTuple(typename std::remove_cvref::type::Type&&... _values) + : values_( + std::forward::type::Type>( + _values)...) { static_assert(no_duplicate_field_names(), "Duplicate field names are not allowed"); } /// Construct from the values. - NamedTuple(const typename std::decay::type::Type&... _values) + NamedTuple( + const typename std::remove_cvref::type::Type&... _values) : values_(std::make_tuple(_values...)) { static_assert(no_duplicate_field_names(), "Duplicate field names are not allowed"); @@ -97,11 +100,11 @@ class NamedTuple { template auto add(Head&& _head, Tail&&... _tail) { if constexpr (sizeof...(Tail) > 0) { - return NamedTuple>( + return NamedTuple>( make_fields<1, Head>(std::forward(_head))) .add(std::forward(_tail)...); } else { - return NamedTuple>( + return NamedTuple>( make_fields<1, Head>(std::forward(_head))); } } @@ -110,11 +113,11 @@ class NamedTuple { template auto add(Head&& _head, Tail&&... _tail) const { if constexpr (sizeof...(Tail) > 0) { - return NamedTuple>( + return NamedTuple>( make_fields<1, Head>(std::forward(_head))) .add(std::forward(_tail)...); } else { - return NamedTuple>( + return NamedTuple>( make_fields<1, Head>(std::forward(_head))); } } @@ -331,7 +334,7 @@ class NamedTuple { // When we add additional fields, it is more intuitive to add // them to the end, that is why we do it like this. using FieldType = typename std::tuple_element::type; - using T = std::decay_t; + using T = std::remove_cvref_t; return make_fields( FieldType(std::forward(std::get(values_))), std::forward(_args)...); @@ -392,7 +395,7 @@ class NamedTuple { /// Replaced the field signified by the field type. template NamedTuple replace_value(T&& _val) { - using FieldType = std::decay_t; + using FieldType = std::remove_cvref_t; constexpr auto index = internal::find_index(); return make_replaced(std::forward(values_), std::forward(_val)); @@ -401,7 +404,7 @@ class NamedTuple { /// Replaced the field signified by the field type. template NamedTuple replace_value(T&& _val) const { - using FieldType = std::decay_t; + using FieldType = std::remove_cvref_t; constexpr auto index = internal::find_index(); auto values = values_; return make_replaced(std::move(values), @@ -446,7 +449,7 @@ class NamedTuple { using FieldType = typename std::tuple_element::type; - using T = std::decay_t; + using T = std::remove_cvref_t; return retrieve_fields( std::forward>(_other_fields), diff --git a/include/rfl/Result.hpp b/include/rfl/Result.hpp index 4c7dad5a..a6d564fc 100644 --- a/include/rfl/Result.hpp +++ b/include/rfl/Result.hpp @@ -79,7 +79,7 @@ class Result { const auto handle_variant = [&](TOrError&& _t_or_err) -> Result_U { - if constexpr (!std::is_same, Error>()) { + if constexpr (!std::is_same, Error>()) { return _f(std::forward(_t_or_err)); } else { return std::forward(_t_or_err); @@ -212,7 +212,7 @@ class Result { Result or_else(const F& _f) { const auto handle_variant = [&](TOrError&& _t_or_err) -> Result { - if constexpr (std::is_same, Error>()) { + if constexpr (std::is_same, Error>()) { return _f(std::forward(_t_or_err)); } else { return std::forward(_t_or_err); @@ -252,7 +252,7 @@ class Result { const auto handle_variant = [&](TOrError&& _t_or_err) -> rfl::Result { - if constexpr (!std::is_same, Error>()) { + if constexpr (!std::is_same, Error>()) { return _f(std::forward(_t_or_err)); } else { return std::forward(_t_or_err); @@ -311,7 +311,7 @@ class Result { /// Returns the value or a default. T value_or(T&& _default) noexcept { const auto handle_variant = [&](TOrError&& _t_or_err) -> T { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (!std::is_same()) { return std::forward(_t_or_err); } else { @@ -342,4 +342,3 @@ class Result { } // namespace rfl #endif - diff --git a/include/rfl/field_names_t.hpp b/include/rfl/field_names_t.hpp index 86771fa6..b37eebbf 100644 --- a/include/rfl/field_names_t.hpp +++ b/include/rfl/field_names_t.hpp @@ -11,7 +11,7 @@ namespace rfl { /// Returns a rfl::Literal containing the field names of struct T. template using field_names_t = typename std::invoke_result< - decltype(internal::get_field_names>)>::type; + decltype(internal::get_field_names>)>::type; } // namespace rfl diff --git a/include/rfl/flexbuf/OutputValue.hpp b/include/rfl/flexbuf/OutputValue.hpp index 3413c7b1..72d852d2 100644 --- a/include/rfl/flexbuf/OutputValue.hpp +++ b/include/rfl/flexbuf/OutputValue.hpp @@ -24,25 +24,25 @@ class OutputValue : public OutputVar { /// Inserts all elements into the builder. void insert(const std::optional& _key, flexbuffers::Builder* _fbb) final { - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { if (_key) { _fbb->String(_key->c_str(), val_); } else { _fbb->String(val_); } - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { if (_key) { _fbb->Bool(_key->c_str(), val_); } else { _fbb->Bool(val_); } - } else if constexpr (std::is_floating_point>()) { + } else if constexpr (std::is_floating_point>()) { if (_key) { _fbb->Double(_key->c_str(), val_); } else { _fbb->Double(val_); } - } else if constexpr (std::is_integral>()) { + } else if constexpr (std::is_integral>()) { if (_key) { _fbb->Int(_key->c_str(), val_); } else { diff --git a/include/rfl/flexbuf/Reader.hpp b/include/rfl/flexbuf/Reader.hpp index 284fd26e..9bca298c 100644 --- a/include/rfl/flexbuf/Reader.hpp +++ b/include/rfl/flexbuf/Reader.hpp @@ -59,22 +59,22 @@ struct Reader { template rfl::Result to_basic_type(const InputVarType& _var) const noexcept { - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { if (!_var.IsString()) { return rfl::Error("Could not cast to string."); } return std::string(_var.AsString().c_str()); - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { if (!_var.IsBool()) { return rfl::Error("Could not cast to boolean."); } return _var.AsBool(); - } else if constexpr (std::is_floating_point>()) { + } else if constexpr (std::is_floating_point>()) { if (!_var.IsNumeric()) { return rfl::Error("Could not cast to double."); } return static_cast(_var.AsDouble()); - } else if constexpr (std::is_integral>()) { + } else if constexpr (std::is_integral>()) { if (!_var.IsNumeric()) { return rfl::Error("Could not cast to int."); } diff --git a/include/rfl/from_named_tuple.hpp b/include/rfl/from_named_tuple.hpp index 2b0451c1..8a114e59 100644 --- a/include/rfl/from_named_tuple.hpp +++ b/include/rfl/from_named_tuple.hpp @@ -15,8 +15,9 @@ namespace rfl { /// Generates the struct T from a named tuple. template T from_named_tuple(NamedTupleType&& _n) { - using RequiredType = std::decay_t>; - if constexpr (!std::is_same, RequiredType>()) { + using RequiredType = std::remove_cvref_t>; + if constexpr (!std::is_same, + RequiredType>()) { return from_named_tuple(RequiredType(std::forward(_n))); } else if constexpr (internal::has_fields()) { if constexpr (std::is_lvalue_reference{}) { @@ -36,8 +37,9 @@ T from_named_tuple(NamedTupleType&& _n) { /// Generates the struct T from a named tuple. template T from_named_tuple(const NamedTupleType& _n) { - using RequiredType = std::decay_t>; - if constexpr (!std::is_same, RequiredType>()) { + using RequiredType = std::remove_cvref_t>; + if constexpr (!std::is_same, + RequiredType>()) { return from_named_tuple(RequiredType(_n)); } else if constexpr (internal::has_fields()) { return internal::copy_from_named_tuple(_n); diff --git a/include/rfl/internal/Getter.hpp b/include/rfl/internal/Getter.hpp index cad68c8d..cee1742a 100644 --- a/include/rfl/internal/Getter.hpp +++ b/include/rfl/internal/Getter.hpp @@ -21,66 +21,64 @@ struct Getter; /// Default case - anything that cannot be explicitly matched. template struct Getter { - public: - /// Retrieves the indicated value from the tuple. - template - static inline auto& get(NamedTupleType& _tup) { - return std::get<_index>(_tup.values()); - } - - /// Gets a field by name. - template - static inline auto& get(NamedTupleType& _tup) { - constexpr auto index = - find_index<_field_name, typename NamedTupleType::Fields>(); - return Getter::template get(_tup); - } - - /// Gets a field by the field type. - template - static inline auto& get(NamedTupleType& _tup) { - constexpr auto index = - find_index(); - static_assert( - std::is_same< - typename std::tuple_element< - index, typename NamedTupleType::Fields>::type::Type, - typename Field::Type>(), - "If two fields have the same name, " - "their type must be the same as " - "well."); - return Getter::template get(_tup); - } - - /// Retrieves the indicated value from the tuple. - template - static inline const auto& get_const(const NamedTupleType& _tup) { - return std::get<_index>(_tup.values()); - } - - /// Gets a field by name. - template - static inline const auto& get_const(const NamedTupleType& _tup) { - constexpr auto index = - find_index<_field_name, typename NamedTupleType::Fields>(); - return Getter::template get_const(_tup); - } - - /// Gets a field by the field type. - template - static inline const auto& get_const(const NamedTupleType& _tup) { - constexpr auto index = - find_index(); - static_assert( - std::is_same< - typename std::tuple_element< - index, typename NamedTupleType::Fields>::type::Type, - typename Field::Type>(), - "If two fields have the same name, " - "their type must be the same as " - "well."); - return Getter::template get_const(_tup); - } + public: + /// Retrieves the indicated value from the tuple. + template + static inline auto& get(NamedTupleType& _tup) { + return std::get<_index>(_tup.values()); + } + + /// Gets a field by name. + template + static inline auto& get(NamedTupleType& _tup) { + constexpr auto index = + find_index<_field_name, typename NamedTupleType::Fields>(); + return Getter::template get(_tup); + } + + /// Gets a field by the field type. + template + static inline auto& get(NamedTupleType& _tup) { + constexpr auto index = + find_index(); + static_assert( + std::is_same::type::Type, + typename Field::Type>(), + "If two fields have the same name, " + "their type must be the same as " + "well."); + return Getter::template get(_tup); + } + + /// Retrieves the indicated value from the tuple. + template + static inline const auto& get_const(const NamedTupleType& _tup) { + return std::get<_index>(_tup.values()); + } + + /// Gets a field by name. + template + static inline const auto& get_const(const NamedTupleType& _tup) { + constexpr auto index = + find_index<_field_name, typename NamedTupleType::Fields>(); + return Getter::template get_const(_tup); + } + + /// Gets a field by the field type. + template + static inline const auto& get_const(const NamedTupleType& _tup) { + constexpr auto index = + find_index(); + static_assert( + std::is_same::type::Type, + typename Field::Type>(), + "If two fields have the same name, " + "their type must be the same as " + "well."); + return Getter::template get_const(_tup); + } }; // ---------------------------------------------------------------------------- @@ -88,69 +86,69 @@ struct Getter { /// For handling std::variant. template struct Getter> { - public: - /// Retrieves the indicated value from the tuple. - template - static inline auto& get(std::variant& _tup) { - const auto apply = [](auto& _t) -> auto& { - using NamedTupleType = std::decay_t; - return Getter::template get<_index>(_t); - }; - return std::visit(apply, _tup); - } - - /// Gets a field by name. - template - static inline auto& get(std::variant& _tup) { - const auto apply = [](auto& _t) -> auto& { - using NamedTupleType = std::decay_t; - return Getter::template get<_field_name>(_t); - }; - return std::visit(apply, _tup); - } - - /// Gets a field by the field type. - template - static inline auto& get(std::variant& _tup) { - const auto apply = [](auto& _t) -> auto& { - using NamedTupleType = std::decay_t; - return Getter::template get(_t); - }; - return std::visit(apply, _tup); - } - - /// Retrieves the indicated value from the tuple. - template - static inline const auto& get_const( - const std::variant& _tup) { - const auto apply = [](const auto& _tup) -> const auto& { - using NamedTupleType = std::decay_t; - return Getter::template get_const<_index>(_tup); - }; - return std::visit(apply, _tup); - } - - /// Gets a field by name. - template - static inline const auto& get_const( - const std::variant& _tup) { - const auto apply = [](const auto& _t) -> const auto& { - using NamedTupleType = std::decay_t; - return Getter::template get_const<_field_name>(_t); - }; - return std::visit(apply, _tup); - } - - /// Gets a field by the field type. - template - static inline const auto& get_const( - const std::variant& _tup) { - const auto apply = [](const auto& _t) -> const auto& { - using NamedTupleType = std::decay_t; - return Getter::template get_const(_t); - }; - return std::visit(apply, _tup); - } + public: + /// Retrieves the indicated value from the tuple. + template + static inline auto& get(std::variant& _tup) { + const auto apply = [](auto& _t) -> auto& { + using NamedTupleType = std::remove_cvref_t; + return Getter::template get<_index>(_t); + }; + return std::visit(apply, _tup); + } + + /// Gets a field by name. + template + static inline auto& get(std::variant& _tup) { + const auto apply = [](auto& _t) -> auto& { + using NamedTupleType = std::remove_cvref_t; + return Getter::template get<_field_name>(_t); + }; + return std::visit(apply, _tup); + } + + /// Gets a field by the field type. + template + static inline auto& get(std::variant& _tup) { + const auto apply = [](auto& _t) -> auto& { + using NamedTupleType = std::remove_cvref_t; + return Getter::template get(_t); + }; + return std::visit(apply, _tup); + } + + /// Retrieves the indicated value from the tuple. + template + static inline const auto& get_const( + const std::variant& _tup) { + const auto apply = [](const auto& _tup) -> const auto& { + using NamedTupleType = std::remove_cvref_t; + return Getter::template get_const<_index>(_tup); + }; + return std::visit(apply, _tup); + } + + /// Gets a field by name. + template + static inline const auto& get_const( + const std::variant& _tup) { + const auto apply = [](const auto& _t) -> const auto& { + using NamedTupleType = std::remove_cvref_t; + return Getter::template get_const<_field_name>(_t); + }; + return std::visit(apply, _tup); + } + + /// Gets a field by the field type. + template + static inline const auto& get_const( + const std::variant& _tup) { + const auto apply = [](const auto& _t) -> const auto& { + using NamedTupleType = std::remove_cvref_t; + return Getter::template get_const(_t); + }; + return std::visit(apply, _tup); + } }; // ---------------------------------------------------------------------------- @@ -158,54 +156,54 @@ struct Getter> { /// For handling std::variant. template struct Getter> { - public: - /// Retrieves the indicated value from the tuple. - template - static inline auto& get( - TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { - return Getter>::template get<_index>( - _tu.variant_); - } - - /// Gets a field by name. - template - static inline auto& get( - TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { - return Getter>::template get< - _field_name>(_tu.variant_); - } - - /// Gets a field by the field type. - template - static inline auto& get( - TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { - return Getter>::template get( - _tu.variant_); - } - - /// Retrieves the indicated value from the tuple. - template - static inline const auto& get_const( - const TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { - return Getter>::template get_const< - _index>(_tu.variant_); - } - - /// Gets a field by name. - template - static inline const auto& get_const( - const TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { - return Getter>::template get_const< - _field_name>(_tu.variant_); - } - - /// Gets a field by the field type. - template - static inline const auto& get_const( - const TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { - return Getter>::template get_const< - Field>(_tu.variant_); - } + public: + /// Retrieves the indicated value from the tuple. + template + static inline auto& get( + TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { + return Getter>::template get<_index>( + _tu.variant_); + } + + /// Gets a field by name. + template + static inline auto& get( + TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { + return Getter>::template get<_field_name>( + _tu.variant_); + } + + /// Gets a field by the field type. + template + static inline auto& get( + TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { + return Getter>::template get( + _tu.variant_); + } + + /// Retrieves the indicated value from the tuple. + template + static inline const auto& get_const( + const TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { + return Getter>::template get_const<_index>( + _tu.variant_); + } + + /// Gets a field by name. + template + static inline const auto& get_const( + const TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { + return Getter>::template get_const< + _field_name>(_tu.variant_); + } + + /// Gets a field by the field type. + template + static inline const auto& get_const( + const TaggedUnion<_discriminator, NamedTupleTypes...>& _tu) { + return Getter>::template get_const( + _tu.variant_); + } }; // ---------------------------------------------------------------------------- diff --git a/include/rfl/internal/copy_flattened_tuple_to_named_tuple.hpp b/include/rfl/internal/copy_flattened_tuple_to_named_tuple.hpp index e7616884..0d9ae912 100644 --- a/include/rfl/internal/copy_flattened_tuple_to_named_tuple.hpp +++ b/include/rfl/internal/copy_flattened_tuple_to_named_tuple.hpp @@ -16,15 +16,15 @@ template auto copy_flattened_tuple_to_named_tuple(const auto& _flattened_tuple, Fields&&... _fields) { constexpr auto size = - std::tuple_size_v>; + std::tuple_size_v>; constexpr auto i = sizeof...(_fields); if constexpr (i == size) { return make_named_tuple(std::move(_fields)...); } else { const auto name_literal = FieldNames::template name_of(); - auto new_field = - rfl::make_field>>( - std::get(_flattened_tuple)); + auto new_field = rfl::make_field< + lit_name_v>>( + std::get(_flattened_tuple)); return copy_flattened_tuple_to_named_tuple( _flattened_tuple, std::move(_fields)..., std::move(new_field)); } diff --git a/include/rfl/internal/extract_discriminators.hpp b/include/rfl/internal/extract_discriminators.hpp index ced132b2..a56c04fb 100644 --- a/include/rfl/internal/extract_discriminators.hpp +++ b/include/rfl/internal/extract_discriminators.hpp @@ -15,8 +15,8 @@ struct extract_discriminators; template struct extract_discriminators> { - using type = define_literal_t< - std::decay_t>...>; + using type = define_literal_t< + std::remove_cvref_t>...>; }; } // namespace internal diff --git a/include/rfl/internal/find_index.hpp b/include/rfl/internal/find_index.hpp index 3d1d2fff..fa028781 100644 --- a/include/rfl/internal/find_index.hpp +++ b/include/rfl/internal/find_index.hpp @@ -12,7 +12,8 @@ namespace internal { /// Finds the index of the field signified by _field_name template constexpr static int find_index() { - using FieldType = std::decay_t::type>; + using FieldType = + std::remove_cvref_t::type>; constexpr bool name_i_matches = (FieldType::name_ == _field_name); diff --git a/include/rfl/internal/get_field_names.hpp b/include/rfl/internal/get_field_names.hpp index 70359e9d..96fa05f8 100644 --- a/include/rfl/internal/get_field_names.hpp +++ b/include/rfl/internal/get_field_names.hpp @@ -75,13 +75,13 @@ auto get_field_names(); template auto get_field_name() { - using Type = std::decay_t::Type>>; if constexpr (is_rename_v) { using Name = typename Type::Name; return Name(); } else if constexpr (is_flatten_field_v) { - return get_field_names>(); + return get_field_names>(); } else { return rfl::Literal()>(); } @@ -114,7 +114,7 @@ template #endif #endif auto get_field_names() { - if constexpr (std::is_pointer_v>) { + if constexpr (std::is_pointer_v>) { return get_field_names>(); } else { constexpr auto ptr_tuple = to_ptr_tuple(fake_object); diff --git a/include/rfl/internal/has_fields.hpp b/include/rfl/internal/has_fields.hpp index 6844f736..1f4e2f5d 100644 --- a/include/rfl/internal/has_fields.hpp +++ b/include/rfl/internal/has_fields.hpp @@ -18,7 +18,7 @@ constexpr bool all_fields_or_flatten() { if constexpr (_i == std::tuple_size_v) { return true; } else { - using T = std::decay_t>; + using T = std::remove_cvref_t>; if constexpr (is_flatten_field_v) { return all_fields_or_flatten< ptr_tuple_t::Type>>() && @@ -34,7 +34,7 @@ constexpr bool some_fields_or_flatten() { if constexpr (_i == std::tuple_size_v) { return false; } else { - using T = std::decay_t>; + using T = std::remove_cvref_t>; if constexpr (is_flatten_field_v) { return some_fields_or_flatten< ptr_tuple_t::Type>>() || diff --git a/include/rfl/internal/has_flatten_fields.hpp b/include/rfl/internal/has_flatten_fields.hpp index 2eef11b6..19241d95 100644 --- a/include/rfl/internal/has_flatten_fields.hpp +++ b/include/rfl/internal/has_flatten_fields.hpp @@ -15,7 +15,7 @@ constexpr bool has_flatten_fields() { if constexpr (_i == std::tuple_size_v) { return false; } else { - using T = std::decay_t>; + using T = std::remove_cvref_t>; return is_flatten_field_v || has_flatten_fields(); } } diff --git a/include/rfl/internal/is_attribute.hpp b/include/rfl/internal/is_attribute.hpp index ce47198e..97d44416 100644 --- a/include/rfl/internal/is_attribute.hpp +++ b/include/rfl/internal/is_attribute.hpp @@ -28,7 +28,7 @@ template class is_attribute*> : public std::true_type {}; template -constexpr bool is_attribute_v = is_attribute>::value; +constexpr bool is_attribute_v = is_attribute>::value; } // namespace internal } // namespace rfl diff --git a/include/rfl/internal/is_basic_type.hpp b/include/rfl/internal/is_basic_type.hpp index f4d0ad1b..a5b4ad6d 100644 --- a/include/rfl/internal/is_basic_type.hpp +++ b/include/rfl/internal/is_basic_type.hpp @@ -8,10 +8,11 @@ namespace rfl { namespace internal { template -constexpr bool is_basic_type_v = std::is_floating_point_v> || - std::is_integral_v> || - std::is_same, std::string>() || - std::is_same, bool>(); +constexpr bool is_basic_type_v = + std::is_floating_point_v> || + std::is_integral_v> || + std::is_same, std::string>() || + std::is_same, bool>(); } // namespace internal } // namespace rfl diff --git a/include/rfl/internal/move_and_flatten_field_tuple.hpp b/include/rfl/internal/move_and_flatten_field_tuple.hpp index 5124eff3..1df49854 100644 --- a/include/rfl/internal/move_and_flatten_field_tuple.hpp +++ b/include/rfl/internal/move_and_flatten_field_tuple.hpp @@ -11,22 +11,22 @@ namespace internal { template auto move_and_flatten_field_tuple(FieldTuple&& _t, Args&&... _args) { - constexpr auto i = sizeof...(Args); - if constexpr (i == std::tuple_size_v>) { - return std::tuple_cat(std::move(_args)...); + constexpr auto i = sizeof...(Args); + if constexpr (i == std::tuple_size_v>) { + return std::tuple_cat(std::move(_args)...); + } else { + using T = std::tuple_element_t>; + if constexpr (is_flatten_field::value) { + return move_and_flatten_field_tuple( + std::move(_t), std::move(_args)..., + move_and_flatten_field_tuple( + move_to_field_tuple(std::move(std::get(_t).value_)))); } else { - using T = std::tuple_element_t>; - if constexpr (is_flatten_field::value) { - return move_and_flatten_field_tuple( - std::move(_t), std::move(_args)..., - move_and_flatten_field_tuple( - move_to_field_tuple(std::move(std::get(_t).value_)))); - } else { - return move_and_flatten_field_tuple( - std::move(_t), std::move(_args)..., - std::make_tuple(std::move(std::get(_t)))); - } + return move_and_flatten_field_tuple( + std::move(_t), std::move(_args)..., + std::make_tuple(std::move(std::get(_t)))); } + } } } // namespace internal diff --git a/include/rfl/internal/move_field_tuple_to_named_tuple.hpp b/include/rfl/internal/move_field_tuple_to_named_tuple.hpp index 24dabd68..070e2659 100644 --- a/include/rfl/internal/move_field_tuple_to_named_tuple.hpp +++ b/include/rfl/internal/move_field_tuple_to_named_tuple.hpp @@ -13,17 +13,17 @@ namespace internal { template auto move_field_tuple_to_named_tuple(FieldTuple&& _field_tuple) { - const auto ft_to_nt = [](Fields&&... _fields) { - return make_named_tuple(std::move(_fields)...); - }; + const auto ft_to_nt = [](Fields&&... _fields) { + return make_named_tuple(std::move(_fields)...); + }; - if constexpr (!has_flatten_fields>()) { - return std::apply(ft_to_nt, std::move(_field_tuple)); - } else { - auto flattened_tuple = - move_and_flatten_field_tuple(std::move(_field_tuple)); - return std::apply(ft_to_nt, std::move(flattened_tuple)); - } + if constexpr (!has_flatten_fields>()) { + return std::apply(ft_to_nt, std::move(_field_tuple)); + } else { + auto flattened_tuple = + move_and_flatten_field_tuple(std::move(_field_tuple)); + return std::apply(ft_to_nt, std::move(flattened_tuple)); + } } } // namespace internal diff --git a/include/rfl/internal/move_from_named_tuple.hpp b/include/rfl/internal/move_from_named_tuple.hpp index 55dbcc9f..b01930c1 100644 --- a/include/rfl/internal/move_from_named_tuple.hpp +++ b/include/rfl/internal/move_from_named_tuple.hpp @@ -17,13 +17,15 @@ template auto make_ptr_fields(PtrNamedTupleType& _n, Args... _args) { constexpr auto i = sizeof...(Args); - constexpr auto size = std::tuple_size_v>; + constexpr auto size = + std::tuple_size_v>; if constexpr (i == size) { return std::make_tuple(_args...); } else { - using Field = std::decay_t>; - using T = std::decay_t>; + using Field = + std::remove_cvref_t>; + using T = std::remove_cvref_t>; if constexpr (is_named_tuple_v) { using SubPtrNamedTupleType = @@ -34,7 +36,7 @@ auto make_ptr_fields(PtrNamedTupleType& _n, Args... _args) { _n, _args..., SubPtrNamedTupleType(_n).fields()); } else if constexpr (is_flatten_field::value) { - using SubPtrFieldTupleType = std::decay_t>; + using SubPtrFieldTupleType = std::remove_cvref_t>; return make_ptr_fields( _n, _args..., make_ptr_fields(_n)); @@ -49,10 +51,10 @@ auto make_ptr_fields(PtrNamedTupleType& _n, Args... _args) { template auto move_from_ptr_fields(Pointers& _ptrs, Args&&... _args) { constexpr auto i = sizeof...(Args); - if constexpr (i == std::tuple_size_v>) { + if constexpr (i == std::tuple_size_v>) { return T{std::move(_args)...}; } else { - using FieldType = std::tuple_element_t>; + using FieldType = std::tuple_element_t>; if constexpr (is_field_v) { return move_from_ptr_fields( @@ -61,9 +63,9 @@ auto move_from_ptr_fields(Pointers& _ptrs, Args&&... _args) { std::move(*std::get(_ptrs).value()))); } else { - using PtrFieldTupleType = std::decay_t>; + using PtrFieldTupleType = std::remove_cvref_t>; - using U = std::decay_t::Type>>; return move_from_ptr_fields( @@ -77,16 +79,16 @@ auto move_from_ptr_fields(Pointers& _ptrs, Args&&... _args) { /// fields. template T move_from_named_tuple(NamedTupleType&& _n) { - using RequiredType = std::decay_t>; + using RequiredType = std::remove_cvref_t>; - if constexpr (is_named_tuple_v>) { + if constexpr (is_named_tuple_v>) { return std::move(_n); - } else if constexpr (std::is_same, + } else if constexpr (std::is_same, RequiredType>()) { auto ptr_named_tuple = nt_to_ptr_named_tuple(_n); - using PtrFieldTupleType = std::decay_t>; + using PtrFieldTupleType = std::remove_cvref_t>; auto pointers = make_ptr_fields(ptr_named_tuple); diff --git a/include/rfl/internal/move_from_tuple.hpp b/include/rfl/internal/move_from_tuple.hpp index 521ffd29..b374ea28 100644 --- a/include/rfl/internal/move_from_tuple.hpp +++ b/include/rfl/internal/move_from_tuple.hpp @@ -32,12 +32,12 @@ template auto unflatten_ptr_tuple(PtrTupleType& _t, Args... _args) { constexpr auto i = sizeof...(Args); - constexpr auto size = std::tuple_size_v>; + constexpr auto size = std::tuple_size_v>; if constexpr (i == size) { return std::make_tuple(_args...); } else { - using T = std::decay_t< + using T = std::remove_cvref_t< std::remove_pointer_t>>; if constexpr (is_flatten_field_v) { @@ -61,19 +61,19 @@ auto unflatten_ptr_tuple(PtrTupleType& _t, Args... _args) { template auto move_from_pointers(Pointers& _ptrs, Args&&... _args) { constexpr auto i = sizeof...(Args); - if constexpr (i == std::tuple_size_v>) { + if constexpr (i == std::tuple_size_v>) { return T{std::move(_args)...}; } else { - using FieldType = std::tuple_element_t>; + using FieldType = std::tuple_element_t>; if constexpr (std::is_pointer_v) { return move_from_pointers(_ptrs, std::move(_args)..., std::move(*std::get(_ptrs))); } else { - using PtrTupleType = ptr_tuple_t>; + using PtrTupleType = ptr_tuple_t>; - using U = std::decay_t>::Type>; return move_from_pointers(_ptrs, std::move(_args)..., @@ -88,7 +88,7 @@ template T move_from_tuple(TupleType&& _t) { auto ptr_tuple = tup_to_ptr_tuple(_t); - using TargetTupleType = tuple_t>; + using TargetTupleType = tuple_t>; auto pointers = unflatten_ptr_tuple(ptr_tuple); diff --git a/include/rfl/internal/move_to_field_tuple.hpp b/include/rfl/internal/move_to_field_tuple.hpp index 3d6e5617..7841ae27 100644 --- a/include/rfl/internal/move_to_field_tuple.hpp +++ b/include/rfl/internal/move_to_field_tuple.hpp @@ -15,7 +15,7 @@ namespace internal { template auto move_to_field_tuple(OriginalStruct&& _t) { - using T = std::decay_t; + using T = std::remove_cvref_t; if constexpr (is_named_tuple_v) { return _t.fields(); } else if constexpr (has_fields()) { diff --git a/include/rfl/internal/no_duplicate_field_names.hpp b/include/rfl/internal/no_duplicate_field_names.hpp index 56c9b317..f025b29c 100644 --- a/include/rfl/internal/no_duplicate_field_names.hpp +++ b/include/rfl/internal/no_duplicate_field_names.hpp @@ -8,33 +8,31 @@ namespace internal { template constexpr inline bool no_duplicate_field_names() { - constexpr auto num_fields = std::tuple_size_v; - - if constexpr (num_fields <= 1) { - return true; + constexpr auto num_fields = std::tuple_size_v; + + if constexpr (num_fields <= 1) { + return true; + } else { + if constexpr (_i == num_fields) { + return true; + } else if constexpr (_j == -1) { + return no_duplicate_field_names(); } else { - if constexpr (_i == num_fields) { - return true; - } else if constexpr (_j == -1) { - return no_duplicate_field_names(); - } else { - using FieldType1 = - std::decay_t::type>; - using FieldType2 = - std::decay_t::type>; - - constexpr auto field_name_i = FieldType1::name_; - constexpr auto field_name_j = FieldType2::name_; - - constexpr bool no_duplicate = (field_name_i != field_name_j); - - static_assert(no_duplicate, - "Duplicate field names are not allowed"); - - return no_duplicate && - no_duplicate_field_names(); - } + using FieldType1 = + std::remove_cvref_t::type>; + using FieldType2 = + std::remove_cvref_t::type>; + + constexpr auto field_name_i = FieldType1::name_; + constexpr auto field_name_j = FieldType2::name_; + + constexpr bool no_duplicate = (field_name_i != field_name_j); + + static_assert(no_duplicate, "Duplicate field names are not allowed"); + + return no_duplicate && no_duplicate_field_names(); } + } } } // namespace internal diff --git a/include/rfl/internal/nt_to_ptr_named_tuple.hpp b/include/rfl/internal/nt_to_ptr_named_tuple.hpp index 4019b28b..4eac64c2 100644 --- a/include/rfl/internal/nt_to_ptr_named_tuple.hpp +++ b/include/rfl/internal/nt_to_ptr_named_tuple.hpp @@ -22,7 +22,7 @@ auto nt_to_ptr_named_tuple(NamedTupleType& _nt, AlreadyExtracted... _a) { return make_named_tuple(_a...); } else { using FieldType = typename std::tuple_element::type; - using T = std::decay_t; + using T = std::remove_cvref_t; return nt_to_ptr_named_tuple( _nt, _a..., Field(&std::get(_nt.values()))); } @@ -41,7 +41,7 @@ auto nt_to_ptr_named_tuple(const NamedTupleType& _nt, AlreadyExtracted... _a) { return make_named_tuple(_a...); } else { using FieldType = typename std::tuple_element::type; - using T = std::decay_t; + using T = std::remove_cvref_t; return nt_to_ptr_named_tuple( _nt, _a..., Field(&std::get(_nt.values()))); diff --git a/include/rfl/internal/remove_fields.hpp b/include/rfl/internal/remove_fields.hpp index a18f96ca..49b28a0d 100644 --- a/include/rfl/internal/remove_fields.hpp +++ b/include/rfl/internal/remove_fields.hpp @@ -29,12 +29,12 @@ struct remove_single_field<_OldNamedTupleType, _name, _NewNamedTupleType, 0> { template struct remove_single_field { - using OldNamedTupleType = std::decay_t<_OldNamedTupleType>; + using OldNamedTupleType = std::remove_cvref_t<_OldNamedTupleType>; constexpr static int num_fields = std::tuple_size_v; - using FieldType = std::decay_t::type>; using NewNamedTupleType = @@ -53,7 +53,7 @@ struct remove_fields; /// Special case - only head is left. template struct remove_fields<_NamedTupleType, _head> { - using NamedTupleType = std::decay_t<_NamedTupleType>; + using NamedTupleType = std::remove_cvref_t<_NamedTupleType>; constexpr static int num_fields = std::tuple_size_v; @@ -65,7 +65,7 @@ struct remove_fields<_NamedTupleType, _head> { /// General case. template struct remove_fields { - using NamedTupleType = std::decay_t<_NamedTupleType>; + using NamedTupleType = std::remove_cvref_t<_NamedTupleType>; constexpr static int num_fields = std::tuple_size_v; diff --git a/include/rfl/internal/remove_ptrs_tup.hpp b/include/rfl/internal/remove_ptrs_tup.hpp index b6f99eed..899e12f4 100644 --- a/include/rfl/internal/remove_ptrs_tup.hpp +++ b/include/rfl/internal/remove_ptrs_tup.hpp @@ -16,7 +16,8 @@ struct remove_ptrs_tup; template struct remove_ptrs_tup> { - using TupleType = std::tuple>...>; + using TupleType = + std::tuple>...>; }; } // namespace internal diff --git a/include/rfl/internal/to_flattened_ptr_tuple.hpp b/include/rfl/internal/to_flattened_ptr_tuple.hpp index 86cea458..eaf9de03 100644 --- a/include/rfl/internal/to_flattened_ptr_tuple.hpp +++ b/include/rfl/internal/to_flattened_ptr_tuple.hpp @@ -15,10 +15,10 @@ auto flatten_ptr_tuple(PtrTuple&& _t, Args... _args) { constexpr auto i = sizeof...(Args); if constexpr (i == 0 && !has_flatten_fields()) { return std::forward(_t); - } else if constexpr (i == std::tuple_size_v>) { + } else if constexpr (i == std::tuple_size_v>) { return std::tuple_cat(std::forward(_args)...); } else { - using T = std::tuple_element_t>; + using T = std::tuple_element_t>; if constexpr (is_flatten_field_v) { return flatten_ptr_tuple( std::forward(_t), std::forward(_args)..., diff --git a/include/rfl/internal/to_ptr_field_tuple.hpp b/include/rfl/internal/to_ptr_field_tuple.hpp index 90fba052..fee5ba6b 100644 --- a/include/rfl/internal/to_ptr_field_tuple.hpp +++ b/include/rfl/internal/to_ptr_field_tuple.hpp @@ -18,7 +18,7 @@ namespace internal { template auto to_ptr_field_tuple(T& _t) { - if constexpr (std::is_pointer_v>) { + if constexpr (std::is_pointer_v>) { return to_ptr_field_tuple(*_t); } else if constexpr (is_named_tuple_v) { return nt_to_ptr_named_tuple(_t).fields(); diff --git a/include/rfl/internal/to_ptr_named_tuple.hpp b/include/rfl/internal/to_ptr_named_tuple.hpp index e6b75275..20d81c4e 100644 --- a/include/rfl/internal/to_ptr_named_tuple.hpp +++ b/include/rfl/internal/to_ptr_named_tuple.hpp @@ -21,10 +21,10 @@ namespace internal { template auto flatten_ptr_field_tuple(PtrFieldTuple& _t, Args&&... _args) { constexpr auto i = sizeof...(Args); - if constexpr (i == std::tuple_size_v>) { + if constexpr (i == std::tuple_size_v>) { return std::tuple_cat(std::forward(_args)...); } else { - using T = std::tuple_element_t>; + using T = std::tuple_element_t>; if constexpr (internal::is_flatten_field::value) { const auto subtuple = internal::to_ptr_field_tuple(*std::get(_t).get()); @@ -43,7 +43,7 @@ auto field_tuple_to_named_tuple(PtrFieldTuple& _ptr_field_tuple) { return make_named_tuple(_fields...); }; - if constexpr (!has_flatten_fields>()) { + if constexpr (!has_flatten_fields>()) { return std::apply(ft_to_nt, std::move(_ptr_field_tuple)); } else { const auto flattened_tuple = flatten_ptr_field_tuple(_ptr_field_tuple); @@ -55,10 +55,10 @@ auto field_tuple_to_named_tuple(PtrFieldTuple& _ptr_field_tuple) { /// the struct. template auto to_ptr_named_tuple(T&& _t) { - if constexpr (has_fields>()) { - if constexpr (std::is_pointer_v>) { + if constexpr (has_fields>()) { + if constexpr (std::is_pointer_v>) { return to_ptr_named_tuple(*_t); - } else if constexpr (is_named_tuple_v>) { + } else if constexpr (is_named_tuple_v>) { return nt_to_ptr_named_tuple(_t); } else { auto ptr_field_tuple = to_ptr_field_tuple(_t); diff --git a/include/rfl/internal/to_ptr_tuple.hpp b/include/rfl/internal/to_ptr_tuple.hpp index 0185d70f..34f04fb8 100644 --- a/include/rfl/internal/to_ptr_tuple.hpp +++ b/include/rfl/internal/to_ptr_tuple.hpp @@ -12,7 +12,7 @@ namespace internal { template constexpr auto to_ptr_tuple(T& _t) { - if constexpr (std::is_pointer_v>) { + if constexpr (std::is_pointer_v>) { return to_ptr_tuple(*_t); } else { return bind_to_tuple(_t, [](auto&& x) { diff --git a/include/rfl/internal/wrap_in_fields.hpp b/include/rfl/internal/wrap_in_fields.hpp index 6f322494..7eb0611c 100644 --- a/include/rfl/internal/wrap_in_fields.hpp +++ b/include/rfl/internal/wrap_in_fields.hpp @@ -13,25 +13,26 @@ namespace internal { template auto wrap_in_fields(auto&& _tuple, Fields&&... _fields) { - constexpr auto size = std::tuple_size_v>; + constexpr auto size = + std::tuple_size_v>; constexpr auto i = sizeof...(_fields); if constexpr (i == size) { return std::make_tuple(std::move(_fields)...); } else { auto value = std::move(std::get(_tuple)); - using Type = std::decay_t>; + using Type = std::remove_cvref_t>; if constexpr (is_flatten_field_v) { // The problem here is that the FieldNames are already flattened, but this // is not, so we need to determine how many field names to skip. constexpr auto n_skip = std::tuple_size_v< - std::decay_t>>; + std::remove_cvref_t>>; return wrap_in_fields( std::move(_tuple), std::move(_fields)..., std::move(value)); } else { const auto name_literal = FieldNames::template name_of(); - auto new_field = - rfl::make_field>>( - std::move(value)); + auto new_field = rfl::make_field< + lit_name_v>>( + std::move(value)); return wrap_in_fields( std::move(_tuple), std::move(_fields)..., std::move(new_field)); } diff --git a/include/rfl/json/Reader.hpp b/include/rfl/json/Reader.hpp index bdc06e83..620f1731 100644 --- a/include/rfl/json/Reader.hpp +++ b/include/rfl/json/Reader.hpp @@ -76,23 +76,23 @@ struct Reader { template rfl::Result to_basic_type(const InputVarType _var) const noexcept { - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { const auto r = yyjson_get_str(_var.val_); if (r == NULL) { return rfl::Error("Could not cast to string."); } return std::string(r); - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { if (!yyjson_is_bool(_var.val_)) { return rfl::Error("Could not cast to boolean."); } return yyjson_get_bool(_var.val_); - } else if constexpr (std::is_floating_point>()) { + } else if constexpr (std::is_floating_point>()) { if (!yyjson_is_num(_var.val_)) { return rfl::Error("Could not cast to double."); } return static_cast(yyjson_get_num(_var.val_)); - } else if constexpr (std::is_integral>()) { + } else if constexpr (std::is_integral>()) { if (!yyjson_is_int(_var.val_)) { return rfl::Error("Could not cast to int."); } diff --git a/include/rfl/json/Writer.hpp b/include/rfl/json/Writer.hpp index 7a8490f5..2adbc814 100644 --- a/include/rfl/json/Writer.hpp +++ b/include/rfl/json/Writer.hpp @@ -57,13 +57,13 @@ struct Writer { template OutputVarType from_basic_type(const T& _var) const noexcept { - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { return OutputVarType(yyjson_mut_strcpy(doc_, _var.c_str())); - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { return OutputVarType(yyjson_mut_bool(doc_, _var)); - } else if constexpr (std::is_floating_point>()) { + } else if constexpr (std::is_floating_point>()) { return OutputVarType(yyjson_mut_real(doc_, static_cast(_var))); - } else if constexpr (std::is_integral>()) { + } else if constexpr (std::is_integral>()) { return OutputVarType(yyjson_mut_int(doc_, static_cast(_var))); } else { static_assert(rfl::always_false_v, "Unsupported type."); diff --git a/include/rfl/make_named_tuple.hpp b/include/rfl/make_named_tuple.hpp index a191f2e0..1b620534 100644 --- a/include/rfl/make_named_tuple.hpp +++ b/include/rfl/make_named_tuple.hpp @@ -11,15 +11,15 @@ namespace rfl { /// to explitly defined the field types. template auto make_named_tuple(FieldTypes&&... _args) { - return NamedTuple...>( - std::forward(_args)...); + return NamedTuple...>( + std::forward(_args)...); } /// Convenience constructor that doesn't require you /// to explitly defined the field types. template auto make_named_tuple(const Head& _h, const Tail&... _t) { - return NamedTuple(_h, _t...); + return NamedTuple(_h, _t...); } } // namespace rfl diff --git a/include/rfl/name_t.hpp b/include/rfl/name_t.hpp index 66563a52..b534e9d7 100644 --- a/include/rfl/name_t.hpp +++ b/include/rfl/name_t.hpp @@ -7,7 +7,7 @@ namespace rfl { /// Convenience class to retrieve the name of a field. template -using name_t = typename std::decay_t::Name; +using name_t = typename std::remove_cvref_t::Name; } // namespace rfl diff --git a/include/rfl/named_tuple_t.hpp b/include/rfl/named_tuple_t.hpp index 5acd9b0c..bd1d7a5a 100644 --- a/include/rfl/named_tuple_t.hpp +++ b/include/rfl/named_tuple_t.hpp @@ -17,7 +17,7 @@ struct remove_ptr; template struct remove_ptr> { - using FieldType = Field<_name, std::decay_t>>; + using FieldType = Field<_name, std::remove_cvref_t>>; }; template diff --git a/include/rfl/parsing/FieldVariantParser.hpp b/include/rfl/parsing/FieldVariantParser.hpp index c3c4ce56..cc7f8c89 100644 --- a/include/rfl/parsing/FieldVariantParser.hpp +++ b/include/rfl/parsing/FieldVariantParser.hpp @@ -16,7 +16,7 @@ namespace parsing { /// To be used when all options of the variants are rfl::Field. Essentially, /// this is an externally tagged union. template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct FieldVariantParser { using ResultType = Result>; @@ -60,7 +60,7 @@ struct FieldVariantParser { const auto handle = [&](const auto& _field) { const auto named_tuple = make_named_tuple(internal::to_ptr_field(_field)); - using NamedTupleType = std::decay_t; + using NamedTupleType = std::remove_cvref_t; return Parser::write(_w, named_tuple); }; @@ -78,10 +78,10 @@ struct FieldVariantParser { "'" + _disc_value + "'."); } else { - using FieldType = std::decay_t< + using FieldType = std::remove_cvref_t< typename std::tuple_element<_i, std::tuple>::type>; - using ValueType = std::decay_t; + using ValueType = std::remove_cvref_t; const auto key = FieldType::name_.str(); diff --git a/include/rfl/parsing/MapParser.hpp b/include/rfl/parsing/MapParser.hpp index 8b56095f..c8cd3db4 100644 --- a/include/rfl/parsing/MapParser.hpp +++ b/include/rfl/parsing/MapParser.hpp @@ -13,7 +13,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter + requires AreReaderAndWriter struct MapParser { public: using InputObjectType = typename R::InputObjectType; @@ -22,8 +22,9 @@ struct MapParser { using OutputObjectType = typename W::OutputObjectType; using OutputVarType = typename W::OutputVarType; - using KeyType = std::decay_t; - using ValueType = std::decay_t; + using KeyType = std::remove_cvref_t; + using ValueType = + std::remove_cvref_t; static Result read(const R& _r, const InputVarType& _var) noexcept { const auto to_map = [&](const auto& _obj) { return make_map(_r, _obj); }; @@ -33,7 +34,8 @@ struct MapParser { static OutputVarType write(const W& _w, const MapType& _m) noexcept { auto obj = _w.new_object(); for (const auto& [k, v] : _m) { - auto parsed_val = Parser>::write(_w, v); + auto parsed_val = + Parser>::write(_w, v); if constexpr (internal::has_reflection_type_v) { using ReflT = typename KeyType::ReflectionType; @@ -100,7 +102,7 @@ struct MapParser { auto pair = std::make_pair(std::move(_pair.first), std::move(_val)); return make_key(pair); }; - return Parser>::read(_r, _pair.second) + return Parser>::read(_r, _pair.second) .and_then(to_pair) .value(); } diff --git a/include/rfl/parsing/NamedTupleParser.hpp b/include/rfl/parsing/NamedTupleParser.hpp index 863304d7..cf820960 100644 --- a/include/rfl/parsing/NamedTupleParser.hpp +++ b/include/rfl/parsing/NamedTupleParser.hpp @@ -19,7 +19,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct NamedTupleParser { using InputObjectType = typename R::InputObjectType; using InputVarType = typename R::InputVarType; @@ -69,7 +69,7 @@ struct NamedTupleParser { using FieldType = typename std::tuple_element< i, typename NamedTuple::Fields>::type; - using ValueType = std::decay_t; + using ValueType = std::remove_cvref_t; const auto& f = std::get(_fields_arr); @@ -125,7 +125,7 @@ struct NamedTupleParser { using FieldType = typename std::tuple_element< _i, typename NamedTuple::Fields>::type; - using ValueType = std::decay_t; + using ValueType = std::remove_cvref_t; const auto& f = std::get<_i>(_fields_arr); @@ -159,7 +159,7 @@ struct NamedTupleParser { } else { using FieldType = typename std::tuple_element<_i, std::tuple>::type; - using ValueType = std::decay_t; + using ValueType = std::remove_cvref_t; auto value = Parser::write(_w, rfl::get<_i>(_tup)); const auto name = FieldType::name_.str(); if constexpr (!is_required()) { @@ -192,7 +192,7 @@ struct NamedTupleParser { const auto key = FieldType::name_.str(); return Error("Failed to parse field '" + key + "': " + _e.what()); }; - using ValueType = std::decay_t; + using ValueType = std::remove_cvref_t; return Parser::read(_r, _var).or_else(embellish_error); } diff --git a/include/rfl/parsing/Parser_array.hpp b/include/rfl/parsing/Parser_array.hpp index af5f666b..eff72956 100644 --- a/include/rfl/parsing/Parser_array.hpp +++ b/include/rfl/parsing/Parser_array.hpp @@ -12,7 +12,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { public: using InputArrayType = typename R::InputArrayType; @@ -47,7 +47,7 @@ struct Parser> { const std::array& _arr) noexcept { auto arr = _w.new_array(); for (auto it = _arr.begin(); it != _arr.end(); ++it) { - _w.add(Parser>::write(_w, *it), &arr); + _w.add(Parser>::write(_w, *it), &arr); } return OutputVarType(arr); } diff --git a/include/rfl/parsing/Parser_box.hpp b/include/rfl/parsing/Parser_box.hpp index 3c391310..cd30c9dc 100644 --- a/include/rfl/parsing/Parser_box.hpp +++ b/include/rfl/parsing/Parser_box.hpp @@ -11,18 +11,19 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; static Result> read(const R& _r, const InputVarType& _var) noexcept { const auto to_box = [](auto&& _t) { return Box::make(std::move(_t)); }; - return Parser>::read(_r, _var).transform(to_box); + return Parser>::read(_r, _var).transform( + to_box); } static OutputVarType write(const W& _w, const Box& _box) noexcept { - return Parser>::write(_w, *_box); + return Parser>::write(_w, *_box); } }; diff --git a/include/rfl/parsing/Parser_default.hpp b/include/rfl/parsing/Parser_default.hpp index 076d87b8..0b2ce8d0 100644 --- a/include/rfl/parsing/Parser_default.hpp +++ b/include/rfl/parsing/Parser_default.hpp @@ -22,7 +22,7 @@ namespace parsing { /// Default case - anything that cannot be explicitly matched. template -requires AreReaderAndWriter + requires AreReaderAndWriter struct Parser { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -33,7 +33,7 @@ struct Parser { return _r.template use_custom_constructor(_var); } else { if constexpr (internal::has_reflection_type_v) { - using ReflectionType = std::decay_t; + using ReflectionType = std::remove_cvref_t; const auto wrap_in_t = [](auto _named_tuple) -> Result { try { return T(_named_tuple); @@ -57,7 +57,7 @@ struct Parser { return _r.template to_basic_type(_var).and_then( StringConverter::string_to_enum); } else if constexpr (internal::is_basic_type_v) { - return _r.template to_basic_type>(_var); + return _r.template to_basic_type>(_var); } else { static_assert( always_false_v, @@ -73,7 +73,7 @@ struct Parser { if constexpr (supports_attributes && internal::is_attribute_v) { return _w.from_basic_type(resolve_reflection_type(_var), true); } else if constexpr (internal::has_reflection_type_v) { - using ReflectionType = std::decay_t; + using ReflectionType = std::remove_cvref_t; if constexpr (internal::has_reflection_method_v) { return Parser::write(_w, _var.reflection()); } else { @@ -82,7 +82,7 @@ struct Parser { } } else if constexpr (std::is_class_v && std::is_aggregate_v) { const auto ptr_named_tuple = internal::to_ptr_named_tuple(_var); - using PtrNamedTupleType = std::decay_t; + using PtrNamedTupleType = std::remove_cvref_t; return Parser::write(_w, ptr_named_tuple); } else if constexpr (std::is_enum_v) { using StringConverter = internal::enums::StringConverter; diff --git a/include/rfl/parsing/Parser_optional.hpp b/include/rfl/parsing/Parser_optional.hpp index 51b4da7a..12081a5a 100644 --- a/include/rfl/parsing/Parser_optional.hpp +++ b/include/rfl/parsing/Parser_optional.hpp @@ -12,7 +12,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -23,14 +23,15 @@ struct Parser> { return std::optional(); } const auto to_opt = [](auto&& _t) { return std::make_optional(_t); }; - return Parser>::read(_r, _var).transform(to_opt); + return Parser>::read(_r, _var).transform( + to_opt); } static OutputVarType write(const W& _w, const std::optional& _o) noexcept { if (!_o) { return _w.empty_var(); } - return Parser>::write(_w, *_o); + return Parser>::write(_w, *_o); } }; diff --git a/include/rfl/parsing/Parser_ptr.hpp b/include/rfl/parsing/Parser_ptr.hpp index a782c7a6..876868a7 100644 --- a/include/rfl/parsing/Parser_ptr.hpp +++ b/include/rfl/parsing/Parser_ptr.hpp @@ -11,7 +11,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter + requires AreReaderAndWriter struct Parser { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -32,7 +32,7 @@ struct Parser { if (!_ptr) { return _w.empty_var(); } - return Parser>::write(_w, *_ptr); + return Parser>::write(_w, *_ptr); } }; diff --git a/include/rfl/parsing/Parser_ref.hpp b/include/rfl/parsing/Parser_ref.hpp index f7a14e59..137083f3 100644 --- a/include/rfl/parsing/Parser_ref.hpp +++ b/include/rfl/parsing/Parser_ref.hpp @@ -12,7 +12,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -20,12 +20,13 @@ struct Parser> { /// Expresses the variables as type T. static Result> read(const R& _r, const InputVarType& _var) noexcept { const auto to_ref = [&](auto&& _t) { return Ref::make(std::move(_t)); }; - return Parser>::read(_r, _var).transform(to_ref); + return Parser>::read(_r, _var).transform( + to_ref); } /// Expresses the variable a a JSON. static OutputVarType write(const W& _w, const Ref& _ref) noexcept { - return Parser>::write(_w, *_ref); + return Parser>::write(_w, *_ref); } }; diff --git a/include/rfl/parsing/Parser_reference_wrapper.hpp b/include/rfl/parsing/Parser_reference_wrapper.hpp index efe6acee..2aed5142 100644 --- a/include/rfl/parsing/Parser_reference_wrapper.hpp +++ b/include/rfl/parsing/Parser_reference_wrapper.hpp @@ -12,7 +12,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -30,7 +30,7 @@ struct Parser> { static OutputVarType write(const W& _w, const std::reference_wrapper _ref) noexcept { - return Parser>::write(_w, _ref.get()); + return Parser>::write(_w, _ref.get()); } }; diff --git a/include/rfl/parsing/Parser_rename.hpp b/include/rfl/parsing/Parser_rename.hpp index 3b7612da..4b485b14 100644 --- a/include/rfl/parsing/Parser_rename.hpp +++ b/include/rfl/parsing/Parser_rename.hpp @@ -13,7 +13,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -23,12 +23,13 @@ struct Parser> { const auto to_rename = [](auto&& _t) { return Rename<_name, T>(std::move(_t)); }; - return Parser>::read(_r, _var).transform(to_rename); + return Parser>::read(_r, _var).transform( + to_rename); } static OutputVarType write(const W& _w, const Rename<_name, T>& _rename) noexcept { - return Parser>::write(_w, _rename.value()); + return Parser>::write(_w, _rename.value()); } }; diff --git a/include/rfl/parsing/Parser_result.hpp b/include/rfl/parsing/Parser_result.hpp index db413533..8e82f9e9 100644 --- a/include/rfl/parsing/Parser_result.hpp +++ b/include/rfl/parsing/Parser_result.hpp @@ -12,22 +12,22 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; using ErrorType = NamedTuple>; - using VariantType = std::variant, ErrorType>; + using VariantType = std::variant, ErrorType>; static Result> read(const R& _r, const InputVarType& _var) noexcept { const auto handle = [](auto&& _t) -> Result { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (std::is_same()) { return Error(_t.template get<"error">()); } else { - return std::forward>(_t); + return std::forward>(_t); } }; @@ -41,7 +41,7 @@ struct Parser> { static OutputVarType write(const W& _w, const Result& _r) noexcept { const auto write_t = [&](const auto& _t) -> OutputVarType { - return Parser>::write(_w, _t); + return Parser>::write(_w, _t); }; const auto write_err = [&](const auto& _err) -> OutputVarType { diff --git a/include/rfl/parsing/Parser_shared_ptr.hpp b/include/rfl/parsing/Parser_shared_ptr.hpp index 1268a570..a8adc0ba 100644 --- a/include/rfl/parsing/Parser_shared_ptr.hpp +++ b/include/rfl/parsing/Parser_shared_ptr.hpp @@ -12,7 +12,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -26,7 +26,8 @@ struct Parser> { const auto to_ptr = [](auto&& _t) { return std::make_shared(std::move(_t)); }; - return Parser>::read(_r, _var).transform(to_ptr); + return Parser>::read(_r, _var).transform( + to_ptr); } /// Expresses the variable a a JSON. @@ -35,7 +36,7 @@ struct Parser> { if (!_s) { return _w.empty_var(); } - return Parser>::write(_w, *_s); + return Parser>::write(_w, *_s); } }; diff --git a/include/rfl/parsing/Parser_tagged_union.hpp b/include/rfl/parsing/Parser_tagged_union.hpp index ade04806..7eee6dec 100644 --- a/include/rfl/parsing/Parser_tagged_union.hpp +++ b/include/rfl/parsing/Parser_tagged_union.hpp @@ -14,8 +14,8 @@ namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using ResultType = Result>; @@ -56,7 +56,7 @@ struct Parser> { return Error("Could not parse tagged union, could not match " + _discriminator.str() + " '" + _disc_value + "'."); } else { - using AlternativeType = std::decay_t< + using AlternativeType = std::remove_cvref_t< std::variant_alternative_t<_i, std::variant>>; if (contains_disc_value(_disc_value)) { @@ -112,8 +112,8 @@ struct Parser> { template static OutputVarType write_wrapped(const W& _w, const T& _val) noexcept { const auto tag = internal::make_tag(); - using TagType = std::decay_t; - if constexpr (internal::has_fields>()) { + using TagType = std::remove_cvref_t; + if constexpr (internal::has_fields>()) { using WrapperType = TaggedUnionWrapperWithFields; const auto wrapper = WrapperType{.tag = tag, .fields = &_val}; diff --git a/include/rfl/parsing/Parser_unique_ptr.hpp b/include/rfl/parsing/Parser_unique_ptr.hpp index 6a7d113e..13ce802e 100644 --- a/include/rfl/parsing/Parser_unique_ptr.hpp +++ b/include/rfl/parsing/Parser_unique_ptr.hpp @@ -12,7 +12,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -25,7 +25,8 @@ struct Parser> { const auto to_ptr = [](auto&& _t) { return std::make_unique(std::move(_t)); }; - return Parser>::read(_r, _var).transform(to_ptr); + return Parser>::read(_r, _var).transform( + to_ptr); } static OutputVarType write(const W& _w, @@ -33,7 +34,7 @@ struct Parser> { if (!_s) { return _w.empty_var(); } - return Parser>::write(_w, *_s); + return Parser>::write(_w, *_s); } }; diff --git a/include/rfl/parsing/Parser_variant.hpp b/include/rfl/parsing/Parser_variant.hpp index c341b767..04cea4fb 100644 --- a/include/rfl/parsing/Parser_variant.hpp +++ b/include/rfl/parsing/Parser_variant.hpp @@ -14,7 +14,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser> { using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; @@ -40,7 +40,7 @@ struct Parser> { return read<_i + 1>(_r, _var, errors); }; - using AltType = std::decay_t< + using AltType = std::remove_cvref_t< std::variant_alternative_t<_i, std::variant>>; return Parser::read(_r, _var) @@ -55,7 +55,7 @@ struct Parser> { return FieldVariantParser::write(_w, _variant); } else { const auto handle = [&](const auto& _v) { - using Type = std::decay_t; + using Type = std::remove_cvref_t; return Parser::write(_w, _v); }; return std::visit(handle, _variant); diff --git a/include/rfl/parsing/TupleParser.hpp b/include/rfl/parsing/TupleParser.hpp index dd5e5905..f3f10844 100644 --- a/include/rfl/parsing/TupleParser.hpp +++ b/include/rfl/parsing/TupleParser.hpp @@ -11,7 +11,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct TupleParser { public: using InputArrayType = typename R::InputArrayType; @@ -71,8 +71,8 @@ struct TupleParser { template static auto extract_single_field( const R& _r, const std::vector& _vec) noexcept { - using NewFieldType = - std::decay_t>::type>; + using NewFieldType = std::remove_cvref_t< + typename std::tuple_element<_i, std::tuple>::type>; using ResultType = Result; @@ -93,7 +93,7 @@ struct TupleParser { static void to_array(const W& _w, const std::tuple& _tup, OutputArrayType* _ptr) noexcept { if constexpr (_i < sizeof...(Ts)) { - using NewFieldType = std::decay_t< + using NewFieldType = std::remove_cvref_t< typename std::tuple_element<_i, std::tuple>::type>; const auto val = diff --git a/include/rfl/parsing/VectorParser.hpp b/include/rfl/parsing/VectorParser.hpp index c1771fb7..9c0de53a 100644 --- a/include/rfl/parsing/VectorParser.hpp +++ b/include/rfl/parsing/VectorParser.hpp @@ -22,7 +22,7 @@ namespace parsing { /// but also includes map-like types, when the key is not of type /// std::string. template -requires AreReaderAndWriter + requires AreReaderAndWriter struct VectorParser { public: using InputArrayType = typename R::InputArrayType; @@ -50,7 +50,7 @@ struct VectorParser { } else { auto arr = _w.new_array(); for (const auto& v : _vec) { - _w.add(Parser>::write(_w, v), &arr); + _w.add(Parser>::write(_w, v), &arr); } return OutputVarType(arr); } @@ -58,13 +58,14 @@ struct VectorParser { private: static auto get_elem(const R& _r, auto& _v) { - return Parser>::read(_r, _v).value(); + return Parser>::read(_r, _v).value(); }; static auto get_pair(const R& _r, auto& _v) { - using K = std::decay_t; - using V = std::decay_t; - return Parser>>::read(_r, _v).value(); + using K = std::remove_cvref_t; + using V = std::remove_cvref_t; + return Parser>>::read(_r, _v) + .value(); } static Result to_container(const R& _r, InputArrayType&& _arr) { @@ -101,7 +102,7 @@ struct VectorParser { static constexpr bool treat_as_map() { if constexpr (is_map_like_not_multimap()) { if constexpr (internal::has_reflection_type_v) { - using U = std::decay_t; + using U = std::remove_cvref_t; return std::is_same() || std::is_integral_v || std::is_floating_point_v; diff --git a/include/rfl/parsing/is_map_like.hpp b/include/rfl/parsing/is_map_like.hpp index caaa5719..3669f268 100644 --- a/include/rfl/parsing/is_map_like.hpp +++ b/include/rfl/parsing/is_map_like.hpp @@ -28,7 +28,7 @@ class is_map_like> : public std::true_type {}; template constexpr bool is_map_like_v = - is_map_like>>::value; + is_map_like>>::value; } // namespace parsing } // namespace rfl diff --git a/include/rfl/parsing/is_required.hpp b/include/rfl/parsing/is_required.hpp index 143e54a5..e72a3f4b 100644 --- a/include/rfl/parsing/is_required.hpp +++ b/include/rfl/parsing/is_required.hpp @@ -36,7 +36,7 @@ constexpr bool is_never_required_v = is_never_required::value; template consteval bool is_required() { - using Type = std::decay_t>; + using Type = std::remove_cvref_t>; if constexpr (internal::has_reflection_type_v) { return is_required(); diff --git a/include/rfl/parsing/is_vector_like.hpp b/include/rfl/parsing/is_vector_like.hpp index 1eba273a..6cf78085 100644 --- a/include/rfl/parsing/is_vector_like.hpp +++ b/include/rfl/parsing/is_vector_like.hpp @@ -45,7 +45,7 @@ class is_vector_like> : public std::true_type {}; template constexpr bool is_vector_like_v = - is_vector_like>>::value; + is_vector_like>>::value; } // namespace parsing } // namespace rfl diff --git a/include/rfl/remove_fields.hpp b/include/rfl/remove_fields.hpp index d1d0cc94..3721abfc 100644 --- a/include/rfl/remove_fields.hpp +++ b/include/rfl/remove_fields.hpp @@ -14,7 +14,7 @@ namespace rfl { /// NamedTupleType. template using remove_fields_t = - typename internal::remove_fields, + typename internal::remove_fields, _names...>::type; } // namespace rfl diff --git a/include/rfl/to_named_tuple.hpp b/include/rfl/to_named_tuple.hpp index 87a3e983..c7d2e017 100644 --- a/include/rfl/to_named_tuple.hpp +++ b/include/rfl/to_named_tuple.hpp @@ -21,9 +21,9 @@ namespace rfl { /// All fields of the struct must be an rfl::Field. template auto to_named_tuple(T&& _t) { - if constexpr (internal::is_named_tuple_v>) { + if constexpr (internal::is_named_tuple_v>) { return _t; - } else if constexpr (internal::is_field_v>) { + } else if constexpr (internal::is_field_v>) { return make_named_tuple(std::forward(_t)); } else if constexpr (std::is_lvalue_reference{}) { auto field_tuple = internal::copy_to_field_tuple(_t); @@ -39,9 +39,9 @@ auto to_named_tuple(T&& _t) { /// All fields of the struct must be an rfl::Field. template auto to_named_tuple(const T& _t) { - if constexpr (internal::is_named_tuple_v>) { + if constexpr (internal::is_named_tuple_v>) { return _t; - } else if constexpr (internal::is_field_v>) { + } else if constexpr (internal::is_field_v>) { return make_named_tuple(_t); } else { auto field_tuple = internal::copy_to_field_tuple(_t); diff --git a/include/rfl/xml/OutputValue.hpp b/include/rfl/xml/OutputValue.hpp index abd10e60..c03defa5 100644 --- a/include/rfl/xml/OutputValue.hpp +++ b/include/rfl/xml/OutputValue.hpp @@ -41,12 +41,12 @@ class OutputValue : public OutputVar { private: /// Transforms the underlying value into a string. std::string to_string() { - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { return val_; - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { return val_ ? "true" : "false"; - } else if constexpr (std::is_floating_point>() || - std::is_integral>()) { + } else if constexpr (std::is_floating_point>() || + std::is_integral>()) { return std::to_string(val_); } else { static_assert(always_false_v, "Unsupported type"); diff --git a/include/rfl/xml/Reader.hpp b/include/rfl/xml/Reader.hpp index 559950d5..25fde797 100644 --- a/include/rfl/xml/Reader.hpp +++ b/include/rfl/xml/Reader.hpp @@ -53,7 +53,7 @@ struct Reader { const std::variant& _node_or_attribute) { const auto cast = [](const auto& _n) -> Result { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (std::is_same()) { return _n; } else { @@ -82,7 +82,7 @@ struct Reader { template rfl::Result to_basic_type(const InputVarType _var) const noexcept { const auto get_value = [](const auto& _n) -> std::string { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (std::is_same()) { return std::string(_n.child_value()); } else { @@ -90,11 +90,11 @@ struct Reader { } }; - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { return std::visit(get_value, _var.node_or_attribute_); - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { return std::visit(get_value, _var.node_or_attribute_) == "true"; - } else if constexpr (std::is_floating_point>()) { + } else if constexpr (std::is_floating_point>()) { const auto str = std::visit(get_value, _var.node_or_attribute_); try { return static_cast(std::stod(str)); @@ -102,7 +102,7 @@ struct Reader { return Error("Could not cast '" + std::string(str) + "' to floating point value."); } - } else if constexpr (std::is_integral>()) { + } else if constexpr (std::is_integral>()) { const auto str = std::visit(get_value, _var.node_or_attribute_); try { return static_cast(std::stoi(str)); diff --git a/include/rfl/xml/is_required_for_xml.hpp b/include/rfl/xml/is_required_for_xml.hpp index d078a5f5..d499554b 100644 --- a/include/rfl/xml/is_required_for_xml.hpp +++ b/include/rfl/xml/is_required_for_xml.hpp @@ -14,7 +14,7 @@ namespace xml { // lax rules when things are required. template consteval bool is_required_for_xml() { - using Type = std::decay_t>; + using Type = std::remove_cvref_t>; if constexpr (internal::has_reflection_type_v) { return is_required_for_xml(); } else { diff --git a/include/rfl/xml/write.hpp b/include/rfl/xml/write.hpp index 2b2011b2..14b44784 100644 --- a/include/rfl/xml/write.hpp +++ b/include/rfl/xml/write.hpp @@ -21,7 +21,7 @@ consteval auto get_root_name() { return _root; } else { return internal::remove_namespaces< - internal::get_type_name>()>(); + internal::get_type_name>()>(); } } From df26f6df6ca8e97d919f188addd484be8a78242a Mon Sep 17 00:00:00 2001 From: hazby2002 <1094501217@qq.com> Date: Wed, 27 Dec 2023 01:26:00 +0800 Subject: [PATCH 03/17] Implement write operation of Parser for c-arrays. --- include/rfl/Result.hpp | 5 ++++ include/rfl/parsing/Parser.hpp | 1 + include/rfl/parsing/Parser_c_array.hpp | 40 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 include/rfl/parsing/Parser_c_array.hpp diff --git a/include/rfl/Result.hpp b/include/rfl/Result.hpp index a6d564fc..096f517d 100644 --- a/include/rfl/Result.hpp +++ b/include/rfl/Result.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -339,6 +340,10 @@ class Result { std::variant t_or_err_; }; +/// This is simply to get the compilation to pass. +template +class Result : public Result> {}; + } // namespace rfl #endif diff --git a/include/rfl/parsing/Parser.hpp b/include/rfl/parsing/Parser.hpp index 71624a33..607356b7 100644 --- a/include/rfl/parsing/Parser.hpp +++ b/include/rfl/parsing/Parser.hpp @@ -4,6 +4,7 @@ #include "Parser_array.hpp" #include "Parser_base.hpp" #include "Parser_box.hpp" +#include "Parser_c_array.hpp" #include "Parser_default.hpp" #include "Parser_map_like.hpp" #include "Parser_named_tuple.hpp" diff --git a/include/rfl/parsing/Parser_c_array.hpp b/include/rfl/parsing/Parser_c_array.hpp new file mode 100644 index 00000000..0755e495 --- /dev/null +++ b/include/rfl/parsing/Parser_c_array.hpp @@ -0,0 +1,40 @@ +#ifndef RFL_PARSING_PARSER_C_ARRAY_HPP_ +#define RFL_PARSING_PARSER_C_ARRAY_HPP_ + +#include + +#include "../Result.hpp" +#include "../always_false.hpp" +#include "Parser_base.hpp" + +namespace rfl { +namespace parsing { + +template + requires AreReaderAndWriter +struct Parser { + public: + using InputArrayType = typename R::InputArrayType; + using InputVarType = typename R::InputVarType; + + using OutputArrayType = typename W::OutputArrayType; + using OutputVarType = typename W::OutputVarType; + + using CArray = T[_size]; + static Result read(const R& _r, const InputVarType& _var) noexcept { + static_assert(always_false_v, "Unimplemented"); + } + + static OutputVarType write(const W& _w, const CArray& _arr) noexcept { + auto arr = _w.new_array(); + for (const auto& e : _arr) { + _w.add(Parser>::write(_w, e), &arr); + } + return OutputVarType(arr); + } +}; + +} // namespace parsing +} // namespace rfl + +#endif From fe956b37790fc452a5c3ce76a8f2f1e151777a62 Mon Sep 17 00:00:00 2001 From: hazby2002 <1094501217@qq.com> Date: Thu, 28 Dec 2023 13:37:56 +0800 Subject: [PATCH 04/17] Implement read operation of Parser for c-arrays. --- include/rfl/Field.hpp | 18 ++++++++++++++++ include/rfl/NamedTuple.hpp | 8 ++++++-- include/rfl/Result.hpp | 11 +++++++++- include/rfl/internal/move_from_tuple.hpp | 26 ++++++++++++++++++++++-- include/rfl/internal/to_std_array.hpp | 24 ++++++++++++++++++++++ include/rfl/parsing/Parser_c_array.hpp | 8 ++++++-- 6 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 include/rfl/internal/to_std_array.hpp diff --git a/include/rfl/Field.hpp b/include/rfl/Field.hpp index 179d9c1e..48b29899 100644 --- a/include/rfl/Field.hpp +++ b/include/rfl/Field.hpp @@ -10,6 +10,7 @@ #include "Literal.hpp" #include "default.hpp" #include "internal/StringLiteral.hpp" +#include "internal/to_std_array.hpp" namespace rfl { @@ -133,6 +134,23 @@ struct Field { Type value_; }; +/// Used to define a field in the NamedTuple. +template +struct Field<_name, T[_n]> : Field<_name, internal::to_std_array_t> { + /// The underlying type. + using Type = T[_n]; + + using StdArray = internal::to_std_array_t; + + using Field<_name, StdArray>::Field; + + Type& c_array() { return reinterpret_cast(this->value_); } + + const Type& c_array() const { + return reinterpret_cast(this->value_); + } +}; + template inline auto make_field(T&& _value) { return Field<_name, T>(std::forward(_value)); diff --git a/include/rfl/NamedTuple.hpp b/include/rfl/NamedTuple.hpp index 3a4cbfec..7ae4c89f 100644 --- a/include/rfl/NamedTuple.hpp +++ b/include/rfl/NamedTuple.hpp @@ -43,16 +43,20 @@ class NamedTuple { "Duplicate field names are not allowed"); } + static auto get(auto &&tuple) { + return reinterpret_cast::type::Type...>&&>(tuple); + } + /// Construct from the fields. NamedTuple(FieldTypes&&... _fields) - : values_(std::make_tuple(std::move(_fields.value_)...)) { + : values_(get(std::make_tuple(std::move(_fields.value_)...))) { static_assert(no_duplicate_field_names(), "Duplicate field names are not allowed"); } /// Construct from the fields. NamedTuple(const FieldTypes&... _fields) - : values_(std::make_tuple(_fields.value_...)) { + : values_(get(std::make_tuple(_fields.value_...))) { static_assert(no_duplicate_field_names(), "Duplicate field names are not allowed"); } diff --git a/include/rfl/Result.hpp b/include/rfl/Result.hpp index 096f517d..b3be13ef 100644 --- a/include/rfl/Result.hpp +++ b/include/rfl/Result.hpp @@ -10,6 +10,8 @@ #include #include +#include "internal/to_std_array.hpp" + namespace rfl { /// To be returned @@ -342,7 +344,14 @@ class Result { /// This is simply to get the compilation to pass. template -class Result : public Result> {}; +struct Result : public Result> { + using StdArray = internal::to_std_array_t; + using Base = Result; + using Base::Base; + + Result(const Base& other) : Base(other) {} + Result(Base&& other) : Base(std::move(other)) {} +}; } // namespace rfl diff --git a/include/rfl/internal/move_from_tuple.hpp b/include/rfl/internal/move_from_tuple.hpp index b374ea28..f69e8ef8 100644 --- a/include/rfl/internal/move_from_tuple.hpp +++ b/include/rfl/internal/move_from_tuple.hpp @@ -82,6 +82,29 @@ auto move_from_pointers(Pointers& _ptrs, Args&&... _args) { } } +template +auto make_tuple_from_element(T (*arr)[n]) { + if constexpr (std::is_array_v) { + return [&](std::index_sequence) { + return std::tuple_cat(make_tuple_from_element(&(*arr)[i])...); + }(std::make_index_sequence()); + } else { + return [&](std::index_sequence) { + return std::make_tuple(&(*arr)[i]...); + }(std::make_index_sequence()); + } +} + +auto make_tuple_from_element(auto &e) { + return std::make_tuple(e); +} + +auto flatten_c_arrays(const auto &tuple) { + return [&](std::index_sequence) { + return std::tuple_cat(make_tuple_from_element(std::get(tuple))...); + }(std::make_index_sequence>>()); +} + /// Creates a struct of type T from a tuple by moving the underlying /// fields. template @@ -90,8 +113,7 @@ T move_from_tuple(TupleType&& _t) { using TargetTupleType = tuple_t>; - auto pointers = unflatten_ptr_tuple(ptr_tuple); - + auto pointers = flatten_c_arrays(unflatten_ptr_tuple(ptr_tuple)); return move_from_pointers(pointers); } diff --git a/include/rfl/internal/to_std_array.hpp b/include/rfl/internal/to_std_array.hpp new file mode 100644 index 00000000..715399b1 --- /dev/null +++ b/include/rfl/internal/to_std_array.hpp @@ -0,0 +1,24 @@ +#ifndef RFL_INTERNAL_TO_STD_ARRAY_HPP_ +#define RFL_INTERNAL_TO_STD_ARRAY_HPP_ + +#include +#include + +namespace rfl::internal { + +template +struct to_std_array { + using type = T; +}; + +template +struct to_std_array { + using type = std::array>::type, _n>; +}; + +template +using to_std_array_t = to_std_array::type; + +} + +#endif diff --git a/include/rfl/parsing/Parser_c_array.hpp b/include/rfl/parsing/Parser_c_array.hpp index 0755e495..bce7e0c9 100644 --- a/include/rfl/parsing/Parser_c_array.hpp +++ b/include/rfl/parsing/Parser_c_array.hpp @@ -5,6 +5,8 @@ #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/to_std_array.hpp" +#include "Parser_array.hpp" #include "Parser_base.hpp" namespace rfl { @@ -21,8 +23,10 @@ struct Parser { using OutputVarType = typename W::OutputVarType; using CArray = T[_size]; - static Result read(const R& _r, const InputVarType& _var) noexcept { - static_assert(always_false_v, "Unimplemented"); + using StdArray = internal::to_std_array_t; + + static auto read(const R& _r, const InputVarType& _var) noexcept { + return Parser::read(_r, _var); } static OutputVarType write(const W& _w, const CArray& _arr) noexcept { From 12007f3eabdf8c40e3d0524c6ca3c1669bdc2d77 Mon Sep 17 00:00:00 2001 From: hazby2002 <1094501217@qq.com> Date: Wed, 27 Dec 2023 01:41:01 +0800 Subject: [PATCH 05/17] Add tests for writing c arrays. --- include/rfl/parsing/Parser_array.hpp | 2 +- tests/json/test_c_array_class1.cpp | 28 ++++++++++++++++++++++++ tests/json/test_c_array_class1.hpp | 5 +++++ tests/json/test_c_array_class2.cpp | 32 ++++++++++++++++++++++++++++ tests/json/test_c_array_class2.hpp | 5 +++++ tests/json/test_c_array_class3.cpp | 21 ++++++++++++++++++ tests/json/test_c_array_class3.hpp | 5 +++++ tests/json/test_c_array_class4.cpp | 26 ++++++++++++++++++++++ tests/json/test_c_array_class4.hpp | 5 +++++ tests/json/tests.cpp | 8 +++++++ 10 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 tests/json/test_c_array_class1.cpp create mode 100644 tests/json/test_c_array_class1.hpp create mode 100644 tests/json/test_c_array_class2.cpp create mode 100644 tests/json/test_c_array_class2.hpp create mode 100644 tests/json/test_c_array_class3.cpp create mode 100644 tests/json/test_c_array_class3.hpp create mode 100644 tests/json/test_c_array_class4.cpp create mode 100644 tests/json/test_c_array_class4.hpp diff --git a/include/rfl/parsing/Parser_array.hpp b/include/rfl/parsing/Parser_array.hpp index eff72956..fd762154 100644 --- a/include/rfl/parsing/Parser_array.hpp +++ b/include/rfl/parsing/Parser_array.hpp @@ -60,7 +60,7 @@ struct Parser> { AlreadyExtracted&&... _already_extracted) noexcept { constexpr size_t i = sizeof...(AlreadyExtracted); if constexpr (i == _size) { - return std::array({std::move(_already_extracted)...}); + return std::array{std::move(_already_extracted)...}; } else { const auto extract_next = [&](auto&& new_entry) { return extract_field_by_field(_r, std::move(_vec), diff --git a/tests/json/test_c_array_class1.cpp b/tests/json/test_c_array_class1.cpp new file mode 100644 index 00000000..91de3284 --- /dev/null +++ b/tests/json/test_c_array_class1.cpp @@ -0,0 +1,28 @@ +#include "test_c_array_class1.hpp" + +#include +#include +#include + +#include "rfl.hpp" +#include "rfl/json.hpp" +#include "write_and_read.hpp" + +namespace test_c_array_class1 { + +struct Test1 { + std::vector classes[3]; +}; + +void test() { + std::cout << std::source_location::current().function_name() << std::endl; + + Test1 test1 = {.classes = {{"Little A", "Little B", "Little C"}, + {"BIG A", "BIG B", "BIG C"}, + {"??", "$%", "#@"}}}; + write_and_read( + test1, + R"({"classes":[["Little A","Little B","Little C"],["BIG A","BIG B","BIG C"],["??","$%","#@"]]})"); +} + +} // namespace test_c_array_class1 diff --git a/tests/json/test_c_array_class1.hpp b/tests/json/test_c_array_class1.hpp new file mode 100644 index 00000000..8bb514e0 --- /dev/null +++ b/tests/json/test_c_array_class1.hpp @@ -0,0 +1,5 @@ +namespace test_c_array_class1 { + +void test(); + +} diff --git a/tests/json/test_c_array_class2.cpp b/tests/json/test_c_array_class2.cpp new file mode 100644 index 00000000..e61134ef --- /dev/null +++ b/tests/json/test_c_array_class2.cpp @@ -0,0 +1,32 @@ +#include "test_c_array_class2.hpp" + +#include +#include +#include + +#include "rfl.hpp" +#include "rfl/json.hpp" +#include "write_and_read.hpp" + +namespace test_c_array_class2 { + +struct Test2 { + int multi_dimension_arr[2][2][2][2]; + std::string s; +}; + +void test() { + std::cout << std::source_location::current().function_name() << std::endl; + + Test2 test2; + for (int i = 0; i < 1 << 4; i++) { + test2.multi_dimension_arr[i >> 3 & 1][i >> 2 & 1][i >> 1 & 1][i >> 0 & 1] = i; + } + test2.s = "Hello, world!"; + + write_and_read( + test2, + R"({"multi_dimension_arr":[[[[0,1],[2,3]],[[4,5],[6,7]]],[[[8,9],[10,11]],[[12,13],[14,15]]]],"s":"Hello, world!"})"); +} + +} // namespace test_c_array diff --git a/tests/json/test_c_array_class2.hpp b/tests/json/test_c_array_class2.hpp new file mode 100644 index 00000000..9e082e55 --- /dev/null +++ b/tests/json/test_c_array_class2.hpp @@ -0,0 +1,5 @@ +namespace test_c_array_class2 { + +void test(); + +} diff --git a/tests/json/test_c_array_class3.cpp b/tests/json/test_c_array_class3.cpp new file mode 100644 index 00000000..b49ce329 --- /dev/null +++ b/tests/json/test_c_array_class3.cpp @@ -0,0 +1,21 @@ +#include "test_c_array_class3.hpp" + +#include +#include + +#include "rfl.hpp" +#include "rfl/json.hpp" +#include "write_and_read.hpp" + +namespace test_c_array_class3 { + +using Test3 = std::array[3]; + +void test() { + std::cout << std::source_location::current().function_name() << std::endl; + + Test3 test3 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + write_and_read(test3, "[[1,2,3],[4,5,6],[7,8,9]]"); +} + +} // namespace test_c_array diff --git a/tests/json/test_c_array_class3.hpp b/tests/json/test_c_array_class3.hpp new file mode 100644 index 00000000..9a2931da --- /dev/null +++ b/tests/json/test_c_array_class3.hpp @@ -0,0 +1,5 @@ +namespace test_c_array_class3 { + +void test(); + +} diff --git a/tests/json/test_c_array_class4.cpp b/tests/json/test_c_array_class4.cpp new file mode 100644 index 00000000..8ba85777 --- /dev/null +++ b/tests/json/test_c_array_class4.cpp @@ -0,0 +1,26 @@ +#include "test_c_array_class4.hpp" + +#include +#include + +#include "rfl.hpp" +#include "rfl/json.hpp" +#include "write_and_read.hpp" + +namespace test_c_array_class4 { + +struct Test4 { + int a[3]; + int b[3]; + int c[2][2]; +}; + +void test() { + std::cout << std::source_location::current().function_name() << std::endl; + + Test4 test4 = {.a = {1, 2, 3}, .b = {4, 5, 6}, .c = {{7, 8}, {9, 10}}}; + + write_and_read(test4, R"({"a":[1,2,3],"b":[4,5,6],"c":[[7,8],[9,10]]})"); +} + +} // namespace test_c_array_class4 diff --git a/tests/json/test_c_array_class4.hpp b/tests/json/test_c_array_class4.hpp new file mode 100644 index 00000000..32857ec4 --- /dev/null +++ b/tests/json/test_c_array_class4.hpp @@ -0,0 +1,5 @@ +namespace test_c_array_class4 { + +void test(); + +} diff --git a/tests/json/tests.cpp b/tests/json/tests.cpp index 839744da..b3471bc0 100644 --- a/tests/json/tests.cpp +++ b/tests/json/tests.cpp @@ -8,6 +8,10 @@ #include "test_as2.hpp" #include "test_as_flatten.hpp" #include "test_box.hpp" +#include "test_c_array_class1.hpp" +#include "test_c_array_class2.hpp" +#include "test_c_array_class3.hpp" +#include "test_c_array_class4.hpp" #include "test_custom_class1.hpp" #include "test_custom_class2.hpp" #include "test_custom_class3.hpp" @@ -135,5 +139,9 @@ int main() { test_meta_fields::test(); + test_c_array_class1::test(); + test_c_array_class2::test(); + test_c_array_class3::test(); + test_c_array_class4::test(); return 0; } From 804e0ed86822c8a7d6e8157a79c45d29544ee8c6 Mon Sep 17 00:00:00 2001 From: hazby2002 <1094501217@qq.com> Date: Tue, 2 Jan 2024 15:27:11 +0800 Subject: [PATCH 06/17] Wrap C arrays with rfl::Array. --- include/rfl/Array.hpp | 26 +++++++++++++++ include/rfl/Field.hpp | 30 ++++------------- include/rfl/NamedTuple.hpp | 8 ++--- include/rfl/internal/move_from_tuple.hpp | 16 ++++++--- include/rfl/named_tuple_t.hpp | 5 ++- include/rfl/parsing/Parser.hpp | 1 + include/rfl/parsing/Parser_c_array.hpp | 4 ++- include/rfl/parsing/Parser_rfl_array.hpp | 41 ++++++++++++++++++++++++ include/rfl/wrap_in_rfl_array_t.hpp | 26 +++++++++++++++ 9 files changed, 121 insertions(+), 36 deletions(-) create mode 100644 include/rfl/Array.hpp create mode 100644 include/rfl/parsing/Parser_rfl_array.hpp create mode 100644 include/rfl/wrap_in_rfl_array_t.hpp diff --git a/include/rfl/Array.hpp b/include/rfl/Array.hpp new file mode 100644 index 00000000..33529059 --- /dev/null +++ b/include/rfl/Array.hpp @@ -0,0 +1,26 @@ +#ifndef RFL_ARRAY_HPP_ +#define RFL_ARRAY_HPP_ + +#include + +#include "internal/to_std_array.hpp" + +namespace rfl { + +template + requires std::is_array_v +struct Array : internal::to_std_array_t { + using Type = T; + using Base = internal::to_std_array_t; + using Base::Base; + + Array() = default; + Array(const Base &t) : Base(t) {} + Array(Base &&t) : Base(std::move(t)) {} + Array(const T &t) : Base(reinterpret_cast(t)) {} + Array(T &&t) : Base(reinterpret_cast(t)) {} +}; + +} // namespace rfl + +#endif diff --git a/include/rfl/Field.hpp b/include/rfl/Field.hpp index 48b29899..8d833179 100644 --- a/include/rfl/Field.hpp +++ b/include/rfl/Field.hpp @@ -7,6 +7,7 @@ #include #include +#include "Array.hpp" #include "Literal.hpp" #include "default.hpp" #include "internal/StringLiteral.hpp" @@ -134,31 +135,14 @@ struct Field { Type value_; }; -/// Used to define a field in the NamedTuple. -template -struct Field<_name, T[_n]> : Field<_name, internal::to_std_array_t> { - /// The underlying type. - using Type = T[_n]; - - using StdArray = internal::to_std_array_t; - - using Field<_name, StdArray>::Field; - - Type& c_array() { return reinterpret_cast(this->value_); } - - const Type& c_array() const { - return reinterpret_cast(this->value_); - } -}; - template inline auto make_field(T&& _value) { - return Field<_name, T>(std::forward(_value)); -} - -template -inline auto make_field(const T& _value) { - return Field<_name, T>(_value); + using T0 = std::remove_cvref_t; + if constexpr (std::is_array_v) { + return Field<_name, T0>(rfl::Array(std::forward(_value))); + } else { + return Field<_name, T0>(std::forward(_value)); + } } } // namespace rfl diff --git a/include/rfl/NamedTuple.hpp b/include/rfl/NamedTuple.hpp index 7ae4c89f..3a4cbfec 100644 --- a/include/rfl/NamedTuple.hpp +++ b/include/rfl/NamedTuple.hpp @@ -43,20 +43,16 @@ class NamedTuple { "Duplicate field names are not allowed"); } - static auto get(auto &&tuple) { - return reinterpret_cast::type::Type...>&&>(tuple); - } - /// Construct from the fields. NamedTuple(FieldTypes&&... _fields) - : values_(get(std::make_tuple(std::move(_fields.value_)...))) { + : values_(std::make_tuple(std::move(_fields.value_)...)) { static_assert(no_duplicate_field_names(), "Duplicate field names are not allowed"); } /// Construct from the fields. NamedTuple(const FieldTypes&... _fields) - : values_(get(std::make_tuple(_fields.value_...))) { + : values_(std::make_tuple(_fields.value_...)) { static_assert(no_duplicate_field_names(), "Duplicate field names are not allowed"); } diff --git a/include/rfl/internal/move_from_tuple.hpp b/include/rfl/internal/move_from_tuple.hpp index f69e8ef8..f10bebd8 100644 --- a/include/rfl/internal/move_from_tuple.hpp +++ b/include/rfl/internal/move_from_tuple.hpp @@ -4,6 +4,7 @@ #include #include +#include "../Array.hpp" #include "is_flatten_field.hpp" #include "is_named_tuple.hpp" #include "ptr_tuple_t.hpp" @@ -95,14 +96,18 @@ auto make_tuple_from_element(T (*arr)[n]) { } } -auto make_tuple_from_element(auto &e) { - return std::make_tuple(e); +template +auto make_tuple_from_element(Array* arr) { + return make_tuple_from_element(reinterpret_cast(arr)); } -auto flatten_c_arrays(const auto &tuple) { +auto make_tuple_from_element(auto& e) { return std::make_tuple(e); } + +auto flatten_c_arrays(const auto& tuple) { return [&](std::index_sequence) { return std::tuple_cat(make_tuple_from_element(std::get(tuple))...); - }(std::make_index_sequence>>()); + }(std::make_index_sequence< + std::tuple_size_v>>()); } /// Creates a struct of type T from a tuple by moving the underlying @@ -113,7 +118,8 @@ T move_from_tuple(TupleType&& _t) { using TargetTupleType = tuple_t>; - auto pointers = flatten_c_arrays(unflatten_ptr_tuple(ptr_tuple)); + auto pointers = + flatten_c_arrays(unflatten_ptr_tuple(ptr_tuple)); return move_from_pointers(pointers); } diff --git a/include/rfl/named_tuple_t.hpp b/include/rfl/named_tuple_t.hpp index bd1d7a5a..2f1cc635 100644 --- a/include/rfl/named_tuple_t.hpp +++ b/include/rfl/named_tuple_t.hpp @@ -9,6 +9,7 @@ #include "internal/is_named_tuple.hpp" #include "internal/ptr_named_tuple_t.hpp" #include "to_named_tuple.hpp" +#include "wrap_in_rfl_array_t.hpp" namespace rfl { @@ -17,7 +18,9 @@ struct remove_ptr; template struct remove_ptr> { - using FieldType = Field<_name, std::remove_cvref_t>>; + using FieldType = + Field<_name, + wrap_in_rfl_array_t>>>; }; template diff --git a/include/rfl/parsing/Parser.hpp b/include/rfl/parsing/Parser.hpp index 607356b7..eaecbc67 100644 --- a/include/rfl/parsing/Parser.hpp +++ b/include/rfl/parsing/Parser.hpp @@ -15,6 +15,7 @@ #include "Parser_reference_wrapper.hpp" #include "Parser_rename.hpp" #include "Parser_result.hpp" +#include "Parser_rfl_array.hpp" #include "Parser_rfl_variant.hpp" #include "Parser_shared_ptr.hpp" #include "Parser_tagged_union.hpp" diff --git a/include/rfl/parsing/Parser_c_array.hpp b/include/rfl/parsing/Parser_c_array.hpp index bce7e0c9..dd539aa6 100644 --- a/include/rfl/parsing/Parser_c_array.hpp +++ b/include/rfl/parsing/Parser_c_array.hpp @@ -3,6 +3,7 @@ #include +#include "../Array.hpp" #include "../Result.hpp" #include "../always_false.hpp" #include "../internal/to_std_array.hpp" @@ -25,7 +26,8 @@ struct Parser { using CArray = T[_size]; using StdArray = internal::to_std_array_t; - static auto read(const R& _r, const InputVarType& _var) noexcept { + static Result> read(const R& _r, + const InputVarType& _var) noexcept { return Parser::read(_r, _var); } diff --git a/include/rfl/parsing/Parser_rfl_array.hpp b/include/rfl/parsing/Parser_rfl_array.hpp new file mode 100644 index 00000000..d0e51a26 --- /dev/null +++ b/include/rfl/parsing/Parser_rfl_array.hpp @@ -0,0 +1,41 @@ +#ifndef RFL_PARSING_PARSER_RFL_ARRAY_HPP_ +#define RFL_PARSING_PARSER_RFL_ARRAY_HPP_ + +#include + +#include "../Array.hpp" +#include "../Result.hpp" +#include "../always_false.hpp" +#include "../internal/to_std_array.hpp" +#include "Parser_array.hpp" +#include "Parser_base.hpp" + +namespace rfl { +namespace parsing { + +template + requires AreReaderAndWriter> +struct Parser> { + public: + using InputArrayType = typename R::InputArrayType; + using InputVarType = typename R::InputVarType; + + using OutputArrayType = typename W::OutputArrayType; + using OutputVarType = typename W::OutputVarType; + + using RflArray = Array; + using StdArray = internal::to_std_array_t; + + static Result read(const R& _r, const InputVarType& _var) noexcept { + return Parser::read(_r, _var); + } + + static OutputVarType write(const W& _w, const RflArray& _arr) noexcept { + return Parser::write(_w, _arr); + } +}; + +} // namespace parsing +} // namespace rfl + +#endif diff --git a/include/rfl/wrap_in_rfl_array_t.hpp b/include/rfl/wrap_in_rfl_array_t.hpp new file mode 100644 index 00000000..24ea6254 --- /dev/null +++ b/include/rfl/wrap_in_rfl_array_t.hpp @@ -0,0 +1,26 @@ +#ifndef RFL_WRAP_IN_RFL_ARRAY_T_ +#define RFL_WRAP_IN_RFL_ARRAY_T_ + +#include + +#include "Array.hpp" + +namespace rfl { + +template +struct wrap_in_rfl_array { + using type = T; +}; + +template + requires std::is_array_v +struct wrap_in_rfl_array { + using type = Array; +}; + +template +using wrap_in_rfl_array_t = typename wrap_in_rfl_array::type; + +} // namespace rfl + +#endif From c6d30125104b377cabd2e9534686dfae3064df31 Mon Sep 17 00:00:00 2001 From: hazby2002 <1094501217@qq.com> Date: Tue, 2 Jan 2024 18:03:40 +0800 Subject: [PATCH 07/17] Remove Result. --- include/rfl/Result.hpp | 11 ----------- include/rfl/flexbuf/read.hpp | 9 +++++---- include/rfl/json/read.hpp | 7 ++++--- include/rfl/parsing/IsReader.hpp | 29 +++++++++++++++++------------ include/rfl/xml/read.hpp | 7 ++++--- 5 files changed, 30 insertions(+), 33 deletions(-) diff --git a/include/rfl/Result.hpp b/include/rfl/Result.hpp index b3be13ef..95d7316a 100644 --- a/include/rfl/Result.hpp +++ b/include/rfl/Result.hpp @@ -342,17 +342,6 @@ class Result { std::variant t_or_err_; }; -/// This is simply to get the compilation to pass. -template -struct Result : public Result> { - using StdArray = internal::to_std_array_t; - using Base = Result; - using Base::Base; - - Result(const Base& other) : Base(other) {} - Result(Base&& other) : Base(std::move(other)) {} -}; - } // namespace rfl #endif diff --git a/include/rfl/flexbuf/read.hpp b/include/rfl/flexbuf/read.hpp index 9c320ca4..7f596b93 100644 --- a/include/rfl/flexbuf/read.hpp +++ b/include/rfl/flexbuf/read.hpp @@ -7,6 +7,7 @@ #include #include "../Result.hpp" +#include "../wrap_in_rfl_array_t.hpp" #include "Parser.hpp" namespace rfl { @@ -16,14 +17,14 @@ using InputVarType = typename Reader::InputVarType; /// Parses an object from flexbuf var. template -Result read(const InputVarType& _obj) { +Result> read(const InputVarType& _obj) { const auto r = Reader(); return Parser::read(r, _obj); } /// Parses an object from flexbuf using reflection. template -Result read(const char* _bytes, const size_t _size) { +Result> read(const char* _bytes, const size_t _size) { const InputVarType root = flexbuffers::GetRoot(reinterpret_cast(_bytes), _size); return read(root); @@ -31,13 +32,13 @@ Result read(const char* _bytes, const size_t _size) { /// Parses an object from flexbuf using reflection. template -Result read(const std::vector& _bytes) { +Result> read(const std::vector& _bytes) { return read(_bytes.data(), _bytes.size()); } /// Parses an object directly from a stream. template -Result read(std::istream& _stream) { +Result> read(std::istream& _stream) { std::istreambuf_iterator begin(_stream), end; const auto bytes = std::vector(begin, end); return read(bytes.data(), bytes.size()); diff --git a/include/rfl/json/read.hpp b/include/rfl/json/read.hpp index 9de24ba2..cea84ab1 100644 --- a/include/rfl/json/read.hpp +++ b/include/rfl/json/read.hpp @@ -6,6 +6,7 @@ #include #include +#include "../wrap_in_rfl_array_t.hpp" #include "Parser.hpp" #include "Reader.hpp" @@ -17,14 +18,14 @@ using InputVarType = typename Reader::InputVarType; /// Parses an object from a JSON var. template -Result read(const InputVarType& _obj) { +Result> read(const InputVarType& _obj) { const auto r = Reader(); return Parser::read(r, _obj); } /// Parses an object from JSON using reflection. template -Result read(const std::string& _json_str) { +Result> read(const std::string& _json_str) { using PtrType = std::unique_ptr; yyjson_doc* doc = yyjson_read(_json_str.c_str(), _json_str.size(), 0); const auto ptr = PtrType(doc, yyjson_doc_free); @@ -33,7 +34,7 @@ Result read(const std::string& _json_str) { /// Parses an object from a stringstream. template -Result read(std::istream& _stream) { +Result> read(std::istream& _stream) { const auto json_str = std::string(std::istreambuf_iterator(_stream), std::istreambuf_iterator()); return read(json_str); diff --git a/include/rfl/parsing/IsReader.hpp b/include/rfl/parsing/IsReader.hpp index b8af6333..bd845eb6 100644 --- a/include/rfl/parsing/IsReader.hpp +++ b/include/rfl/parsing/IsReader.hpp @@ -10,16 +10,17 @@ #include #include "../Result.hpp" +#include "../internal/is_basic_type.hpp" +#include "../wrap_in_rfl_array_t.hpp" namespace rfl { namespace parsing { template -concept IsReader = requires(R r, std::string name, - std::function fct, - typename R::InputArrayType arr, - typename R::InputObjectType obj, - typename R::InputVarType var) { +concept IsReader = requires( + R r, std::string name, std::function fct, + typename R::InputArrayType arr, typename R::InputObjectType obj, + typename R::InputVarType var) { /// Any Reader needs to define the following: /// /// 1) An InputArrayType, which must be an array-like data structure. @@ -34,21 +35,23 @@ concept IsReader = requires(R r, std::string name, /// Retrieves a particular field from an object. { r.get_field(name, obj) - } -> std::same_as>; + } -> std::same_as>; /// Determines whether a variable is empty (the NULL type). { r.is_empty(var) } -> std::same_as; /// Transforms var to a basic type (bool, integral, /// floating point, std::string) - { r.template to_basic_type(var) } -> std::same_as>; + { + r.template to_basic_type>(var) + } -> std::same_as>>; /// fct is a function that turns the field name into the field index of the /// struct. It returns -1, if the fields does not exist on the struct. This /// returns an std::array that can be used to build up the struct. { r.template to_fields_array<6>(fct, obj) - } -> std::same_as, 6>>; + } -> std::same_as, 6>>; /// Casts var as an InputArrayType. { r.to_array(var) } -> std::same_as>; @@ -57,13 +60,13 @@ concept IsReader = requires(R r, std::string name, /// a vector. { r.to_map(obj) - } -> std::same_as< - std::vector>>; + } -> std::same_as< + std::vector>>; /// Casts var as an InputObjectType. { r.to_object(var) - } -> std::same_as>; + } -> std::same_as>; /// Iterates through an array and writes the contained vars into /// a vector. @@ -71,7 +74,9 @@ concept IsReader = requires(R r, std::string name, /// Uses the custom constructor, if it has been determined that T has one /// (see above). - { r.template use_custom_constructor(var) } -> std::same_as>; + { + r.template use_custom_constructor>(var) + } -> std::same_as>>; }; } // namespace parsing diff --git a/include/rfl/xml/read.hpp b/include/rfl/xml/read.hpp index 3aa49a29..0ef26ed4 100644 --- a/include/rfl/xml/read.hpp +++ b/include/rfl/xml/read.hpp @@ -7,6 +7,7 @@ #include "../internal/get_type_name.hpp" #include "../internal/remove_namespaces.hpp" +#include "../wrap_in_rfl_array_t.hpp" #include "Parser.hpp" #include "Reader.hpp" @@ -17,14 +18,14 @@ using InputVarType = typename Reader::InputVarType; /// Parses an object from a XML var. template -Result read(const InputVarType& _var) { +Result> read(const InputVarType& _var) { const auto r = Reader(); return Parser::read(r, _var); } /// Parses an object from XML using reflection. template -Result read(const std::string& _xml_str) { +Result> read(const std::string& _xml_str) { pugi::xml_document doc; const auto result = doc.load_string(_xml_str.c_str()); if (!result) { @@ -37,7 +38,7 @@ Result read(const std::string& _xml_str) { /// Parses an object from a stringstream. template -Result read(std::istream& _stream) { +Result> read(std::istream& _stream) { const auto xml_str = std::string(std::istreambuf_iterator(_stream), std::istreambuf_iterator()); return read(xml_str); From 7a5b53b85dc3f49b9de1c8512379c40529477480 Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Wed, 3 Jan 2024 15:50:52 +0100 Subject: [PATCH 08/17] Replaced all decay_t with cvref_t --- include/rfl/flexbuf/Writer.hpp | 16 ++++++++-------- include/rfl/parsing/FieldVariantParser.hpp | 2 +- include/rfl/parsing/MapParser.hpp | 10 ++++++---- include/rfl/parsing/Parent.hpp | 12 ++++++------ include/rfl/parsing/Parser_array.hpp | 2 +- include/rfl/parsing/Parser_box.hpp | 2 +- include/rfl/parsing/Parser_default.hpp | 4 ++-- include/rfl/parsing/Parser_optional.hpp | 2 +- include/rfl/parsing/Parser_ptr.hpp | 2 +- include/rfl/parsing/Parser_ref.hpp | 2 +- include/rfl/parsing/Parser_reference_wrapper.hpp | 2 +- include/rfl/parsing/Parser_rename.hpp | 2 +- include/rfl/parsing/Parser_shared_ptr.hpp | 2 +- include/rfl/parsing/Parser_unique_ptr.hpp | 2 +- include/rfl/parsing/VectorParser.hpp | 2 +- include/rfl/parsing/is_empty.hpp | 2 +- include/rfl/xml/Writer.hpp | 8 ++++---- include/rfl/yaml/Reader.hpp | 10 +++++----- 18 files changed, 43 insertions(+), 41 deletions(-) diff --git a/include/rfl/flexbuf/Writer.hpp b/include/rfl/flexbuf/Writer.hpp index edeed4ee..9baca78e 100644 --- a/include/rfl/flexbuf/Writer.hpp +++ b/include/rfl/flexbuf/Writer.hpp @@ -115,13 +115,13 @@ struct Writer { template OutputVarType insert_value(const std::string& _name, const T& _var) const noexcept { - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { fbb_->String(_name.c_str(), _var); - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { fbb_->Bool(_name.c_str(), _var); - } else if constexpr (std::is_floating_point>()) { + } else if constexpr (std::is_floating_point>()) { fbb_->Double(_name.c_str(), _var); - } else if constexpr (std::is_integral>()) { + } else if constexpr (std::is_integral>()) { fbb_->Int(_name.c_str(), _var); } else { static_assert(always_false_v, "Unsupported type"); @@ -131,13 +131,13 @@ struct Writer { template OutputVarType insert_value(const T& _var) const noexcept { - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { fbb_->String(_var); - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { fbb_->Bool(_var); - } else if constexpr (std::is_floating_point>()) { + } else if constexpr (std::is_floating_point>()) { fbb_->Double(_var); - } else if constexpr (std::is_integral>()) { + } else if constexpr (std::is_integral>()) { fbb_->Int(_var); } else { static_assert(always_false_v, "Unsupported type"); diff --git a/include/rfl/parsing/FieldVariantParser.hpp b/include/rfl/parsing/FieldVariantParser.hpp index 21b31a52..749f3f23 100644 --- a/include/rfl/parsing/FieldVariantParser.hpp +++ b/include/rfl/parsing/FieldVariantParser.hpp @@ -61,7 +61,7 @@ struct FieldVariantParser { const auto handle = [&](const auto& _field) { const auto named_tuple = make_named_tuple(internal::to_ptr_field(_field)); - using NamedTupleType = std::decay_t; + using NamedTupleType = std::remove_cvref_t; Parser::write(_w, named_tuple, _parent); }; diff --git a/include/rfl/parsing/MapParser.hpp b/include/rfl/parsing/MapParser.hpp index 3cb914e2..368709dd 100644 --- a/include/rfl/parsing/MapParser.hpp +++ b/include/rfl/parsing/MapParser.hpp @@ -45,21 +45,23 @@ struct MapParser { std::is_floating_point_v) { const auto new_parent = typename ParentType::Object{std::to_string(k.reflection()), &obj}; - Parser>::write(_w, v, new_parent); + Parser>::write(_w, v, + new_parent); } else { const auto new_parent = typename ParentType::Object{k.reflection(), &obj}; - Parser>::write(_w, v, new_parent); + Parser>::write(_w, v, + new_parent); } } else if constexpr (std::is_integral_v || std::is_floating_point_v) { const auto new_parent = typename ParentType::Object{std::to_string(k), &obj}; - Parser>::write(_w, v, new_parent); + Parser>::write(_w, v, new_parent); } else { const auto new_parent = typename ParentType::Object{k, &obj}; - Parser>::write(_w, v, new_parent); + Parser>::write(_w, v, new_parent); } } _w.end_object(&obj); diff --git a/include/rfl/parsing/Parent.hpp b/include/rfl/parsing/Parent.hpp index 215c2a05..c0859701 100644 --- a/include/rfl/parsing/Parent.hpp +++ b/include/rfl/parsing/Parent.hpp @@ -32,7 +32,7 @@ struct Parent { template static OutputArrayType add_array(const W& _w, const size_t _size, const ParentType& _parent) { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (std::is_same()) { return _w.add_array_to_array(_size, _parent.arr_); } else if constexpr (std::is_same()) { @@ -47,7 +47,7 @@ struct Parent { template static OutputObjectType add_object(const W& _w, const size_t _size, const ParentType& _parent) { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (std::is_same()) { return _w.add_object_to_array(_size, _parent.arr_); } else if constexpr (std::is_same()) { @@ -61,11 +61,11 @@ struct Parent { template static OutputVarType add_null(const W& _w, const ParentType& _parent) { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (std::is_same()) { return _w.add_null_to_array(_parent.arr_); } else if constexpr (std::is_same()) { - if constexpr (supports_attributes>) { + if constexpr (supports_attributes>) { return _w.add_null_to_object(_parent.name_, _parent.obj_, _parent.is_attribute_); } else { @@ -81,11 +81,11 @@ struct Parent { template static OutputVarType add_value(const W& _w, const T& _var, const ParentType& _parent) { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (std::is_same()) { return _w.add_value_to_array(_var, _parent.arr_); } else if constexpr (std::is_same()) { - if constexpr (supports_attributes>) { + if constexpr (supports_attributes>) { return _w.add_value_to_object(_parent.name_, _var, _parent.obj_, _parent.is_attribute_); } else { diff --git a/include/rfl/parsing/Parser_array.hpp b/include/rfl/parsing/Parser_array.hpp index bd6dabf8..839d15e7 100644 --- a/include/rfl/parsing/Parser_array.hpp +++ b/include/rfl/parsing/Parser_array.hpp @@ -52,7 +52,7 @@ struct Parser> { auto arr = ParentType::add_array(_w, _size, _parent); const auto new_parent = typename ParentType::Array{&arr}; for (auto it = _arr.begin(); it != _arr.end(); ++it) { - Parser>::write(_w, *it, new_parent); + Parser>::write(_w, *it, new_parent); } _w.end_array(&arr); } diff --git a/include/rfl/parsing/Parser_box.hpp b/include/rfl/parsing/Parser_box.hpp index ddcd846b..7c7ba208 100644 --- a/include/rfl/parsing/Parser_box.hpp +++ b/include/rfl/parsing/Parser_box.hpp @@ -25,7 +25,7 @@ struct Parser> { template static void write(const W& _w, const Box& _box, const P& _parent) noexcept { - Parser>::write(_w, *_box, _parent); + Parser>::write(_w, *_box, _parent); } }; diff --git a/include/rfl/parsing/Parser_default.hpp b/include/rfl/parsing/Parser_default.hpp index 2c3f46a7..ec34fff0 100644 --- a/include/rfl/parsing/Parser_default.hpp +++ b/include/rfl/parsing/Parser_default.hpp @@ -72,7 +72,7 @@ struct Parser { template static void write(const W& _w, const T& _var, const P& _parent) noexcept { if constexpr (internal::has_reflection_type_v) { - using ReflectionType = std::decay_t; + using ReflectionType = std::remove_cvref_t; if constexpr (internal::has_reflection_method_v) { Parser::write(_w, _var.reflection(), _parent); } else { @@ -81,7 +81,7 @@ struct Parser { } } else if constexpr (std::is_class_v && std::is_aggregate_v) { const auto ptr_named_tuple = internal::to_ptr_named_tuple(_var); - using PtrNamedTupleType = std::decay_t; + using PtrNamedTupleType = std::remove_cvref_t; Parser::write(_w, ptr_named_tuple, _parent); } else if constexpr (std::is_enum_v) { using StringConverter = internal::enums::StringConverter; diff --git a/include/rfl/parsing/Parser_optional.hpp b/include/rfl/parsing/Parser_optional.hpp index c7b76c8d..8e1c7144 100644 --- a/include/rfl/parsing/Parser_optional.hpp +++ b/include/rfl/parsing/Parser_optional.hpp @@ -37,7 +37,7 @@ struct Parser> { ParentType::add_null(_w, _parent); return; } - Parser>::write(_w, *_o, _parent); + Parser>::write(_w, *_o, _parent); } }; diff --git a/include/rfl/parsing/Parser_ptr.hpp b/include/rfl/parsing/Parser_ptr.hpp index 20981605..20ed3f1d 100644 --- a/include/rfl/parsing/Parser_ptr.hpp +++ b/include/rfl/parsing/Parser_ptr.hpp @@ -36,7 +36,7 @@ struct Parser { ParentType::add_null(_w, _parent); return; } - Parser>::write(_w, *_ptr, _parent); + Parser>::write(_w, *_ptr, _parent); } }; diff --git a/include/rfl/parsing/Parser_ref.hpp b/include/rfl/parsing/Parser_ref.hpp index 3a51ee87..72189840 100644 --- a/include/rfl/parsing/Parser_ref.hpp +++ b/include/rfl/parsing/Parser_ref.hpp @@ -26,7 +26,7 @@ struct Parser> { template static void write(const W& _w, const Ref& _ref, const P& _parent) noexcept { - Parser>::write(_w, *_ref, _parent); + Parser>::write(_w, *_ref, _parent); } }; diff --git a/include/rfl/parsing/Parser_reference_wrapper.hpp b/include/rfl/parsing/Parser_reference_wrapper.hpp index fbc76dba..bb5d0009 100644 --- a/include/rfl/parsing/Parser_reference_wrapper.hpp +++ b/include/rfl/parsing/Parser_reference_wrapper.hpp @@ -31,7 +31,7 @@ struct Parser> { template static void write(const W& _w, const std::reference_wrapper _ref, const P& _p) noexcept { - Parser>::write(_w, _ref.get(), _p); + Parser>::write(_w, _ref.get(), _p); } }; diff --git a/include/rfl/parsing/Parser_rename.hpp b/include/rfl/parsing/Parser_rename.hpp index d06674f5..89857a66 100644 --- a/include/rfl/parsing/Parser_rename.hpp +++ b/include/rfl/parsing/Parser_rename.hpp @@ -30,7 +30,7 @@ struct Parser> { template static void write(const W& _w, const Rename<_name, T>& _rename, const P& _parent) noexcept { - Parser>::write(_w, _rename.value(), _parent); + Parser>::write(_w, _rename.value(), _parent); } }; diff --git a/include/rfl/parsing/Parser_shared_ptr.hpp b/include/rfl/parsing/Parser_shared_ptr.hpp index 551aee47..d03ab412 100644 --- a/include/rfl/parsing/Parser_shared_ptr.hpp +++ b/include/rfl/parsing/Parser_shared_ptr.hpp @@ -39,7 +39,7 @@ struct Parser> { ParentType::add_null(_w, _parent); return; } - Parser>::write(_w, *_s, _parent); + Parser>::write(_w, *_s, _parent); } }; diff --git a/include/rfl/parsing/Parser_unique_ptr.hpp b/include/rfl/parsing/Parser_unique_ptr.hpp index 17475b96..a8b269fb 100644 --- a/include/rfl/parsing/Parser_unique_ptr.hpp +++ b/include/rfl/parsing/Parser_unique_ptr.hpp @@ -39,7 +39,7 @@ struct Parser> { ParentType::add_null(_w, _parent); return; } - Parser>::write(_w, *_s, _parent); + Parser>::write(_w, *_s, _parent); } }; diff --git a/include/rfl/parsing/VectorParser.hpp b/include/rfl/parsing/VectorParser.hpp index 7f869ec5..db2bc8f8 100644 --- a/include/rfl/parsing/VectorParser.hpp +++ b/include/rfl/parsing/VectorParser.hpp @@ -58,7 +58,7 @@ struct VectorParser { _w, std::distance(_vec.begin(), _vec.end()), _parent); const auto new_parent = typename ParentType::Array{&arr}; for (const auto& v : _vec) { - Parser>::write(_w, v, new_parent); + Parser>::write(_w, v, new_parent); } _w.end_array(&arr); } diff --git a/include/rfl/parsing/is_empty.hpp b/include/rfl/parsing/is_empty.hpp index 205f0d2d..3d9dfd4b 100644 --- a/include/rfl/parsing/is_empty.hpp +++ b/include/rfl/parsing/is_empty.hpp @@ -14,7 +14,7 @@ namespace parsing { template static const bool is_empty(const T& _var) { - using Type = std::decay_t; + using Type = std::remove_cvref_t; if constexpr (std::is_pointer_v) { return !_var || is_empty(*_var); } else if constexpr (internal::has_reflection_type_v) { diff --git a/include/rfl/xml/Writer.hpp b/include/rfl/xml/Writer.hpp index aa45737d..009d2e48 100644 --- a/include/rfl/xml/Writer.hpp +++ b/include/rfl/xml/Writer.hpp @@ -156,12 +156,12 @@ struct Writer { private: template std::string to_string(const T& _val) const noexcept { - if constexpr (std::is_same, std::string>()) { + if constexpr (std::is_same, std::string>()) { return _val; - } else if constexpr (std::is_same, bool>()) { + } else if constexpr (std::is_same, bool>()) { return _val ? "true" : "false"; - } else if constexpr (std::is_floating_point>() || - std::is_integral>()) { + } else if constexpr (std::is_floating_point>() || + std::is_integral>()) { return std::to_string(_val); } else { static_assert(always_false_v, "Unsupported type"); diff --git a/include/rfl/yaml/Reader.hpp b/include/rfl/yaml/Reader.hpp index c9b0f18e..91fcac84 100644 --- a/include/rfl/yaml/Reader.hpp +++ b/include/rfl/yaml/Reader.hpp @@ -65,11 +65,11 @@ struct Reader { template rfl::Result to_basic_type(const InputVarType& _var) const noexcept { try { - if constexpr (std::is_same, std::string>() || - std::is_same, bool>() || - std::is_floating_point>() || - std::is_integral>()) { - return _var.node_.as>(); + if constexpr (std::is_same, std::string>() || + std::is_same, bool>() || + std::is_floating_point>() || + std::is_integral>()) { + return _var.node_.as>(); } else { static_assert(rfl::always_false_v, "Unsupported type."); } From e01ff0b3b1b68dd7df51c2ddf5c485fe82cf5649 Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Wed, 3 Jan 2024 16:40:43 +0100 Subject: [PATCH 09/17] Some more adaptations --- include/rfl/parsing/Parser_array.hpp | 4 ++-- include/rfl/parsing/Parser_c_array.hpp | 17 +++++++++++------ include/rfl/parsing/Parser_result.hpp | 9 ++++++--- include/rfl/parsing/Parser_rfl_array.hpp | 11 ++++++----- include/rfl/parsing/Parser_variant.hpp | 2 +- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/include/rfl/parsing/Parser_array.hpp b/include/rfl/parsing/Parser_array.hpp index 839d15e7..751ed803 100644 --- a/include/rfl/parsing/Parser_array.hpp +++ b/include/rfl/parsing/Parser_array.hpp @@ -51,8 +51,8 @@ struct Parser> { const P& _parent) noexcept { auto arr = ParentType::add_array(_w, _size, _parent); const auto new_parent = typename ParentType::Array{&arr}; - for (auto it = _arr.begin(); it != _arr.end(); ++it) { - Parser>::write(_w, *it, new_parent); + for (const auto& e : _arr) { + Parser>::write(_w, e, new_parent); } _w.end_array(&arr); } diff --git a/include/rfl/parsing/Parser_c_array.hpp b/include/rfl/parsing/Parser_c_array.hpp index dd539aa6..abda05e3 100644 --- a/include/rfl/parsing/Parser_c_array.hpp +++ b/include/rfl/parsing/Parser_c_array.hpp @@ -7,6 +7,7 @@ #include "../Result.hpp" #include "../always_false.hpp" #include "../internal/to_std_array.hpp" +#include "Parent.hpp" #include "Parser_array.hpp" #include "Parser_base.hpp" @@ -14,7 +15,7 @@ namespace rfl { namespace parsing { template - requires AreReaderAndWriter +requires AreReaderAndWriter struct Parser { public: using InputArrayType = typename R::InputArrayType; @@ -23,20 +24,24 @@ struct Parser { using OutputArrayType = typename W::OutputArrayType; using OutputVarType = typename W::OutputVarType; + using ParentType = Parent; using CArray = T[_size]; - using StdArray = internal::to_std_array_t; static Result> read(const R& _r, const InputVarType& _var) noexcept { + using StdArray = internal::to_std_array_t; return Parser::read(_r, _var); } - static OutputVarType write(const W& _w, const CArray& _arr) noexcept { - auto arr = _w.new_array(); + template + static void write(const W& _w, const CArray& _arr, + const P& _parent) noexcept { + auto arr = ParentType::add_array(_w, _size, _parent); + const auto new_parent = typename ParentType::Array{&arr}; for (const auto& e : _arr) { - _w.add(Parser>::write(_w, e), &arr); + Parser>::write(_w, e, new_parent); } - return OutputVarType(arr); + _w.end_array(&arr); } }; diff --git a/include/rfl/parsing/Parser_result.hpp b/include/rfl/parsing/Parser_result.hpp index db7d2d30..303cf3b4 100644 --- a/include/rfl/parsing/Parser_result.hpp +++ b/include/rfl/parsing/Parser_result.hpp @@ -39,9 +39,12 @@ struct Parser> { Parser::read(_r, _var).transform(to_res)); } - static OutputVarType write(const W& _w, const Result& _r) noexcept { - const auto write_t = [&](const auto& _t) -> OutputVarType { - return Parser>::write(_w, _t); + template + static void write(const W& _w, const Result& _r, + const P& _parent) noexcept { + const auto write_t = [&](const auto& _t) -> Nothing { + Parser>::write(_w, _t, _parent); + return Nothing{}; }; const auto write_err = [&](const auto& _err) -> Nothing { diff --git a/include/rfl/parsing/Parser_rfl_array.hpp b/include/rfl/parsing/Parser_rfl_array.hpp index d0e51a26..eb4ea53c 100644 --- a/include/rfl/parsing/Parser_rfl_array.hpp +++ b/include/rfl/parsing/Parser_rfl_array.hpp @@ -14,7 +14,7 @@ namespace rfl { namespace parsing { template - requires AreReaderAndWriter> +requires AreReaderAndWriter> struct Parser> { public: using InputArrayType = typename R::InputArrayType; @@ -23,15 +23,16 @@ struct Parser> { using OutputArrayType = typename W::OutputArrayType; using OutputVarType = typename W::OutputVarType; - using RflArray = Array; using StdArray = internal::to_std_array_t; - static Result read(const R& _r, const InputVarType& _var) noexcept { + static Result> read(const R& _r, const InputVarType& _var) noexcept { return Parser::read(_r, _var); } - static OutputVarType write(const W& _w, const RflArray& _arr) noexcept { - return Parser::write(_w, _arr); + template + static void write(const W& _w, const Array& _arr, + const P& _parent) noexcept { + Parser::write(_w, _arr, _parent); } }; diff --git a/include/rfl/parsing/Parser_variant.hpp b/include/rfl/parsing/Parser_variant.hpp index 5d0c909a..e46628b6 100644 --- a/include/rfl/parsing/Parser_variant.hpp +++ b/include/rfl/parsing/Parser_variant.hpp @@ -57,7 +57,7 @@ struct Parser> { } else { const auto handle = [&](const auto& _v) { using Type = std::remove_cvref_t; - return Parser::write(_w, _v); + Parser::write(_w, _v, _parent); }; return std::visit(handle, _variant); } From fe441a2d9d93f6999df0c2a7bc3afb667cdd31c3 Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Wed, 3 Jan 2024 16:56:40 +0100 Subject: [PATCH 10/17] Apply 'composition over inheritance' to rfl::Array --- include/rfl/Array.hpp | 19 +++++++++++-------- include/rfl/parsing/Parser_rfl_array.hpp | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/rfl/Array.hpp b/include/rfl/Array.hpp index 33529059..7e4f931e 100644 --- a/include/rfl/Array.hpp +++ b/include/rfl/Array.hpp @@ -8,17 +8,20 @@ namespace rfl { template - requires std::is_array_v -struct Array : internal::to_std_array_t { +requires std::is_array_v +struct Array { using Type = T; - using Base = internal::to_std_array_t; - using Base::Base; + using StdArrayType = internal::to_std_array_t; Array() = default; - Array(const Base &t) : Base(t) {} - Array(Base &&t) : Base(std::move(t)) {} - Array(const T &t) : Base(reinterpret_cast(t)) {} - Array(T &&t) : Base(reinterpret_cast(t)) {} + Array(const StdArrayType &_arr) : arr_(_arr) {} + Array(StdArrayType &&_arr) : arr_(std::move(_arr)) {} + Array(const T &_t) : arr_(reinterpret_cast(_t)) {} + Array(T &&_t) : arr_(reinterpret_cast(_t)) {} + + ~Array() = default; + + StdArrayType arr_; }; } // namespace rfl diff --git a/include/rfl/parsing/Parser_rfl_array.hpp b/include/rfl/parsing/Parser_rfl_array.hpp index eb4ea53c..e5fd4004 100644 --- a/include/rfl/parsing/Parser_rfl_array.hpp +++ b/include/rfl/parsing/Parser_rfl_array.hpp @@ -32,7 +32,7 @@ struct Parser> { template static void write(const W& _w, const Array& _arr, const P& _parent) noexcept { - Parser::write(_w, _arr, _parent); + Parser::write(_w, _arr.arr_, _parent); } }; From d6f3fa510dca85465ae056719932875ccb3af6df Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Wed, 3 Jan 2024 17:40:42 +0100 Subject: [PATCH 11/17] Got rid of the reinterpret_casts --- include/rfl/Array.hpp | 2 - include/rfl/internal/move_from_tuple.hpp | 49 +++++++++++++---- include/rfl/xml/OutputValue.hpp | 67 ------------------------ 3 files changed, 38 insertions(+), 80 deletions(-) delete mode 100644 include/rfl/xml/OutputValue.hpp diff --git a/include/rfl/Array.hpp b/include/rfl/Array.hpp index 7e4f931e..88059b64 100644 --- a/include/rfl/Array.hpp +++ b/include/rfl/Array.hpp @@ -16,8 +16,6 @@ struct Array { Array() = default; Array(const StdArrayType &_arr) : arr_(_arr) {} Array(StdArrayType &&_arr) : arr_(std::move(_arr)) {} - Array(const T &_t) : arr_(reinterpret_cast(_t)) {} - Array(T &&_t) : arr_(reinterpret_cast(_t)) {} ~Array() = default; diff --git a/include/rfl/internal/move_from_tuple.hpp b/include/rfl/internal/move_from_tuple.hpp index f10bebd8..6bda97a2 100644 --- a/include/rfl/internal/move_from_tuple.hpp +++ b/include/rfl/internal/move_from_tuple.hpp @@ -83,22 +83,48 @@ auto move_from_pointers(Pointers& _ptrs, Args&&... _args) { } } -template -auto make_tuple_from_element(T (*arr)[n]) { - if constexpr (std::is_array_v) { +template +struct is_std_array : public std::false_type {}; + +template +struct is_std_array> : public std::true_type {}; + +template +constexpr bool is_std_array_v = is_std_array::value; + +template +auto make_tuple_from_element(T (*_arr)[_n]) { + if constexpr (std::is_array_v || is_std_array_v) { + return [&](std::index_sequence) { + return std::tuple_cat(make_tuple_from_element(&(*_arr)[i])...); + } + (std::make_index_sequence<_n>()); + } else { return [&](std::index_sequence) { - return std::tuple_cat(make_tuple_from_element(&(*arr)[i])...); - }(std::make_index_sequence()); + return std::make_tuple(&(*_arr)[i]...); + } + (std::make_index_sequence<_n>()); + } +} + +template +auto make_tuple_from_element(std::array* _arr) { + if constexpr (std::is_array_v || is_std_array_v) { + return [&](std::index_sequence) { + return std::tuple_cat(make_tuple_from_element(&(*_arr)[i])...); + } + (std::make_index_sequence<_n>()); } else { return [&](std::index_sequence) { - return std::make_tuple(&(*arr)[i]...); - }(std::make_index_sequence()); + return std::make_tuple(&(*_arr)[i]...); + } + (std::make_index_sequence<_n>()); } } template -auto make_tuple_from_element(Array* arr) { - return make_tuple_from_element(reinterpret_cast(arr)); +auto make_tuple_from_element(Array* _arr) { + return make_tuple_from_element(&(_arr->arr_)); } auto make_tuple_from_element(auto& e) { return std::make_tuple(e); } @@ -106,8 +132,9 @@ auto make_tuple_from_element(auto& e) { return std::make_tuple(e); } auto flatten_c_arrays(const auto& tuple) { return [&](std::index_sequence) { return std::tuple_cat(make_tuple_from_element(std::get(tuple))...); - }(std::make_index_sequence< - std::tuple_size_v>>()); + } + (std::make_index_sequence< + std::tuple_size_v>>()); } /// Creates a struct of type T from a tuple by moving the underlying diff --git a/include/rfl/xml/OutputValue.hpp b/include/rfl/xml/OutputValue.hpp deleted file mode 100644 index c03defa5..00000000 --- a/include/rfl/xml/OutputValue.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef RFL_XML_OUTPUTVALUE_HPP_ -#define RFL_XML_OUTPUTVALUE_HPP_ - -#include -#include -#include - -#include "../always_false.hpp" -#include "OutputVar.hpp" - -namespace rfl { -namespace xml { - -template -class OutputValue : public OutputVar { - public: - static constexpr const char* XML_CONTENT = "xml_content"; - - public: - OutputValue(T _val, bool _is_attribute) - : is_attribute_(_is_attribute), val_(_val) {} - - ~OutputValue() = default; - - /// Inserts all elements into the builder. - void insert(const std::string& _key, pugi::xml_node* _parent) final { - const auto str = to_string(); - if (is_attribute_) { - _parent->append_attribute(_key.c_str()) = str.c_str(); - } else if (_key == XML_CONTENT) { - _parent->append_child(pugi::node_pcdata).set_value(str.c_str()); - } else { - auto node_child = _parent->append_child(_key.c_str()); - node_child.append_child(pugi::node_pcdata).set_value(str.c_str()); - } - }; - - /// Whether this is null. - bool is_null() const final { return false; } - - private: - /// Transforms the underlying value into a string. - std::string to_string() { - if constexpr (std::is_same, std::string>()) { - return val_; - } else if constexpr (std::is_same, bool>()) { - return val_ ? "true" : "false"; - } else if constexpr (std::is_floating_point>() || - std::is_integral>()) { - return std::to_string(val_); - } else { - static_assert(always_false_v, "Unsupported type"); - } - } - - private: - /// Whether you want this encoded as an attribute. - bool is_attribute_; - - /// The underlying value. - T val_; -}; - -} // namespace xml -} // namespace rfl - -#endif From f9f5cc77924f592053979be70f94af778decd8d4 Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Wed, 3 Jan 2024 17:43:50 +0100 Subject: [PATCH 12/17] Got rid of stray OutputValue.hpp --- include/rfl/flexbuf/OutputValue.hpp | 67 ----------------------------- 1 file changed, 67 deletions(-) delete mode 100644 include/rfl/flexbuf/OutputValue.hpp diff --git a/include/rfl/flexbuf/OutputValue.hpp b/include/rfl/flexbuf/OutputValue.hpp deleted file mode 100644 index 72d852d2..00000000 --- a/include/rfl/flexbuf/OutputValue.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef FLEXBUF_OUTPUTVALUE_HPP_ -#define FLEXBUF_OUTPUTVALUE_HPP_ - -#include - -#include -#include -#include - -#include "../Ref.hpp" -#include "../always_false.hpp" -#include "OutputVar.hpp" - -namespace rfl { -namespace flexbuf { - -template -class OutputValue : public OutputVar { - public: - OutputValue(T _val) : val_(_val) {} - - ~OutputValue() = default; - - /// Inserts all elements into the builder. - void insert(const std::optional& _key, - flexbuffers::Builder* _fbb) final { - if constexpr (std::is_same, std::string>()) { - if (_key) { - _fbb->String(_key->c_str(), val_); - } else { - _fbb->String(val_); - } - } else if constexpr (std::is_same, bool>()) { - if (_key) { - _fbb->Bool(_key->c_str(), val_); - } else { - _fbb->Bool(val_); - } - } else if constexpr (std::is_floating_point>()) { - if (_key) { - _fbb->Double(_key->c_str(), val_); - } else { - _fbb->Double(val_); - } - } else if constexpr (std::is_integral>()) { - if (_key) { - _fbb->Int(_key->c_str(), val_); - } else { - _fbb->Int(val_); - } - } else { - static_assert(always_false_v, "Unsupported type"); - } - }; - - /// Whether this is null. - bool is_null() const final { return false; } - - private: - /// The underlying value. - T val_; -}; - -} // namespace flexbuf -} // namespace rfl - -#endif From f4d2cf57d7bcf2fae0a501130760457737a02569 Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Wed, 3 Jan 2024 23:13:33 +0100 Subject: [PATCH 13/17] Simplified flatten_c_arrays --- include/rfl/internal/move_from_tuple.hpp | 59 ++++++++---------------- 1 file changed, 18 insertions(+), 41 deletions(-) diff --git a/include/rfl/internal/move_from_tuple.hpp b/include/rfl/internal/move_from_tuple.hpp index 6bda97a2..2b381235 100644 --- a/include/rfl/internal/move_from_tuple.hpp +++ b/include/rfl/internal/move_from_tuple.hpp @@ -84,57 +84,33 @@ auto move_from_pointers(Pointers& _ptrs, Args&&... _args) { } template -struct is_std_array : public std::false_type {}; - -template -struct is_std_array> : public std::true_type {}; - -template -constexpr bool is_std_array_v = is_std_array::value; +auto flatten_array(T* _v) { + return std::make_tuple(_v); +} template -auto make_tuple_from_element(T (*_arr)[_n]) { - if constexpr (std::is_array_v || is_std_array_v) { - return [&](std::index_sequence) { - return std::tuple_cat(make_tuple_from_element(&(*_arr)[i])...); - } - (std::make_index_sequence<_n>()); - } else { - return [&](std::index_sequence) { - return std::make_tuple(&(*_arr)[i]...); - } - (std::make_index_sequence<_n>()); - } +auto flatten_array(std::array* _arr) { + const auto fct = [](auto&... _v) { + return std::tuple_cat(flatten_array(&_v)...); + }; + return std::apply(fct, *_arr); } -template -auto make_tuple_from_element(std::array* _arr) { - if constexpr (std::is_array_v || is_std_array_v) { - return [&](std::index_sequence) { - return std::tuple_cat(make_tuple_from_element(&(*_arr)[i])...); - } - (std::make_index_sequence<_n>()); - } else { - return [&](std::index_sequence) { - return std::make_tuple(&(*_arr)[i]...); - } - (std::make_index_sequence<_n>()); - } +template +auto make_tuple_from_element(T _v) { + return std::make_tuple(_v); } template auto make_tuple_from_element(Array* _arr) { - return make_tuple_from_element(&(_arr->arr_)); + return flatten_array(&(_arr->arr_)); } -auto make_tuple_from_element(auto& e) { return std::make_tuple(e); } - -auto flatten_c_arrays(const auto& tuple) { - return [&](std::index_sequence) { - return std::tuple_cat(make_tuple_from_element(std::get(tuple))...); - } - (std::make_index_sequence< - std::tuple_size_v>>()); +auto flatten_c_arrays(const auto& _tup) { + const auto fct = [](auto... _v) { + return std::tuple_cat(make_tuple_from_element(_v)...); + }; + return std::apply(fct, _tup); } /// Creates a struct of type T from a tuple by moving the underlying @@ -147,6 +123,7 @@ T move_from_tuple(TupleType&& _t) { auto pointers = flatten_c_arrays(unflatten_ptr_tuple(ptr_tuple)); + return move_from_pointers(pointers); } From a89cca0a947f99c62439ddbcbcd701b1a80b7757 Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Thu, 4 Jan 2024 04:14:42 +0100 Subject: [PATCH 14/17] Added explanatory comments to num_fields.hpp --- include/rfl/internal/num_fields.hpp | 50 +++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/include/rfl/internal/num_fields.hpp b/include/rfl/internal/num_fields.hpp index 64d234f5..f7198d34 100644 --- a/include/rfl/internal/num_fields.hpp +++ b/include/rfl/internal/num_fields.hpp @@ -1,10 +1,44 @@ #ifndef RFL_INTERNAL_NUM_FIELDS_HPP_ #define RFL_INTERNAL_NUM_FIELDS_HPP_ +/* +We infer the number of fields using by figuring out how many fields +we need to construct it. This is done by implementing the constructible +concept, see below. + +However, there is a problem with C arrays. Suppose you have a struct +like this: + +struct A{ + int arr[3]; +}; + +Then, the struct can be initialized like this: + +const auto a = A{1, 2, 3}; + +This is a problem, because a naive logic would believe that A +has three fields, when in fact it has only one. + +That is why we use the constructible concept to get the maximum +possible number of fields and then try to subdivide them into arrays +in order to figure out which of these fields is in fact an array. + +Basically, for every field there is, we try to squeeze as many variables into +the potential array as we can without missing variables in subsequent fields. +This is the purpose of get_nested_array_size(). +*/ + #include #include #include +#if __GNUC__ +#ifndef __clang__ +#pragma GCC system_header +#endif +#endif + namespace rfl { namespace internal { @@ -15,22 +49,24 @@ struct any { }; template -struct count_fields_helper { +struct CountFieldsHelper { template static consteval bool constructible() { return [](std::index_sequence) { return requires { T{any(is)...}; }; - }(std::make_index_sequence()); + } + (std::make_index_sequence()); } template static consteval bool constructible_with_nested() { return []( - std::index_sequence, std::index_sequence, - std::index_sequence) { + std::index_sequence, std::index_sequence, + std::index_sequence) { return requires { T{any(i)..., {any(j)...}, any(k)...}; }; - }(std::make_index_sequence(), std::make_index_sequence(), - std::make_index_sequence()); + } + (std::make_index_sequence(), std::make_index_sequence(), + std::make_index_sequence()); } template @@ -73,7 +109,7 @@ struct count_fields_helper { }; template -constexpr std::size_t num_fields = count_fields_helper::count_fields(); +constexpr std::size_t num_fields = CountFieldsHelper::count_fields(); } // namespace internal } // namespace rfl From 03f6f2ef44551608e7bfad6d234b3d86c464f0c1 Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Thu, 4 Jan 2024 04:39:36 +0100 Subject: [PATCH 15/17] Moved Array.hpp and wrap_in_rfl_array_t into internal --- include/rfl/Field.hpp | 4 +-- include/rfl/flexbuf/read.hpp | 9 +++--- include/rfl/{ => internal}/Array.hpp | 10 ++++--- include/rfl/internal/move_from_tuple.hpp | 2 +- .../{ => internal}/wrap_in_rfl_array_t.hpp | 8 +++-- include/rfl/json/read.hpp | 7 ++--- include/rfl/named_tuple_t.hpp | 6 ++-- include/rfl/parsing/IsReader.hpp | 29 ++++++++++--------- include/rfl/parsing/Parser_c_array.hpp | 8 ++--- include/rfl/parsing/Parser_rfl_array.hpp | 11 +++---- include/rfl/xml/read.hpp | 7 ++--- include/rfl/yaml/read.hpp | 6 ++-- 12 files changed, 55 insertions(+), 52 deletions(-) rename include/rfl/{ => internal}/Array.hpp (64%) rename include/rfl/{ => internal}/wrap_in_rfl_array_t.hpp (67%) diff --git a/include/rfl/Field.hpp b/include/rfl/Field.hpp index 8d833179..5ebe4374 100644 --- a/include/rfl/Field.hpp +++ b/include/rfl/Field.hpp @@ -7,9 +7,9 @@ #include #include -#include "Array.hpp" #include "Literal.hpp" #include "default.hpp" +#include "internal/Array.hpp" #include "internal/StringLiteral.hpp" #include "internal/to_std_array.hpp" @@ -139,7 +139,7 @@ template inline auto make_field(T&& _value) { using T0 = std::remove_cvref_t; if constexpr (std::is_array_v) { - return Field<_name, T0>(rfl::Array(std::forward(_value))); + return Field<_name, T0>(internal::Array(std::forward(_value))); } else { return Field<_name, T0>(std::forward(_value)); } diff --git a/include/rfl/flexbuf/read.hpp b/include/rfl/flexbuf/read.hpp index 7f596b93..3a4cf9f3 100644 --- a/include/rfl/flexbuf/read.hpp +++ b/include/rfl/flexbuf/read.hpp @@ -7,7 +7,6 @@ #include #include "../Result.hpp" -#include "../wrap_in_rfl_array_t.hpp" #include "Parser.hpp" namespace rfl { @@ -17,14 +16,14 @@ using InputVarType = typename Reader::InputVarType; /// Parses an object from flexbuf var. template -Result> read(const InputVarType& _obj) { +auto read(const InputVarType& _obj) { const auto r = Reader(); return Parser::read(r, _obj); } /// Parses an object from flexbuf using reflection. template -Result> read(const char* _bytes, const size_t _size) { +auto read(const char* _bytes, const size_t _size) { const InputVarType root = flexbuffers::GetRoot(reinterpret_cast(_bytes), _size); return read(root); @@ -32,13 +31,13 @@ Result> read(const char* _bytes, const size_t _size) { /// Parses an object from flexbuf using reflection. template -Result> read(const std::vector& _bytes) { +auto read(const std::vector& _bytes) { return read(_bytes.data(), _bytes.size()); } /// Parses an object directly from a stream. template -Result> read(std::istream& _stream) { +auto read(std::istream& _stream) { std::istreambuf_iterator begin(_stream), end; const auto bytes = std::vector(begin, end); return read(bytes.data(), bytes.size()); diff --git a/include/rfl/Array.hpp b/include/rfl/internal/Array.hpp similarity index 64% rename from include/rfl/Array.hpp rename to include/rfl/internal/Array.hpp index 88059b64..5341b578 100644 --- a/include/rfl/Array.hpp +++ b/include/rfl/internal/Array.hpp @@ -1,17 +1,18 @@ -#ifndef RFL_ARRAY_HPP_ -#define RFL_ARRAY_HPP_ +#ifndef RFL_INTERNAL_ARRAY_HPP_ +#define RFL_INTERNAL_ARRAY_HPP_ #include -#include "internal/to_std_array.hpp" +#include "to_std_array.hpp" namespace rfl { +namespace internal { template requires std::is_array_v struct Array { using Type = T; - using StdArrayType = internal::to_std_array_t; + using StdArrayType = to_std_array_t; Array() = default; Array(const StdArrayType &_arr) : arr_(_arr) {} @@ -22,6 +23,7 @@ struct Array { StdArrayType arr_; }; +} // namespace internal } // namespace rfl #endif diff --git a/include/rfl/internal/move_from_tuple.hpp b/include/rfl/internal/move_from_tuple.hpp index 2b381235..3ddcd4e4 100644 --- a/include/rfl/internal/move_from_tuple.hpp +++ b/include/rfl/internal/move_from_tuple.hpp @@ -4,7 +4,7 @@ #include #include -#include "../Array.hpp" +#include "Array.hpp" #include "is_flatten_field.hpp" #include "is_named_tuple.hpp" #include "ptr_tuple_t.hpp" diff --git a/include/rfl/wrap_in_rfl_array_t.hpp b/include/rfl/internal/wrap_in_rfl_array_t.hpp similarity index 67% rename from include/rfl/wrap_in_rfl_array_t.hpp rename to include/rfl/internal/wrap_in_rfl_array_t.hpp index 24ea6254..2378d579 100644 --- a/include/rfl/wrap_in_rfl_array_t.hpp +++ b/include/rfl/internal/wrap_in_rfl_array_t.hpp @@ -1,11 +1,12 @@ -#ifndef RFL_WRAP_IN_RFL_ARRAY_T_ -#define RFL_WRAP_IN_RFL_ARRAY_T_ +#ifndef RFL_INTERNAL_WRAP_IN_RFL_ARRAY_T_ +#define RFL_INTERNAL_WRAP_IN_RFL_ARRAY_T_ #include #include "Array.hpp" namespace rfl { +namespace internal { template struct wrap_in_rfl_array { @@ -13,7 +14,7 @@ struct wrap_in_rfl_array { }; template - requires std::is_array_v +requires std::is_array_v struct wrap_in_rfl_array { using type = Array; }; @@ -21,6 +22,7 @@ struct wrap_in_rfl_array { template using wrap_in_rfl_array_t = typename wrap_in_rfl_array::type; +} // namespace internal } // namespace rfl #endif diff --git a/include/rfl/json/read.hpp b/include/rfl/json/read.hpp index cea84ab1..c8b7d926 100644 --- a/include/rfl/json/read.hpp +++ b/include/rfl/json/read.hpp @@ -6,7 +6,6 @@ #include #include -#include "../wrap_in_rfl_array_t.hpp" #include "Parser.hpp" #include "Reader.hpp" @@ -18,14 +17,14 @@ using InputVarType = typename Reader::InputVarType; /// Parses an object from a JSON var. template -Result> read(const InputVarType& _obj) { +auto read(const InputVarType& _obj) { const auto r = Reader(); return Parser::read(r, _obj); } /// Parses an object from JSON using reflection. template -Result> read(const std::string& _json_str) { +auto read(const std::string& _json_str) { using PtrType = std::unique_ptr; yyjson_doc* doc = yyjson_read(_json_str.c_str(), _json_str.size(), 0); const auto ptr = PtrType(doc, yyjson_doc_free); @@ -34,7 +33,7 @@ Result> read(const std::string& _json_str) { /// Parses an object from a stringstream. template -Result> read(std::istream& _stream) { +auto read(std::istream& _stream) { const auto json_str = std::string(std::istreambuf_iterator(_stream), std::istreambuf_iterator()); return read(json_str); diff --git a/include/rfl/named_tuple_t.hpp b/include/rfl/named_tuple_t.hpp index 2f1cc635..d1bfd385 100644 --- a/include/rfl/named_tuple_t.hpp +++ b/include/rfl/named_tuple_t.hpp @@ -8,8 +8,8 @@ #include "NamedTuple.hpp" #include "internal/is_named_tuple.hpp" #include "internal/ptr_named_tuple_t.hpp" +#include "internal/wrap_in_rfl_array_t.hpp" #include "to_named_tuple.hpp" -#include "wrap_in_rfl_array_t.hpp" namespace rfl { @@ -19,8 +19,8 @@ struct remove_ptr; template struct remove_ptr> { using FieldType = - Field<_name, - wrap_in_rfl_array_t>>>; + Field<_name, internal::wrap_in_rfl_array_t< + std::remove_cvref_t>>>; }; template diff --git a/include/rfl/parsing/IsReader.hpp b/include/rfl/parsing/IsReader.hpp index b3099ee1..383aff8d 100644 --- a/include/rfl/parsing/IsReader.hpp +++ b/include/rfl/parsing/IsReader.hpp @@ -11,16 +11,17 @@ #include "../Result.hpp" #include "../internal/is_basic_type.hpp" -#include "../wrap_in_rfl_array_t.hpp" +#include "../internal/wrap_in_rfl_array_t.hpp" namespace rfl { namespace parsing { template -concept IsReader = requires( - R r, std::string name, std::function fct, - typename R::InputArrayType arr, typename R::InputObjectType obj, - typename R::InputVarType var) { +concept IsReader = requires(R r, std::string name, + std::function fct, + typename R::InputArrayType arr, + typename R::InputObjectType obj, + typename R::InputVarType var) { /// Any Reader needs to define the following: /// /// 1) An InputArrayType, which must be an array-like data structure. @@ -35,7 +36,7 @@ concept IsReader = requires( /// Retrieves a particular field from an object. { r.get_field(name, obj) - } -> std::same_as>; + } -> std::same_as>; /// Determines whether a variable is empty (the NULL type). { r.is_empty(var) } -> std::same_as; @@ -43,15 +44,15 @@ concept IsReader = requires( /// Transforms var to a basic type (bool, integral, /// floating point, std::string) { - r.template to_basic_type>(var) - } -> std::same_as>>; + r.template to_basic_type>(var) + } -> std::same_as>>; /// _fct is a function that turns the field name into the field index of the /// struct. It returns -1, if the fields does not exist on the struct. This /// returns an std::array that can be used to build up the struct. { r.template to_fields_array<6>(fct, obj) - } -> std::same_as, 6>>; + } -> std::same_as, 6>>; /// Casts var as an InputArrayType. { r.to_array(var) } -> std::same_as>; @@ -60,13 +61,13 @@ concept IsReader = requires( /// a vector. { r.to_map(obj) - } -> std::same_as< - std::vector>>; + } -> std::same_as< + std::vector>>; /// Casts var as an InputObjectType. { r.to_object(var) - } -> std::same_as>; + } -> std::same_as>; /// Iterates through an array and writes the contained vars into /// a vector. @@ -75,8 +76,8 @@ concept IsReader = requires( /// Uses the custom constructor, if it has been determined that T has one /// (see above). { - r.template use_custom_constructor>(var) - } -> std::same_as>>; + r.template use_custom_constructor>(var) + } -> std::same_as>>; }; } // namespace parsing diff --git a/include/rfl/parsing/Parser_c_array.hpp b/include/rfl/parsing/Parser_c_array.hpp index abda05e3..fe34fb97 100644 --- a/include/rfl/parsing/Parser_c_array.hpp +++ b/include/rfl/parsing/Parser_c_array.hpp @@ -3,9 +3,9 @@ #include -#include "../Array.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/Array.hpp" #include "../internal/to_std_array.hpp" #include "Parent.hpp" #include "Parser_array.hpp" @@ -27,9 +27,9 @@ struct Parser { using ParentType = Parent; using CArray = T[_size]; - static Result> read(const R& _r, - const InputVarType& _var) noexcept { - using StdArray = internal::to_std_array_t; + static Result> read( + const R& _r, const InputVarType& _var) noexcept { + using StdArray = internal::to_std_array_t; return Parser::read(_r, _var); } diff --git a/include/rfl/parsing/Parser_rfl_array.hpp b/include/rfl/parsing/Parser_rfl_array.hpp index e5fd4004..cfce4de0 100644 --- a/include/rfl/parsing/Parser_rfl_array.hpp +++ b/include/rfl/parsing/Parser_rfl_array.hpp @@ -3,9 +3,9 @@ #include -#include "../Array.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/Array.hpp" #include "../internal/to_std_array.hpp" #include "Parser_array.hpp" #include "Parser_base.hpp" @@ -14,8 +14,8 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> -struct Parser> { +requires AreReaderAndWriter> +struct Parser> { public: using InputArrayType = typename R::InputArrayType; using InputVarType = typename R::InputVarType; @@ -25,12 +25,13 @@ struct Parser> { using StdArray = internal::to_std_array_t; - static Result> read(const R& _r, const InputVarType& _var) noexcept { + static Result> read(const R& _r, + const InputVarType& _var) noexcept { return Parser::read(_r, _var); } template - static void write(const W& _w, const Array& _arr, + static void write(const W& _w, const internal::Array& _arr, const P& _parent) noexcept { Parser::write(_w, _arr.arr_, _parent); } diff --git a/include/rfl/xml/read.hpp b/include/rfl/xml/read.hpp index 0ef26ed4..e5a26968 100644 --- a/include/rfl/xml/read.hpp +++ b/include/rfl/xml/read.hpp @@ -7,7 +7,6 @@ #include "../internal/get_type_name.hpp" #include "../internal/remove_namespaces.hpp" -#include "../wrap_in_rfl_array_t.hpp" #include "Parser.hpp" #include "Reader.hpp" @@ -18,14 +17,14 @@ using InputVarType = typename Reader::InputVarType; /// Parses an object from a XML var. template -Result> read(const InputVarType& _var) { +auto read(const InputVarType& _var) { const auto r = Reader(); return Parser::read(r, _var); } /// Parses an object from XML using reflection. template -Result> read(const std::string& _xml_str) { +auto read(const std::string& _xml_str) { pugi::xml_document doc; const auto result = doc.load_string(_xml_str.c_str()); if (!result) { @@ -38,7 +37,7 @@ Result> read(const std::string& _xml_str) { /// Parses an object from a stringstream. template -Result> read(std::istream& _stream) { +auto read(std::istream& _stream) { const auto xml_str = std::string(std::istreambuf_iterator(_stream), std::istreambuf_iterator()); return read(xml_str); diff --git a/include/rfl/yaml/read.hpp b/include/rfl/yaml/read.hpp index c615460a..ba10de70 100644 --- a/include/rfl/yaml/read.hpp +++ b/include/rfl/yaml/read.hpp @@ -16,14 +16,14 @@ using InputVarType = typename Reader::InputVarType; /// Parses an object from a YAML var. template -Result read(const InputVarType& _var) { +auto read(const InputVarType& _var) { const auto r = Reader(); return Parser::read(r, _var); } /// Parses an object from YAML using reflection. template -Result read(const std::string& _yaml_str) { +auto read(const std::string& _yaml_str) { try { const auto var = InputVarType(YAML::Load(_yaml_str)); return read(var); @@ -34,7 +34,7 @@ Result read(const std::string& _yaml_str) { /// Parses an object from a stringstream. template -Result read(std::istream& _stream) { +auto read(std::istream& _stream) { const auto yaml_str = std::string(std::istreambuf_iterator(_stream), std::istreambuf_iterator()); return read(yaml_str); From b63c246f92463879073bf87ef4d30e9d1f6ebe7c Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Thu, 4 Jan 2024 21:49:25 +0100 Subject: [PATCH 16/17] Made sure that to_named_tuple (and, by extension, rfl::replace) works properly --- include/rfl/Field.hpp | 5 ++- include/rfl/from_named_tuple.hpp | 4 +- include/rfl/internal/Array.hpp | 3 ++ include/rfl/internal/move_from_tuple.hpp | 4 +- include/rfl/internal/move_to_field_tuple.hpp | 11 ++++- include/rfl/internal/to_std_array.hpp | 47 +++++++++++++++++--- tests/json/test_c_array_class5.cpp | 28 ++++++++++++ tests/json/test_c_array_class5.hpp | 5 +++ tests/json/tests.cpp | 11 +++-- 9 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 tests/json/test_c_array_class5.cpp create mode 100644 tests/json/test_c_array_class5.hpp diff --git a/include/rfl/Field.hpp b/include/rfl/Field.hpp index 5ebe4374..ae190b30 100644 --- a/include/rfl/Field.hpp +++ b/include/rfl/Field.hpp @@ -12,6 +12,7 @@ #include "internal/Array.hpp" #include "internal/StringLiteral.hpp" #include "internal/to_std_array.hpp" +#include "internal/wrap_in_rfl_array_t.hpp" namespace rfl { @@ -19,7 +20,7 @@ namespace rfl { template struct Field { /// The underlying type. - using Type = T; + using Type = internal::wrap_in_rfl_array_t; /// The name of the field. using Name = rfl::Literal<_name>; @@ -30,7 +31,7 @@ struct Field { Field(Field<_name, T>&& _field) noexcept = default; - Field(const Field<_name, Type>& _field) = default; + Field(const Field<_name, T>& _field) = default; template Field(const Field<_name, U>& _field) : value_(_field.get()) {} diff --git a/include/rfl/from_named_tuple.hpp b/include/rfl/from_named_tuple.hpp index 8a114e59..63a29838 100644 --- a/include/rfl/from_named_tuple.hpp +++ b/include/rfl/from_named_tuple.hpp @@ -14,7 +14,7 @@ namespace rfl { /// Generates the struct T from a named tuple. template -T from_named_tuple(NamedTupleType&& _n) { +auto from_named_tuple(NamedTupleType&& _n) { using RequiredType = std::remove_cvref_t>; if constexpr (!std::is_same, RequiredType>()) { @@ -36,7 +36,7 @@ T from_named_tuple(NamedTupleType&& _n) { /// Generates the struct T from a named tuple. template -T from_named_tuple(const NamedTupleType& _n) { +auto from_named_tuple(const NamedTupleType& _n) { using RequiredType = std::remove_cvref_t>; if constexpr (!std::is_same, RequiredType>()) { diff --git a/include/rfl/internal/Array.hpp b/include/rfl/internal/Array.hpp index 5341b578..9f75a35d 100644 --- a/include/rfl/internal/Array.hpp +++ b/include/rfl/internal/Array.hpp @@ -1,6 +1,7 @@ #ifndef RFL_INTERNAL_ARRAY_HPP_ #define RFL_INTERNAL_ARRAY_HPP_ +#include #include #include "to_std_array.hpp" @@ -17,6 +18,8 @@ struct Array { Array() = default; Array(const StdArrayType &_arr) : arr_(_arr) {} Array(StdArrayType &&_arr) : arr_(std::move(_arr)) {} + Array(const T &_arr) : arr_(to_std_array(_arr)) {} + Array(T &&_arr) : arr_(to_std_array(_arr)) {} ~Array() = default; diff --git a/include/rfl/internal/move_from_tuple.hpp b/include/rfl/internal/move_from_tuple.hpp index 3ddcd4e4..02b4d217 100644 --- a/include/rfl/internal/move_from_tuple.hpp +++ b/include/rfl/internal/move_from_tuple.hpp @@ -63,7 +63,7 @@ template auto move_from_pointers(Pointers& _ptrs, Args&&... _args) { constexpr auto i = sizeof...(Args); if constexpr (i == std::tuple_size_v>) { - return T{std::move(_args)...}; + return std::remove_cvref_t{std::move(_args)...}; } else { using FieldType = std::tuple_element_t>; @@ -116,7 +116,7 @@ auto flatten_c_arrays(const auto& _tup) { /// Creates a struct of type T from a tuple by moving the underlying /// fields. template -T move_from_tuple(TupleType&& _t) { +auto move_from_tuple(TupleType&& _t) { auto ptr_tuple = tup_to_ptr_tuple(_t); using TargetTupleType = tuple_t>; diff --git a/include/rfl/internal/move_to_field_tuple.hpp b/include/rfl/internal/move_to_field_tuple.hpp index 7841ae27..b7d10a40 100644 --- a/include/rfl/internal/move_to_field_tuple.hpp +++ b/include/rfl/internal/move_to_field_tuple.hpp @@ -5,6 +5,7 @@ #include #include "../field_names_t.hpp" +#include "Array.hpp" #include "bind_to_tuple.hpp" #include "has_fields.hpp" #include "is_named_tuple.hpp" @@ -22,7 +23,15 @@ auto move_to_field_tuple(OriginalStruct&& _t) { return bind_to_tuple(_t, [](auto& x) { return std::move(x); }); } else { using FieldNames = field_names_t; - auto tup = bind_to_tuple(_t, [](auto& x) { return std::move(x); }); + const auto fct = [](T& _v) { + using Type = std::remove_cvref_t; + if constexpr (std::is_array_v) { + return Array(_v); + } else { + return std::move(_v); + } + }; + auto tup = bind_to_tuple(_t, fct); return wrap_in_fields(std::move(tup)); } } diff --git a/include/rfl/internal/to_std_array.hpp b/include/rfl/internal/to_std_array.hpp index 715399b1..8703eb47 100644 --- a/include/rfl/internal/to_std_array.hpp +++ b/include/rfl/internal/to_std_array.hpp @@ -1,24 +1,57 @@ #ifndef RFL_INTERNAL_TO_STD_ARRAY_HPP_ #define RFL_INTERNAL_TO_STD_ARRAY_HPP_ -#include #include +#include +#include namespace rfl::internal { template -struct to_std_array { - using type = T; +struct StdArrayType { + using Type = T; }; -template -struct to_std_array { - using type = std::array>::type, _n>; +template +struct StdArrayType { + using Type = + std::array>::Type, _n>; + using ValueType = std::remove_cvref_t; + constexpr static size_t size = _n; }; template -using to_std_array_t = to_std_array::type; +using to_std_array_t = StdArrayType::Type; +template +auto to_std_array(T&& _t) { + using Type = std::remove_cvref_t; + if constexpr (std::is_array_v) { + constexpr size_t n = StdArrayType::size; + const auto fct = [&](std::index_sequence<_i...>) { + return to_std_array_t({to_std_array( + std::forward::ValueType>(_t[_i]))...}); + }; + return fct(std::make_index_sequence()); + } else { + return std::forward(_t); + } } +template +auto to_std_array(const T& _t) { + using Type = std::remove_cvref_t; + if constexpr (std::is_array_v) { + constexpr size_t n = StdArrayType::size; + const auto fct = [&](std::index_sequence<_i...>) { + return to_std_array_t({to_std_array(_t[_i])...}); + }; + return fct(std::make_index_sequence()); + } else { + return _t; + } +} + +} // namespace rfl::internal + #endif diff --git a/tests/json/test_c_array_class5.cpp b/tests/json/test_c_array_class5.cpp new file mode 100644 index 00000000..55fe7b29 --- /dev/null +++ b/tests/json/test_c_array_class5.cpp @@ -0,0 +1,28 @@ +#include "test_c_array_class5.hpp" + +#include +#include + +#include "rfl.hpp" +#include "rfl/json.hpp" +#include "write_and_read.hpp" + +namespace test_c_array_class5 { + +struct Test5 { + int a[3]; + int b[3]; + int c[2][2]; +}; + +void test() { + std::cout << std::source_location::current().function_name() << std::endl; + + Test5 t1 = {.a = {1, 2, 3}, .b = {4, 5, 6}, .c = {{7, 8}, {9, 10}}}; + + const auto t2 = rfl::replace(t1, rfl::make_field<"b", int[3]>({1, 2, 3})); + + write_and_read(t2, R"({"a":[1,2,3],"b":[1,2,3],"c":[[7,8],[9,10]]})"); +} + +} // namespace test_c_array_class5 diff --git a/tests/json/test_c_array_class5.hpp b/tests/json/test_c_array_class5.hpp new file mode 100644 index 00000000..4b87e475 --- /dev/null +++ b/tests/json/test_c_array_class5.hpp @@ -0,0 +1,5 @@ +namespace test_c_array_class5 { + +void test(); + +} diff --git a/tests/json/tests.cpp b/tests/json/tests.cpp index b3471bc0..93e1bd30 100644 --- a/tests/json/tests.cpp +++ b/tests/json/tests.cpp @@ -12,6 +12,7 @@ #include "test_c_array_class2.hpp" #include "test_c_array_class3.hpp" #include "test_c_array_class4.hpp" +#include "test_c_array_class5.hpp" #include "test_custom_class1.hpp" #include "test_custom_class2.hpp" #include "test_custom_class3.hpp" @@ -116,6 +117,12 @@ int main() { test_custom_class3::test(); test_custom_class4::test(); + test_c_array_class1::test(); + test_c_array_class2::test(); + test_c_array_class3::test(); + test_c_array_class4::test(); + test_c_array_class5::test(); + test_replace::test(); test_replace2::test(); test_replace_flatten::test(); @@ -139,9 +146,5 @@ int main() { test_meta_fields::test(); - test_c_array_class1::test(); - test_c_array_class2::test(); - test_c_array_class3::test(); - test_c_array_class4::test(); return 0; } From 5e9a660fa2901eaecd124a9203a34d1f86f3b626 Mon Sep 17 00:00:00 2001 From: Patrick Urbanke Date: Thu, 4 Jan 2024 22:19:52 +0100 Subject: [PATCH 17/17] Fixed return type --- include/rfl/json/read.hpp | 6 +++++- include/rfl/xml/read.hpp | 2 +- include/rfl/yaml/read.hpp | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/rfl/json/read.hpp b/include/rfl/json/read.hpp index c8b7d926..89877bbd 100644 --- a/include/rfl/json/read.hpp +++ b/include/rfl/json/read.hpp @@ -6,6 +6,7 @@ #include #include +#include "../internal/wrap_in_rfl_array_t.hpp" #include "Parser.hpp" #include "Reader.hpp" @@ -24,9 +25,12 @@ auto read(const InputVarType& _obj) { /// Parses an object from JSON using reflection. template -auto read(const std::string& _json_str) { +Result> read(const std::string& _json_str) { using PtrType = std::unique_ptr; yyjson_doc* doc = yyjson_read(_json_str.c_str(), _json_str.size(), 0); + if (!doc) { + return Error("Could not parse document!"); + } const auto ptr = PtrType(doc, yyjson_doc_free); return read(InputVarType(yyjson_doc_get_root(doc))); } diff --git a/include/rfl/xml/read.hpp b/include/rfl/xml/read.hpp index e5a26968..a13d45c2 100644 --- a/include/rfl/xml/read.hpp +++ b/include/rfl/xml/read.hpp @@ -24,7 +24,7 @@ auto read(const InputVarType& _var) { /// Parses an object from XML using reflection. template -auto read(const std::string& _xml_str) { +Result read(const std::string& _xml_str) { pugi::xml_document doc; const auto result = doc.load_string(_xml_str.c_str()); if (!result) { diff --git a/include/rfl/yaml/read.hpp b/include/rfl/yaml/read.hpp index ba10de70..e3b38ec8 100644 --- a/include/rfl/yaml/read.hpp +++ b/include/rfl/yaml/read.hpp @@ -6,6 +6,7 @@ #include #include +#include "../internal/wrap_in_rfl_array_t.hpp" #include "Parser.hpp" #include "Reader.hpp" @@ -23,7 +24,7 @@ auto read(const InputVarType& _var) { /// Parses an object from YAML using reflection. template -auto read(const std::string& _yaml_str) { +Result> read(const std::string& _yaml_str) { try { const auto var = InputVarType(YAML::Load(_yaml_str)); return read(var);