diff --git a/CMakeLists.txt b/CMakeLists.txt index 527425ba24..566088ed1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(${PROJECT_NAME} INTERFACE Boost::headers fmt::fmt) add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) # llama IDE target to make source browsable/editable in IDEs -file(GLOB_RECURSE llamaSources "${CMAKE_CURRENT_SOURCE_DIR}/include/**") +file(GLOB_RECURSE llamaSources "${CMAKE_CURRENT_SOURCE_DIR}/include/llama/**") add_custom_target("llamaIde" SOURCES ${llamaSources}) source_group(TREE "${CMAKE_CURRENT_LIST_DIR}/include/llama" FILES ${llamaSources}) diff --git a/examples/nbody/nbody.cpp b/examples/nbody/nbody.cpp index e4fb515e1f..c18b61bac2 100644 --- a/examples/nbody/nbody.cpp +++ b/examples/nbody/nbody.cpp @@ -34,45 +34,86 @@ constexpr auto L1D_SIZE = 32 * 1024; constexpr auto L2D_SIZE = 512 * 1024; using namespace std::string_literals; +using namespace llama::literals; namespace usellama { - // clang-format off - namespace tag + struct Vec { - struct Pos{}; - struct Vel{}; - struct X{}; - struct Y{}; - struct Z{}; - struct Mass{}; - } + FP x; + FP y; + FP z; + + auto operator*=(FP s) -> Vec& + { + x *= s; + y *= s; + z *= s; + return *this; + } + + auto operator*=(Vec v) -> Vec& + { + x *= v.x; + y *= v.y; + z *= v.z; + return *this; + } - using Particle = llama::DS< - llama::DE, - llama::DE, - llama::DE - >>, - llama::DE, - llama::DE, - llama::DE - >>, - llama::DE - >; - // clang-format on + auto operator+=(Vec v) -> Vec& + { + x += v.x; + y += v.y; + z += v.z; + return *this; + } + + auto operator-=(Vec v) -> Vec& + { + x -= v.x; + y -= v.y; + z -= v.z; + return *this; + } + + friend auto operator+(Vec a, Vec b) -> Vec + { + return a += b; + } + + friend auto operator-(Vec a, Vec b) -> Vec + { + return a -= b; + } + + friend auto operator*(Vec a, FP s) -> Vec + { + return a *= s; + } + + friend auto operator*(Vec a, Vec b) -> Vec + { + return a *= b; + } + }; + + struct Particle + { + Vec pos; + Vec vel; + FP mass; + }; template LLAMA_FN_HOST_ACC_INLINE void pPInteraction(VirtualParticleI&& pi, VirtualParticleJ pj) { - auto dist = pi(tag::Pos{}) - pj(tag::Pos{}); + auto dist = pi->pos - pj->pos; dist *= dist; - const FP distSqr = EPS2 + dist(tag::X{}) + dist(tag::Y{}) + dist(tag::Z{}); + const FP distSqr = EPS2 + dist.x + dist.y + dist.z; const FP distSixth = distSqr * distSqr * distSqr; const FP invDistCube = 1.0f / std::sqrt(distSixth); - const FP sts = pj(tag::Mass{}) * invDistCube * TIMESTEP; - pi(tag::Vel{}) += dist * sts; + const FP sts = pj->mass * invDistCube * TIMESTEP; + pi(1_DC) = pi->vel + dist * sts; } template @@ -102,7 +143,7 @@ namespace usellama { LLAMA_INDEPENDENT_DATA for (std::size_t i = 0; i < PROBLEM_SIZE; i++) - particles(i)(tag::Pos{}) += particles(i)(tag::Vel{}) * TIMESTEP; + particles(i)(0_DC) = particles(i)->pos + particles(i)->vel * TIMESTEP; } template @@ -162,14 +203,15 @@ namespace usellama std::normal_distribution dist(FP(0), FP(1)); for (std::size_t i = 0; i < PROBLEM_SIZE; ++i) { - auto p = particles(i); - p(tag::Pos{}, tag::X{}) = dist(engine); - p(tag::Pos{}, tag::Y{}) = dist(engine); - p(tag::Pos{}, tag::Z{}) = dist(engine); - p(tag::Vel{}, tag::X{}) = dist(engine) / FP(10); - p(tag::Vel{}, tag::Y{}) = dist(engine) / FP(10); - p(tag::Vel{}, tag::Z{}) = dist(engine) / FP(10); - p(tag::Mass{}) = dist(engine) / FP(100); + Particle p; + p.pos.x = dist(engine); + p.pos.y = dist(engine); + p.pos.z = dist(engine); + p.vel.x = dist(engine) / FP(10); + p.vel.y = dist(engine) / FP(10); + p.vel.z = dist(engine) / FP(10); + p.mass = dist(engine) / FP(100); + particles(i) = p; } watch.printAndReset("init"); diff --git a/include/boost/pfr.hpp b/include/boost/pfr.hpp new file mode 100644 index 0000000000..4c425cac54 --- /dev/null +++ b/include/boost/pfr.hpp @@ -0,0 +1,21 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PFR_HPP +#define BOOST_PFR_HPP + +/// \file boost/pfr.hpp +/// Includes all the Boost.PFR headers + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_PFR_HPP diff --git a/include/boost/pfr/core.hpp b/include/boost/pfr/core.hpp new file mode 100644 index 0000000000..7022733a3f --- /dev/null +++ b/include/boost/pfr/core.hpp @@ -0,0 +1,226 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PFR_CORE_HPP +#define BOOST_PFR_CORE_HPP +#pragma once + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include // metaprogramming stuff + +#include + +/// \file boost/pfr/core.hpp +/// Contains all the basic tuple-like interfaces \forcedlink{get}, \forcedlink{tuple_size}, \forcedlink{tuple_element_t}, and others. +/// +/// \b Synopsis: + +namespace boost { namespace pfr { + +/// \brief Returns reference or const reference to a field with index `I` in \aggregate `val`. +/// +/// \b Example: +/// \code +/// struct my_struct { int i, short s; }; +/// my_struct s {10, 11}; +/// assert(boost::pfr::get<0>(s) == 10); +/// boost::pfr::get<1>(s) = 0; +/// \endcode +template +constexpr decltype(auto) get(const T& val) noexcept { + return detail::sequence_tuple::get( detail::tie_as_tuple(val) ); +} + + +/// \overload get +template +constexpr decltype(auto) get(T& val +#if !BOOST_PFR_USE_CPP17 + , std::enable_if_t::value>* = nullptr +#endif +) noexcept { + return detail::sequence_tuple::get( detail::tie_as_tuple(val) ); +} + +#if !BOOST_PFR_USE_CPP17 +/// \overload get +template +constexpr auto get(T&, std::enable_if_t::value>* = nullptr) noexcept { + static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17"); + return 0; +} +#endif + + +/// \overload get +template +constexpr auto get(T&& val, std::enable_if_t< std::is_rvalue_reference::value>* = 0) noexcept { + return std::move(detail::sequence_tuple::get( detail::tie_as_tuple(val) )); +} + + +/// \brief `tuple_element` has a member typedef `type` that returns the type of a field with index I in \aggregate T. +/// +/// \b Example: +/// \code +/// std::vector< boost::pfr::tuple_element<0, my_structure>::type > v; +/// \endcode +template +using tuple_element = detail::sequence_tuple::tuple_element()) ) >; + + +/// \brief Type of a field with index `I` in \aggregate `T`. +/// +/// \b Example: +/// \code +/// std::vector< boost::pfr::tuple_element_t<0, my_structure> > v; +/// \endcode +template +using tuple_element_t = typename tuple_element::type; + + +/// \brief Creates a `std::tuple` from fields of an \aggregate `val`. +/// +/// \b Example: +/// \code +/// struct my_struct { int i, short s; }; +/// my_struct s {10, 11}; +/// std::tuple t = make_tuple(s); +/// assert(get<0>(t) == 10); +/// \endcode +template +constexpr auto structure_to_tuple(const T& val) noexcept { + return detail::make_stdtuple_from_tietuple( + detail::tie_as_tuple(val), + detail::make_index_sequence< tuple_size_v >() + ); +} + + +/// \brief std::tie` like function that ties fields of a structure. +/// +/// \returns a `std::tuple` with lvalue and const lvalue references to fields of an \aggregate `val`. +/// +/// \b Example: +/// \code +/// void foo(const int&, const short&); +/// struct my_struct { int i, short s; }; +/// +/// const my_struct const_s{1, 2}; +/// std::apply(foo, structure_tie(const_s)); +/// +/// my_struct s; +/// structure_tie(s) = std::tuple{10, 11}; +/// assert(s.s == 11); +/// \endcode +template +constexpr auto structure_tie(const T& val) noexcept { + return detail::make_conststdtiedtuple_from_tietuple( + detail::tie_as_tuple(const_cast(val)), + detail::make_index_sequence< tuple_size_v >() + ); +} + + +/// \overload structure_tie +template +constexpr auto structure_tie(T& val +#if !BOOST_PFR_USE_CPP17 + , std::enable_if_t::value>* = nullptr +#endif +) noexcept { + return detail::make_stdtiedtuple_from_tietuple( + detail::tie_as_tuple(val), + detail::make_index_sequence< tuple_size_v >() + ); +} + +#if !BOOST_PFR_USE_CPP17 +/// \overload structure_tie +template +constexpr auto structure_tie(T&, std::enable_if_t::value>* = nullptr) noexcept { + static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on non const non assignable type is allowed only in C++17"); + return 0; +} +#endif + + +/// \overload structure_tie +template +constexpr auto structure_tie(T&&, std::enable_if_t< std::is_rvalue_reference::value>* = 0) noexcept { + static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on rvalue references is forbidden"); + return 0; +} + +/// Calls `func` for each field of a `value`. +/// +/// \param func must have one of the following signatures: +/// * any_return_type func(U&& field) // field of value is perfect forwarded to function +/// * any_return_type func(U&& field, std::size_t i) +/// * any_return_type func(U&& value, I i) // Here I is an `std::integral_constant` +/// +/// \param value To each field of this variable will be the `func` applied. +/// +/// \b Example: +/// \code +/// struct my_struct { int i, short s; }; +/// int sum = 0; +/// for_each_field(my_struct{20, 22}, [&sum](const auto& field) { sum += field; }); +/// assert(sum == 42); +/// \endcode +template +void for_each_field(T&& value, F&& func) { + constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count>(); + + ::boost::pfr::detail::for_each_field_dispatcher( + value, + [f = std::forward(func)](auto&& t) mutable { + // MSVC related workaround. Its lambdas do not capture constexprs. + constexpr std::size_t fields_count_val_in_lambda + = boost::pfr::detail::fields_count>(); + + ::boost::pfr::detail::for_each_field_impl( + t, + std::forward(f), + detail::make_index_sequence{}, + std::is_rvalue_reference{} + ); + }, + detail::make_index_sequence{} + ); +} + +/// \brief std::tie-like function that allows assigning to tied values from aggregates. +/// +/// \returns an object with lvalue references to `args...`; on assignment of an \aggregate value to that +/// object each field of an aggregate is assigned to the corresponding `args...` reference. +/// +/// \b Example: +/// \code +/// auto f() { +/// struct { struct { int x, y } p; short s; } res { { 4, 5 }, 6 }; +/// return res; +/// } +/// auto [p, s] = f(); +/// tie_from_structure(p, s) = f(); +/// \endcode +template +constexpr detail::tie_from_structure_tuple tie_from_structure(Elements&... args) noexcept { + return detail::tie_from_structure_tuple(args...); +} + +}} // namespace boost::pfr + +#endif // BOOST_PFR_CORE_HPP diff --git a/include/boost/pfr/detail/cast_to_layout_compatible.hpp b/include/boost/pfr/detail/cast_to_layout_compatible.hpp new file mode 100644 index 0000000000..1267495335 --- /dev/null +++ b/include/boost/pfr/detail/cast_to_layout_compatible.hpp @@ -0,0 +1,75 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PFR_DETAIL_CAST_TO_LAYOUT_COMPATIBLE_HPP +#define BOOST_PFR_DETAIL_CAST_TO_LAYOUT_COMPATIBLE_HPP +#pragma once + +#include + +#include +#include // metaprogramming stuff +#include + +namespace boost { namespace pfr { namespace detail { + +template +constexpr void static_assert_layout_compatible() noexcept { + static_assert( + std::alignment_of::value == std::alignment_of::value, + "====================> Boost.PFR: Alignment check failed, probably your structure has user-defined alignment for the whole structure or for some of the fields." + ); + static_assert(sizeof(T) == sizeof(U), "====================> Boost.PFR: Size check failed, probably your structure has bitfields or user-defined alignment."); +} + +/// @cond +#ifdef __GNUC__ +#define MAY_ALIAS __attribute__((__may_alias__)) +#else +#define MAY_ALIAS +#endif +/// @endcond + +template +MAY_ALIAS const To& cast_to_layout_compatible(const From& val) noexcept { + MAY_ALIAS const To* const t = reinterpret_cast( std::addressof(val) ); + detail::static_assert_layout_compatible(); + return *t; +} + +template +MAY_ALIAS const volatile To& cast_to_layout_compatible(const volatile From& val) noexcept { + MAY_ALIAS const volatile To* const t = reinterpret_cast( std::addressof(val) ); + detail::static_assert_layout_compatible(); + return *t; +} + + +template +MAY_ALIAS volatile To& cast_to_layout_compatible(volatile From& val) noexcept { + MAY_ALIAS volatile To* const t = reinterpret_cast( std::addressof(val) ); + detail::static_assert_layout_compatible(); + return *t; +} + + +template +MAY_ALIAS To& cast_to_layout_compatible(From& val) noexcept { + MAY_ALIAS To* const t = reinterpret_cast( std::addressof(val) ); + detail::static_assert_layout_compatible(); + return *t; +} + +#ifdef BOOST_PFR_DETAIL_STRICT_RVALUE_TESTING +template +To&& cast_to_layout_compatible(rvalue_t val) noexcept = delete; +#endif + +#undef MAY_ALIAS + + +}}} // namespace boost::pfr::detail + +#endif // BOOST_PFR_DETAIL_CAST_TO_LAYOUT_COMPATIBLE_HPP diff --git a/include/boost/pfr/detail/config.hpp b/include/boost/pfr/detail/config.hpp new file mode 100644 index 0000000000..55f2bff4ce --- /dev/null +++ b/include/boost/pfr/detail/config.hpp @@ -0,0 +1,80 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PFR_DETAIL_CONFIG_HPP +#define BOOST_PFR_DETAIL_CONFIG_HPP +#pragma once + +#include // to get non standard platform macro definitions (__GLIBCXX__ for example) + +// Reminder: +// * MSVC++ 14.2 _MSC_VER == 1927 <- Loophole is known to work (Visual Studio ????) +// * MSVC++ 14.1 _MSC_VER == 1916 <- Loophole is known to NOT work (Visual Studio 2017) +// * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) +// * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) + +#if defined(_MSC_VER) +# if !defined(_MSVC_LANG) || _MSC_VER <= 1900 +# error Boost.PFR library requires more modern MSVC compiler. +# endif +#elif __cplusplus < 201402L +# error Boost.PFR library requires at least C++14. +#endif + +#ifndef BOOST_PFR_USE_LOOPHOLE +# if defined(_MSC_VER) +# if _MSC_VER >= 1927 +# define BOOST_PFR_USE_LOOPHOLE 1 +# else +# define BOOST_PFR_USE_LOOPHOLE 0 +# endif +# elif defined(__clang_major__) && __clang_major__ >= 8 +# define BOOST_PFR_USE_LOOPHOLE 0 +# else +# define BOOST_PFR_USE_LOOPHOLE 1 +# endif +#endif + +#ifndef BOOST_PFR_USE_CPP17 +# ifdef __cpp_structured_bindings +# define BOOST_PFR_USE_CPP17 1 +# elif defined(_MSVC_LANG) +# if _MSVC_LANG >= 201703L +# define BOOST_PFR_USE_CPP17 1 +# else +# define BOOST_PFR_USE_CPP17 0 +# if !BOOST_PFR_USE_LOOPHOLE +# error Boost.PFR requires /std:c++latest or /std:c++17 flags on your compiler. +# endif +# endif +# else +# define BOOST_PFR_USE_CPP17 0 +# endif +#endif + +#ifndef BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE +// Assume that libstdc++ since GCC-7.3 does not have linear instantiation depth in std::make_integral_sequence +# if defined( __GLIBCXX__) && __GLIBCXX__ >= 20180101 +# define BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE 1 +# elif defined(_MSC_VER) +# define BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE 1 +//# elif other known working lib +# else +# define BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE 0 +# endif +#endif + +#if defined(__has_cpp_attribute) +# if __has_cpp_attribute(maybe_unused) +# define BOOST_PFR_MAYBE_UNUSED [[maybe_unused]] +# endif +#endif + +#ifndef BOOST_PFR_MAYBE_UNUSED +# define BOOST_PFR_MAYBE_UNUSED +#endif + + +#endif // BOOST_PFR_DETAIL_CONFIG_HPP diff --git a/include/boost/pfr/detail/core.hpp b/include/boost/pfr/detail/core.hpp new file mode 100644 index 0000000000..6aabfb2deb --- /dev/null +++ b/include/boost/pfr/detail/core.hpp @@ -0,0 +1,24 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PFR_DETAIL_CORE_HPP +#define BOOST_PFR_DETAIL_CORE_HPP +#pragma once + +#include + +// Each core provides `boost::pfr::detail::tie_as_tuple` and +// `boost::pfr::detail::for_each_field_dispatcher` functions. +// +// The whole PFR library is build on top of those two functions. +#if BOOST_PFR_USE_CPP17 +# include +#elif BOOST_PFR_USE_LOOPHOLE +# include +#else +# include +#endif + +#endif // BOOST_PFR_DETAIL_CORE_HPP diff --git a/include/boost/pfr/detail/core14_classic.hpp b/include/boost/pfr/detail/core14_classic.hpp new file mode 100644 index 0000000000..9349118b20 --- /dev/null +++ b/include/boost/pfr/detail/core14_classic.hpp @@ -0,0 +1,703 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PFR_DETAIL_CORE14_CLASSIC_HPP +#define BOOST_PFR_DETAIL_CORE14_CLASSIC_HPP +#pragma once + +#include + +#include +#include // metaprogramming stuff + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmissing-braces" +# pragma clang diagnostic ignored "-Wundefined-inline" +# pragma clang diagnostic ignored "-Wundefined-internal" +# pragma clang diagnostic ignored "-Wmissing-field-initializers" +#endif + +namespace boost { namespace pfr { namespace detail { + +///////////////////// General utility stuff + +template struct identity { + typedef T type; +}; + +template +constexpr T construct_helper() noexcept { // adding const here allows to deal with copyable only types + return {}; +} + +template constexpr size_array fields_count_and_type_ids_with_zeros() noexcept; +template constexpr auto flat_array_of_type_ids() noexcept; + +///////////////////// All the stuff for representing Type as integer and converting integer back to type +namespace typeid_conversions { + +///////////////////// Helper constants and typedefs + +#ifdef _MSC_VER +# pragma warning( push ) + // '<<': check operator precedence for possible error; use parentheses to clarify precedence +# pragma warning( disable : 4554 ) +#endif + +constexpr std::size_t native_types_mask = 31; +constexpr std::size_t bits_per_extension = 3; +constexpr std::size_t extension_mask = ( + static_cast((1 << bits_per_extension) - 1) + << static_cast(sizeof(std::size_t) * 8 - bits_per_extension) +); +constexpr std::size_t native_ptr_type = ( + static_cast(1) + << static_cast(sizeof(std::size_t) * 8 - bits_per_extension) +); +constexpr std::size_t native_const_ptr_type = ( + static_cast(2) + << static_cast(sizeof(std::size_t) * 8 - bits_per_extension) +); + +constexpr std::size_t native_const_volatile_ptr_type = ( + static_cast(3) + << static_cast(sizeof(std::size_t) * 8 - bits_per_extension) +); + +constexpr std::size_t native_volatile_ptr_type = ( + static_cast(4) + << static_cast(sizeof(std::size_t) * 8 - bits_per_extension) +); + +constexpr std::size_t native_ref_type = ( + static_cast(5) + << static_cast(sizeof(std::size_t) * 8 - bits_per_extension) +); + +template +using if_extension = std::enable_if_t< (Index & extension_mask) == Extension >*; + +///////////////////// Helper functions +template +constexpr std::size_t type_to_id_extension_apply(std::size_t ext) noexcept { + constexpr std::size_t native_id = (Unptr & native_types_mask); + constexpr std::size_t extensions = (Unptr & ~native_types_mask); + static_assert( + !((extensions >> bits_per_extension) & native_types_mask), + "====================> Boost.PFR: Too many extensions for a single field (something close to `int************************** p;` is in the POD type)." + ); + + return (extensions >> bits_per_extension) | native_id | ext; +} + +template +using remove_1_ext = size_t_< + ((Index & ~native_types_mask) << bits_per_extension) | (Index & native_types_mask) +>; + +#ifdef _MSC_VER +# pragma warning( pop ) +#endif + +///////////////////// Forward declarations + +template constexpr std::size_t type_to_id(identity) noexcept; +template constexpr std::size_t type_to_id(identity) noexcept; +template constexpr std::size_t type_to_id(identity) noexcept; +template constexpr std::size_t type_to_id(identity) noexcept; +template constexpr std::size_t type_to_id(identity) noexcept; +template constexpr std::size_t type_to_id(identity, std::enable_if_t::value>* = 0) noexcept; +template constexpr std::size_t type_to_id(identity, std::enable_if_t::value>* = 0) noexcept; +template constexpr std::size_t type_to_id(identity, std::enable_if_t::value>* = 0) noexcept; +template constexpr size_array type_to_id(identity, std::enable_if_t::value && !std::is_empty::value && !std::is_union::value>* = 0) noexcept; + +template constexpr auto id_to_type(size_t_, if_extension = 0) noexcept; +template constexpr auto id_to_type(size_t_, if_extension = 0) noexcept; +template constexpr auto id_to_type(size_t_, if_extension = 0) noexcept; +template constexpr auto id_to_type(size_t_, if_extension = 0) noexcept; +template constexpr auto id_to_type(size_t_, if_extension = 0) noexcept; + + +///////////////////// Definitions of type_to_id and id_to_type for fundamental types +/// @cond +#define BOOST_MAGIC_GET_REGISTER_TYPE(Type, Index) \ + constexpr std::size_t type_to_id(identity) noexcept { \ + return Index; \ + } \ + constexpr Type id_to_type( size_t_ ) noexcept { \ + return detail::construct_helper(); \ + } \ + /**/ +/// @endcond + + +// Register all base types here +BOOST_MAGIC_GET_REGISTER_TYPE(unsigned char , 1) +BOOST_MAGIC_GET_REGISTER_TYPE(unsigned short , 2) +BOOST_MAGIC_GET_REGISTER_TYPE(unsigned int , 3) +BOOST_MAGIC_GET_REGISTER_TYPE(unsigned long , 4) +BOOST_MAGIC_GET_REGISTER_TYPE(unsigned long long , 5) +BOOST_MAGIC_GET_REGISTER_TYPE(signed char , 6) +BOOST_MAGIC_GET_REGISTER_TYPE(short , 7) +BOOST_MAGIC_GET_REGISTER_TYPE(int , 8) +BOOST_MAGIC_GET_REGISTER_TYPE(long , 9) +BOOST_MAGIC_GET_REGISTER_TYPE(long long , 10) +BOOST_MAGIC_GET_REGISTER_TYPE(char , 11) +BOOST_MAGIC_GET_REGISTER_TYPE(wchar_t , 12) +BOOST_MAGIC_GET_REGISTER_TYPE(char16_t , 13) +BOOST_MAGIC_GET_REGISTER_TYPE(char32_t , 14) +BOOST_MAGIC_GET_REGISTER_TYPE(float , 15) +BOOST_MAGIC_GET_REGISTER_TYPE(double , 16) +BOOST_MAGIC_GET_REGISTER_TYPE(long double , 17) +BOOST_MAGIC_GET_REGISTER_TYPE(bool , 18) +BOOST_MAGIC_GET_REGISTER_TYPE(void* , 19) +BOOST_MAGIC_GET_REGISTER_TYPE(const void* , 20) +BOOST_MAGIC_GET_REGISTER_TYPE(volatile void* , 21) +BOOST_MAGIC_GET_REGISTER_TYPE(const volatile void* , 22) +BOOST_MAGIC_GET_REGISTER_TYPE(std::nullptr_t , 23) +constexpr std::size_t tuple_begin_tag = 24; +constexpr std::size_t tuple_end_tag = 25; + +#undef BOOST_MAGIC_GET_REGISTER_TYPE + +///////////////////// Definitions of type_to_id and id_to_type for types with extensions and nested types +template +constexpr std::size_t type_to_id(identity) noexcept { + constexpr auto unptr = typeid_conversions::type_to_id(identity{}); + static_assert( + std::is_same::value, + "====================> Boost.PFR: Pointers to user defined types are not supported." + ); + return typeid_conversions::type_to_id_extension_apply(native_ptr_type); +} + +template +constexpr std::size_t type_to_id(identity) noexcept { + constexpr auto unptr = typeid_conversions::type_to_id(identity{}); + static_assert( + std::is_same::value, + "====================> Boost.PFR: Const pointers to user defined types are not supported." + ); + return typeid_conversions::type_to_id_extension_apply(native_const_ptr_type); +} + +template +constexpr std::size_t type_to_id(identity) noexcept { + constexpr auto unptr = typeid_conversions::type_to_id(identity{}); + static_assert( + std::is_same::value, + "====================> Boost.PFR: Const volatile pointers to user defined types are not supported." + ); + return typeid_conversions::type_to_id_extension_apply(native_const_volatile_ptr_type); +} + +template +constexpr std::size_t type_to_id(identity) noexcept { + constexpr auto unptr = typeid_conversions::type_to_id(identity{}); + static_assert( + std::is_same::value, + "====================> Boost.PFR: Volatile pointers to user defined types are not supported." + ); + return typeid_conversions::type_to_id_extension_apply(native_volatile_ptr_type); +} + +template +constexpr std::size_t type_to_id(identity) noexcept { + constexpr auto unptr = typeid_conversions::type_to_id(identity{}); + static_assert( + std::is_same::value, + "====================> Boost.PFR: References to user defined types are not supported." + ); + return typeid_conversions::type_to_id_extension_apply(native_ref_type); +} + +template +constexpr std::size_t type_to_id(identity, std::enable_if_t::value>*) noexcept { + return typeid_conversions::type_to_id(identity::type >{}); +} + +template +constexpr std::size_t type_to_id(identity, std::enable_if_t::value>*) noexcept { + static_assert(!std::is_empty::value, "====================> Boost.PFR: Empty classes/structures as members are not supported."); + return 0; +} + +template +constexpr std::size_t type_to_id(identity, std::enable_if_t::value>*) noexcept { + static_assert( + !std::is_union::value, + "====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info." + ); + return 0; +} + +template +constexpr size_array type_to_id(identity, std::enable_if_t::value && !std::is_empty::value && !std::is_union::value>*) noexcept { + constexpr auto t = detail::flat_array_of_type_ids(); + size_array result {{tuple_begin_tag}}; + constexpr bool requires_tuplening = ( + (t.count_nonzeros() != 1) || (t.count_nonzeros() == t.count_from_opening_till_matching_parenthis_seq(0, tuple_begin_tag, tuple_end_tag)) + ); + + if (requires_tuplening) { + for (std::size_t i = 0; i < t.size(); ++i) + result.data[i + 1] = t.data[i]; + result.data[result.size() - 1] = tuple_end_tag; + } else { + for (std::size_t i = 0; i < t.size(); ++i) + result.data[i] = t.data[i]; + } + return result; +} + + + +template +constexpr auto id_to_type(size_t_, if_extension) noexcept { + typedef decltype( typeid_conversions::id_to_type(remove_1_ext()) )* res_t; + return detail::construct_helper(); +} + +template +constexpr auto id_to_type(size_t_, if_extension) noexcept { + typedef const decltype( typeid_conversions::id_to_type(remove_1_ext()) )* res_t; + return detail::construct_helper(); +} + +template +constexpr auto id_to_type(size_t_, if_extension) noexcept { + typedef const volatile decltype( typeid_conversions::id_to_type(remove_1_ext()) )* res_t; + return detail::construct_helper(); +} + + +template +constexpr auto id_to_type(size_t_, if_extension) noexcept { + typedef volatile decltype( typeid_conversions::id_to_type(remove_1_ext()) )* res_t; + return detail::construct_helper(); +} + + +template +constexpr auto id_to_type(size_t_, if_extension) noexcept { + static_assert(!Index, "====================> Boost.PFR: References are not supported"); + return nullptr; +} + +} // namespace typeid_conversions + +///////////////////// Structure that remembers types as integers on a `constexpr operator Type()` call +struct ubiq_val { + std::size_t* ref_; + + template + constexpr void assign(const T& typeids) const noexcept { + for (std::size_t i = 0; i < T::size(); ++i) + ref_[i] = typeids.data[i]; + } + + constexpr void assign(std::size_t val) const noexcept { + ref_[0] = val; + } + + template + constexpr operator Type() const noexcept { + constexpr auto typeids = typeid_conversions::type_to_id(identity{}); + assign(typeids); + return detail::construct_helper(); + } +}; + +///////////////////// Structure that remembers size of the type on a `constexpr operator Type()` call +struct ubiq_sizes { + std::size_t& ref_; + + template + constexpr operator Type() const noexcept { + ref_ = sizeof(Type); + return detail::construct_helper(); + } +}; + +///////////////////// Returns array of (offsets without accounting alignments). Required for keeping places for nested type ids +template +constexpr size_array get_type_offsets() noexcept { + typedef size_array array_t; + array_t sizes{}; + T tmp{ ubiq_sizes{sizes.data[I]}... }; + (void)tmp; + + array_t offsets{{0}}; + for (std::size_t i = 1; i < N; ++i) + offsets.data[i] = offsets.data[i - 1] + sizes.data[i - 1]; + + return offsets; +} + +///////////////////// Returns array of typeids and zeros if construtor of a type accepts sizeof...(I) parameters +template +constexpr void* flat_type_to_array_of_type_ids(std::size_t* types, std::index_sequence) noexcept +{ + static_assert( + N <= sizeof(T), + "====================> Boost.PFR: Bit fields are not supported." + ); + + constexpr auto offsets = detail::get_type_offsets(); + T tmp{ ubiq_val{types + get(offsets) * 3}... }; + (void)types; + (void)tmp; + (void)offsets; // If type is empty offsets are not used + return nullptr; +} + +///////////////////// Returns array of typeids and zeros +template +constexpr size_array fields_count_and_type_ids_with_zeros() noexcept { + size_array types{}; + constexpr std::size_t N = detail::fields_count(); + detail::flat_type_to_array_of_type_ids(types.data, detail::make_index_sequence()); + return types; +} + +///////////////////// Returns array of typeids without zeros +template +constexpr auto flat_array_of_type_ids() noexcept { + constexpr auto types = detail::fields_count_and_type_ids_with_zeros(); + constexpr std::size_t count = types.count_nonzeros(); + size_array res{}; + std::size_t j = 0; + for (std::size_t i = 0; i < decltype(types)::size(); ++i) { + if (types.data[i]) { + res.data[j] = types.data[i]; + ++ j; + } + } + + return res; +} + +///////////////////// Convert array of typeids into sequence_tuple::tuple + +template +constexpr auto as_flat_tuple_impl(std::index_sequence) noexcept; + +template +constexpr sequence_tuple::tuple<> as_flat_tuple_impl(std::index_sequence<>) noexcept { + return sequence_tuple::tuple<>{}; +} + +template +constexpr auto increment_index_sequence(std::index_sequence) noexcept { + return std::index_sequence{}; +} + +template +constexpr auto prepare_subtuples(size_t_, size_t_, size_t_) noexcept { + static_assert(SubtupleLength == 0, "====================> Boost.PFR: Internal error while representing nested field as tuple"); + return typeid_conversions::id_to_type(size_t_{}); +} + +template +constexpr auto prepare_subtuples(size_t_, size_t_, size_t_) noexcept { + static_assert(sizeof(T) == 0, "====================> Boost.PFR: Internal error while representing nested field as tuple"); + return int{}; +} + +template +constexpr auto prepare_subtuples(size_t_, size_t_, size_t_) noexcept { + static_assert(SubtupleLength > 2, "====================> Boost.PFR: Internal error while representing nested field as tuple"); + constexpr auto seq = detail::make_index_sequence{}; + return detail::as_flat_tuple_impl( detail::increment_index_sequence(seq) ); +} + + +template +constexpr Array remove_subtuples(Array indexes_plus_1, const Array& subtuple_lengths) noexcept { + for (std::size_t i = 0; i < subtuple_lengths.size(); ++i) { + if (subtuple_lengths.data[i]) { + const std::size_t skips_count = subtuple_lengths.data[i]; + for (std::size_t j = i + 1; j < skips_count + i; ++j) { + indexes_plus_1.data[j] = 0; + } + i += skips_count - 1; + } + } + return indexes_plus_1; +} + +template +constexpr size_array resize_dropping_zeros_and_decrementing(size_t_, const Array& a) noexcept { + size_array result{}; + std::size_t result_indx = 0; + for (std::size_t i = 0; i < a.size(); ++i) { + if (a.data[i]) { + result.data[result_indx] = static_cast(a.data[i] - 1); + ++ result_indx; + } + } + + return result; +} + +template +constexpr auto as_flat_tuple_impl_drop_helpers(std::index_sequence, std::index_sequence) noexcept { + constexpr auto a = detail::flat_array_of_type_ids(); + + constexpr size_array subtuples_length {{ + a.count_from_opening_till_matching_parenthis_seq(First, typeid_conversions::tuple_begin_tag, typeid_conversions::tuple_end_tag), + a.count_from_opening_till_matching_parenthis_seq(I, typeid_conversions::tuple_begin_tag, typeid_conversions::tuple_end_tag)... + }}; + + constexpr size_array type_indexes_with_subtuple_internals {{ 1, 1 + I - First...}}; + constexpr auto type_indexes_plus_1_and_zeros_as_skips = detail::remove_subtuples(type_indexes_with_subtuple_internals, subtuples_length); + constexpr auto new_size = size_t_{}; + constexpr auto type_indexes = detail::resize_dropping_zeros_and_decrementing(new_size, type_indexes_plus_1_and_zeros_as_skips); + + typedef sequence_tuple::tuple< + decltype(detail::prepare_subtuples( + size_t_< a.data[ First + type_indexes.data[INew] ] >{}, // id of type + size_t_< First + type_indexes.data[INew] >{}, // index of current id in `a` + size_t_< subtuples_length.data[ type_indexes.data[INew] ] >{} // if id of type is tuple, then length of that tuple + ))... + > subtuples_uncleanuped_t; + + return subtuples_uncleanuped_t{}; +} + +template +constexpr std::size_t count_skips_in_array(std::size_t begin_index, std::size_t end_index, const Array& a) noexcept { + std::size_t skips = 0; + for (std::size_t i = begin_index; i < end_index; ++i) { + if (a.data[i] == typeid_conversions::tuple_begin_tag) { + const std::size_t this_tuple_size = a.count_from_opening_till_matching_parenthis_seq(i, typeid_conversions::tuple_begin_tag, typeid_conversions::tuple_end_tag) - 1; + skips += this_tuple_size; + i += this_tuple_size - 1; + } + } + + return skips; +} + +template +constexpr auto as_flat_tuple_impl(std::index_sequence) noexcept { + constexpr auto a = detail::flat_array_of_type_ids(); + constexpr std::size_t count_of_I = sizeof...(I); + + return detail::as_flat_tuple_impl_drop_helpers( + std::index_sequence{}, + detail::make_index_sequence< 1 + count_of_I - count_skips_in_array(First, First + count_of_I, a) >{} + ); +} + +template +constexpr auto internal_tuple_with_same_alignment() noexcept { + typedef typename std::remove_cv::type type; + + static_assert( + std::is_trivial::value && std::is_standard_layout::value, + "====================> Boost.PFR: Type can not be reflected without Loophole or C++17, because it's not POD" + ); + static_assert(!std::is_reference::value, "====================> Boost.PFR: Not applyable"); + constexpr auto res = detail::as_flat_tuple_impl( + detail::make_index_sequence< decltype(detail::flat_array_of_type_ids())::size() >() + ); + + return res; +} + +template +using internal_tuple_with_same_alignment_t = decltype( detail::internal_tuple_with_same_alignment() ); + + +///////////////////// Flattening +struct ubiq_is_flat_refelectable { + bool& is_flat_refelectable; + + template + constexpr operator Type() const noexcept { + is_flat_refelectable = std::is_fundamental>::value; + return {}; + } +}; + +template +constexpr bool is_flat_refelectable(std::index_sequence) noexcept { + constexpr std::size_t fields = sizeof...(I); + bool result[fields] = {static_cast(I)...}; + const T v{ ubiq_is_flat_refelectable{result[I]}... }; + (void)v; + + for (std::size_t i = 0; i < fields; ++i) { + if (!result[i]) { + return false; + } + } + + return true; +} + +template +auto tie_as_flat_tuple(T& lvalue) noexcept { + static_assert( + !std::is_union::value, + "====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info." + ); + using type = std::remove_cv_t; + using tuple_type = internal_tuple_with_same_alignment_t; + + offset_based_getter getter; + return boost::pfr::detail::make_flat_tuple_of_references(lvalue, getter, size_t_<0>{}, size_t_{}); +} + +template +auto tie_as_tuple(T& val) noexcept { + static_assert( + !std::is_union::value, + "====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info." + ); + static_assert( + boost::pfr::detail::is_flat_refelectable( detail::make_index_sequence()>{} ), + "====================> Boost.PFR: Not possible in C++14 to represent that type without loosing information. Change type definition or enable C++17" + ); + return boost::pfr::detail::tie_as_flat_tuple(val); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +///////////////////// Structure that can be converted to copy of anything +struct ubiq_constructor_constexpr_copy { + std::size_t ignore; + + template + constexpr operator Type() const noexcept { + static_assert( + std::is_trivially_destructible::value, + "====================> Boost.PFR: One of the fields in the type passed to `for_each_field` has non trivial destructor." + ); + return {}; + } +}; + +///////////////////// + +template +struct is_constexpr_aggregate_initializable { // TODO: try to fix it + template + static std::true_type test(long) noexcept; + + static std::false_type test(...) noexcept; + + static constexpr decltype( test(0) ) value{}; +}; + + +template +void for_each_field_in_depth(T& t, F&& f, std::index_sequence, identity...); + +template +void for_each_field_in_depth(T& t, F&& f, std::index_sequence<>, identity...); + +template +struct next_step { + T& t; + F& f; + + template + operator Field() const { + boost::pfr::detail::for_each_field_in_depth( + t, + std::forward(f), + IndexSeq{}, + identity{}..., + identity{} + ); + + return {}; + } +}; + +template +void for_each_field_in_depth(T& t, F&& f, std::index_sequence, identity...) { + (void)std::add_const_t>{ + Fields{}..., + next_step, Fields...>{t, f}, + ubiq_constructor_constexpr_copy{I}... + }; +} + +template +void for_each_field_in_depth(T& lvalue, F&& f, std::index_sequence<>, identity...) { + using tuple_type = sequence_tuple::tuple; + + offset_based_getter>, tuple_type> getter; + std::forward(f)( + boost::pfr::detail::make_flat_tuple_of_references(lvalue, getter, size_t_<0>{}, size_t_{}) + ); +} + +template +void for_each_field_dispatcher_1(T& t, F&& f, std::index_sequence, std::true_type /*is_flat_refelectable*/) { + std::forward(f)( + boost::pfr::detail::tie_as_flat_tuple(t) + ); +} + + +template +void for_each_field_dispatcher_1(T& t, F&& f, std::index_sequence, std::false_type /*is_flat_refelectable*/) { + boost::pfr::detail::for_each_field_in_depth( + t, + std::forward(f), + std::index_sequence{} + ); +} + +template +void for_each_field_dispatcher(T& t, F&& f, std::index_sequence) { + static_assert( + !std::is_union::value, + "====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info." + ); + + /// Compile time error at this point means that you have called `for_each_field` or some other non-flat function or operator for a + /// type that is not constexpr aggregate initializable. + /// + /// Make sure that all the fields of your type have constexpr default construtors and trivial destructors. + /// Or compile in C++17 mode. + constexpr T tmp{ ubiq_constructor_constexpr_copy{I}... }; + (void)tmp; + + //static_assert(is_constexpr_aggregate_initializable::value, "====================> Boost.PFR: T must be a constexpr initializable type"); + + constexpr bool is_flat_refelectable_val = detail::is_flat_refelectable( std::index_sequence{} ); + detail::for_each_field_dispatcher_1( + t, + std::forward(f), + std::index_sequence{}, + std::integral_constant{} + ); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +}}} // namespace boost::pfr::detail + +#endif // BOOST_PFR_DETAIL_CORE14_CLASSIC_HPP diff --git a/include/boost/pfr/detail/core14_loophole.hpp b/include/boost/pfr/detail/core14_loophole.hpp new file mode 100644 index 0000000000..7920c7b1a2 --- /dev/null +++ b/include/boost/pfr/detail/core14_loophole.hpp @@ -0,0 +1,200 @@ +// Copyright (c) 2017-2018 Alexandr Poltavsky, Antony Polukhin. +// Copyright (c) 2019-2020 Antony Polukhin. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// The Great Type Loophole (C++14) +// Initial implementation by Alexandr Poltavsky, http://alexpolt.github.io +// +// Description: +// The Great Type Loophole is a technique that allows to exchange type information with template +// instantiations. Basically you can assign and read type information during compile time. +// Here it is used to detect data members of a data type. I described it for the first time in +// this blog post http://alexpolt.github.io/type-loophole.html . +// +// This technique exploits the http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118 +// CWG 2118. Stateful metaprogramming via friend injection +// Note: CWG agreed that such techniques should be ill-formed, although the mechanism for prohibiting them is as yet undetermined. + +#ifndef BOOST_PFR_DETAIL_CORE14_LOOPHOLE_HPP +#define BOOST_PFR_DETAIL_CORE14_LOOPHOLE_HPP + +#include + +#include +#include + +#include // still needed for enums +#include +#include +#include +#include +#include +#include +#include + + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmissing-braces" +# pragma clang diagnostic ignored "-Wundefined-inline" +# pragma clang diagnostic ignored "-Wundefined-internal" +# pragma clang diagnostic ignored "-Wmissing-field-initializers" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wnon-template-friend" +#endif + + +namespace boost { namespace pfr { namespace detail { + +// tag generates friend declarations and helps with overload resolution. +// There are two types: one with the auto return type, which is the way we read types later. +// The second one is used in the detection of instantiations without which we'd get multiple +// definitions. + +template +struct tag { + friend auto loophole(tag); +}; + +// The definitions of friend functions. +template +struct fn_def_lref { + friend auto loophole(tag) { + // Standard Library containers do not SFINAE on invalid copy constructor. Because of that std::vector> reports that it is copyable, + // which leads to an instantiation error at this place. + // + // To workaround the issue, we check that the type U is movable, and move it in that case. + using no_extents_t = std::remove_all_extents_t; + return static_cast< std::conditional_t::value, no_extents_t&&, no_extents_t&> >( + boost::pfr::detail::unsafe_declval() + ); + } +}; +template +struct fn_def_rref { + friend auto loophole(tag) { return std::move(boost::pfr::detail::unsafe_declval< std::remove_all_extents_t& >()); } +}; + + +// Those specializations are to avoid multiple definition errors. +template +struct fn_def_lref {}; + +template +struct fn_def_rref {}; + + +// This has a templated conversion operator which in turn triggers instantiations. +// Important point, using sizeof seems to be more reliable. Also default template +// arguments are "cached" (I think). To fix that I provide a U template parameter to +// the ins functions which do the detection using constexpr friend functions and SFINAE. +template +struct loophole_ubiq_lref { + template static std::size_t ins(...); + template{})) > static char ins(int); + + template(0)) == sizeof(char)>)> + constexpr operator U&() const&& noexcept; // `const&&` here helps to avoid ambiguity in loophole instantiations. optional_like test validate that behavior. +}; + +template +struct loophole_ubiq_rref { + template static std::size_t ins(...); + template{})) > static char ins(int); + + template(0)) == sizeof(char)>)> + constexpr operator U&&() const&& noexcept; // `const&&` here helps to avoid ambiguity in loophole instantiations. optional_like test validate that behavior. +}; + + +// This is a helper to turn a data structure into a tuple. +template +struct loophole_type_list_lref; + +template +struct loophole_type_list_lref< T, std::index_sequence > + // Instantiating loopholes: + : sequence_tuple::tuple< decltype(T{ loophole_ubiq_lref{}... }, 0) > +{ + using type = sequence_tuple::tuple< decltype(loophole(tag{}))... >; +}; + + +template +struct loophole_type_list_rref; + +template +struct loophole_type_list_rref< T, std::index_sequence > + // Instantiating loopholes: + : sequence_tuple::tuple< decltype(T{ loophole_ubiq_rref{}... }, 0) > +{ + using type = sequence_tuple::tuple< decltype(loophole(tag{}))... >; +}; + + +// Lazily returns loophole_type_list_{lr}ref. +template +struct loophole_type_list_selector { + using type = loophole_type_list_lref; +}; + +template +struct loophole_type_list_selector { + using type = loophole_type_list_rref; +}; + +template +auto tie_as_tuple_loophole_impl(T& lvalue) noexcept { + using type = std::remove_cv_t>; + using indexes = detail::make_index_sequence()>; + using loophole_type_list = typename detail::loophole_type_list_selector< + std::is_copy_constructible>::value, type, indexes + >::type; + using tuple_type = typename loophole_type_list::type; + + return boost::pfr::detail::make_flat_tuple_of_references( + lvalue, + offset_based_getter{}, + size_t_<0>{}, + size_t_{} + ); +} + +template +auto tie_as_tuple(T& val) noexcept { + static_assert( + !std::is_union::value, + "====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info." + ); + return boost::pfr::detail::tie_as_tuple_loophole_impl( + val + ); +} + +template +void for_each_field_dispatcher(T& t, F&& f, std::index_sequence) { + static_assert( + !std::is_union::value, + "====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info." + ); + std::forward(f)( + boost::pfr::detail::tie_as_tuple_loophole_impl(t) + ); +} + +}}} // namespace boost::pfr::detail + + +#ifdef __clang__ +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + + +#endif // BOOST_PFR_DETAIL_CORE14_LOOPHOLE_HPP + diff --git a/include/boost/pfr/detail/core17.hpp b/include/boost/pfr/detail/core17.hpp new file mode 100644 index 0000000000..16a2c15c07 --- /dev/null +++ b/include/boost/pfr/detail/core17.hpp @@ -0,0 +1,71 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef BOOST_PFR_DETAIL_CORE17_HPP +#define BOOST_PFR_DETAIL_CORE17_HPP + +#include +#include +#include +#include + +namespace boost { namespace pfr { namespace detail { + +#ifndef _MSC_VER // MSVC fails to compile the following code, but compiles the structured bindings in core17_generated.hpp +struct do_not_define_std_tuple_size_for_me { + bool test1 = true; +}; + +template +constexpr bool do_structured_bindings_work() noexcept { // ******************************************* IN CASE OF ERROR READ THE FOLLOWING LINES IN boost/pfr/detail/core17.hpp FILE: + T val{}; + const auto& [a] = val; // ******************************************* IN CASE OF ERROR READ THE FOLLOWING LINES IN boost/pfr/detail/core17.hpp FILE: + + /**************************************************************************** + * + * It looks like your compiler or Standard Library can not handle C++17 + * structured bindings. + * + * Workaround: Define BOOST_PFR_USE_CPP17 to 0 + * It will disable the C++17 features for Boost.PFR library. + * + * Sorry for the inconvenience caused. + * + ****************************************************************************/ + + return a; +} + +static_assert( + do_structured_bindings_work(), + "====================> Boost.PFR: Your compiler can not handle C++17 structured bindings. Read the above comments for workarounds." +); +#endif // #ifndef _MSC_VER + +template +constexpr auto tie_as_tuple(T& val) noexcept { + static_assert( + !std::is_union::value, + "====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info." + ); + typedef size_t_()> fields_count_tag; + return boost::pfr::detail::tie_as_tuple(val, fields_count_tag{}); +} + +template +void for_each_field_dispatcher(T& t, F&& f, std::index_sequence) { + static_assert( + !std::is_union::value, + "====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info." + ); + std::forward(f)( + detail::tie_as_tuple(t) + ); +} + +}}} // namespace boost::pfr::detail + +#endif // BOOST_PFR_DETAIL_CORE17_HPP diff --git a/include/boost/pfr/detail/core17_generated.hpp b/include/boost/pfr/detail/core17_generated.hpp new file mode 100644 index 0000000000..b4e26fcc41 --- /dev/null +++ b/include/boost/pfr/detail/core17_generated.hpp @@ -0,0 +1,1036 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////// THIS HEADER IS AUTO GENERATED BY misc/generate_cpp17.py //////////////// +//////////////// MODIFY AND RUN THE misc/generate_cpp17.py INSTEAD OF DIRECTLY MODIFYING THE GENERATED FILE //////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_PFR_DETAIL_CORE17_GENERATED_HPP +#define BOOST_PFR_DETAIL_CORE17_GENERATED_HPP +#pragma once + +#include +#if !BOOST_PFR_USE_CPP17 +# error C++17 is required for this header. +#endif + +#include +#include + +namespace boost { namespace pfr { namespace detail { + +template +constexpr auto make_tuple_of_references(Args&&... args) noexcept { + return sequence_tuple::tuple{ args... }; +} + +template +constexpr auto tie_as_tuple(T& /*val*/, size_t_<0>) noexcept { + return sequence_tuple::tuple<>{}; +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<1>, std::enable_if_t >::value>* = 0) noexcept { + auto& [a] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a); +} + + +template +constexpr auto tie_as_tuple(T& val, size_t_<1>, std::enable_if_t >::value>* = 0) noexcept { + return ::boost::pfr::detail::make_tuple_of_references( val ); +} + + +template +constexpr auto tie_as_tuple(T& val, size_t_<2>) noexcept { + auto& [a,b] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<3>) noexcept { + auto& [a,b,c] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<4>) noexcept { + auto& [a,b,c,d] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<5>) noexcept { + auto& [a,b,c,d,e] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<6>) noexcept { + auto& [a,b,c,d,e,f] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<7>) noexcept { + auto& [a,b,c,d,e,f,g] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<8>) noexcept { + auto& [a,b,c,d,e,f,g,h] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<9>) noexcept { + auto& [a,b,c,d,e,f,g,h,j] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<10>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<11>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<12>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<13>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<14>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<15>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<16>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<17>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<18>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<19>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<20>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<21>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<22>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<23>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<24>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<25>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<26>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<27>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<28>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<29>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<30>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<31>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<32>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<33>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<34>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<35>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<36>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<37>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<38>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<39>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<40>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<41>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<42>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<43>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<44>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<45>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<46>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<47>) noexcept { + auto& [a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + return ::boost::pfr::detail::make_tuple_of_references(a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<48>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<49>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<50>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<51>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<52>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<53>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<54>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<55>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<56>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<57>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<58>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<59>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<60>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<61>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<62>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<63>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<64>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<65>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<66>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<67>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<68>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<69>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<70>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<71>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<72>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<73>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<74>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<75>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<76>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<77>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<78>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<79>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<80>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<81>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<82>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<83>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<84>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<85>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<86>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<87>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<88>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<89>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<90>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<91>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<92>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<93>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<94>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<95>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<96>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<97>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb,bc + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb,bc + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<98>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb,bc,bd + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb,bc,bd + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<99>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb,bc,bd,be + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb,bc,bd,be + ); +} + +template +constexpr auto tie_as_tuple(T& val, size_t_<100>) noexcept { + auto& [ + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb,bc,bd,be,bf + ] = val; // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. + + return ::boost::pfr::detail::make_tuple_of_references( + a,b,c,d,e,f,g,h,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,U,V,W,X,Y,Z, + aa,ab,ac,ad,ae,af,ag,ah,aj,ak,al,am,an,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aJ,aK,aL,aM,aN,aP,aQ,aR,aS,aU,aV,aW,aX,aY,aZ, + ba,bb,bc,bd,be,bf + ); +} + + +template +constexpr void tie_as_tuple(T& /*val*/, size_t_) noexcept { + static_assert(sizeof(T) && false, + "====================> Boost.PFR: Too many fields in a structure T. Regenerate include/boost/pfr/detail/core17_generated.hpp file for appropriate count of fields. For example: `python ./misc/generate_cpp17.py 300 > include/boost/pfr/detail/core17_generated.hpp`"); +} + +}}} // namespace boost::pfr::detail + +#endif // BOOST_PFR_DETAIL_CORE17_GENERATED_HPP + diff --git a/include/boost/pfr/detail/detectors.hpp b/include/boost/pfr/detail/detectors.hpp new file mode 100644 index 0000000000..2ee04e34a5 --- /dev/null +++ b/include/boost/pfr/detail/detectors.hpp @@ -0,0 +1,70 @@ +// Copyright (c) 2016-2020 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PFR_DETAIL_DETECTORS_HPP +#define BOOST_PFR_DETAIL_DETECTORS_HPP +#pragma once + +#include + +#include +#include + +namespace boost { namespace pfr { namespace detail { +///////////////////// `value` is true if Detector does not compile (SFINAE) + struct can_not_apply{}; + + template