From bdd7002726c43c2cb3ea229509a9c259aa75be01 Mon Sep 17 00:00:00 2001 From: glensand Date: Sun, 21 Jan 2024 10:37:37 -0800 Subject: [PATCH] moved from hope, small refactoring --- CMakeLists.txt | 11 + lib/CMakeLists.txt | 20 + lib/hope_core/fsm/fsm.h | 67 ++ .../switch_expression/switch_expression.h | 102 ++ .../tuple/compute_field_count_recursive.h | 71 ++ lib/hope_core/tuple/detect_fields_count.h | 90 ++ lib/hope_core/tuple/flat_sorted_tuple.h | 46 + lib/hope_core/tuple/flat_tuple.h | 345 +++++++ lib/hope_core/tuple/generated.h | 919 ++++++++++++++++++ lib/hope_core/tuple/legacy/tuple.h | 115 +++ lib/hope_core/tuple/print_tuple.h | 51 + lib/hope_core/tuple/tuple_from_struct.h | 37 + .../tuple/tuple_from_struct_unsafe.h | 68 ++ lib/hope_core/tuple/tuple_policy.h | 36 + lib/hope_core/tuple/tuple_utils.h | 131 +++ lib/hope_core/type_traits/any_convertible.h | 60 ++ lib/hope_core/type_traits/detector.h | 53 + lib/hope_core/type_traits/integraltypes.h | 27 + lib/hope_core/type_traits/is_invokable.h | 45 + lib/hope_core/type_traits/loophole.h | 52 + lib/hope_core/type_traits/type_list.h | 190 ++++ lib/hope_core/type_traits/type_list_detail.h | 52 + lib/hope_core/type_traits/type_value_map.h | 95 ++ lib/hope_core/type_traits/typelistsort.h | 69 ++ lib/hope_core/type_traits/typemap.h | 57 ++ .../type_traits/user_defined_types.h | 54 + lib/hope_core/type_traits/utility.h | 93 ++ test/CMakeLists.txt | 46 + test/CMakeLists.txt.in | 15 + test/Tests.cpp | 15 + test/tests/any_convertible_test.cpp | 51 + test/tests/detector_test.cpp | 21 + test/tests/fieldescounttest.cpp | 60 ++ test/tests/ref_tuple_from_struct_test.cpp | 49 + test/tests/switch_expression_test.cpp | 21 + test/tests/tupletest.cpp | 250 +++++ test/tests/typelisttests.cpp | 30 + test/tests/typemap_test.cpp | 60 ++ test/tests/utility_test.cpp | 62 ++ 39 files changed, 3636 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 lib/CMakeLists.txt create mode 100644 lib/hope_core/fsm/fsm.h create mode 100644 lib/hope_core/switch_expression/switch_expression.h create mode 100644 lib/hope_core/tuple/compute_field_count_recursive.h create mode 100644 lib/hope_core/tuple/detect_fields_count.h create mode 100644 lib/hope_core/tuple/flat_sorted_tuple.h create mode 100644 lib/hope_core/tuple/flat_tuple.h create mode 100644 lib/hope_core/tuple/generated.h create mode 100644 lib/hope_core/tuple/legacy/tuple.h create mode 100644 lib/hope_core/tuple/print_tuple.h create mode 100644 lib/hope_core/tuple/tuple_from_struct.h create mode 100644 lib/hope_core/tuple/tuple_from_struct_unsafe.h create mode 100644 lib/hope_core/tuple/tuple_policy.h create mode 100644 lib/hope_core/tuple/tuple_utils.h create mode 100644 lib/hope_core/type_traits/any_convertible.h create mode 100644 lib/hope_core/type_traits/detector.h create mode 100644 lib/hope_core/type_traits/integraltypes.h create mode 100644 lib/hope_core/type_traits/is_invokable.h create mode 100644 lib/hope_core/type_traits/loophole.h create mode 100644 lib/hope_core/type_traits/type_list.h create mode 100644 lib/hope_core/type_traits/type_list_detail.h create mode 100644 lib/hope_core/type_traits/type_value_map.h create mode 100644 lib/hope_core/type_traits/typelistsort.h create mode 100644 lib/hope_core/type_traits/typemap.h create mode 100644 lib/hope_core/type_traits/user_defined_types.h create mode 100644 lib/hope_core/type_traits/utility.h create mode 100644 test/CMakeLists.txt create mode 100644 test/CMakeLists.txt.in create mode 100644 test/Tests.cpp create mode 100644 test/tests/any_convertible_test.cpp create mode 100644 test/tests/detector_test.cpp create mode 100644 test/tests/fieldescounttest.cpp create mode 100644 test/tests/ref_tuple_from_struct_test.cpp create mode 100644 test/tests/switch_expression_test.cpp create mode 100644 test/tests/tupletest.cpp create mode 100644 test/tests/typelisttests.cpp create mode 100644 test/tests/typemap_test.cpp create mode 100644 test/tests/utility_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ba5970b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.11) + +project(hope-core-main) + +enable_testing() + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_subdirectory(test) +add_subdirectory(lib) \ No newline at end of file diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..161f22a --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.11) + +project(hope-core) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +file(GLOB HOPE_HEADERS + hope_core/fsm*.h + hope_core/switch_expression*.h + hope_core/tuple*.h + hope_core/type_traits*.h +) + +add_library(hope-core INTERFACE ${HOPE_HEADERS}) +target_include_directories(hope-core INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +set(CMAKE_INSTALL_DIRECTORY ${CMAKE_BINARY_DIR}) +INSTALL(DIRECTORY hope_core/ DESTINATION ${CMAKE_INSTALL_DIRECTORY}/include/hope_core + FILES_MATCHING PATTERN "*.h") \ No newline at end of file diff --git a/lib/hope_core/fsm/fsm.h b/lib/hope_core/fsm/fsm.h new file mode 100644 index 0000000..41542c7 --- /dev/null +++ b/lib/hope_core/fsm/fsm.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2021 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope/tuple/flat_tuple.h" +#include + +namespace hope::fsm { + + template + struct transit_to final { + using target_state_t = State; + }; + + template + class fsm; + + template + class fsm, Handlers...> final : public Handlers... { + public: + using Handlers::operator()...; + + constexpr explicit fsm(Handlers&&... handlers) + : Handlers(std::forward(handlers))...{ } + + template + void on_event(Event&& e) { + std::size_t state_index{ 0 }; + bool transition_done{ false }; + for_each(states, [&] (auto&& state){ + if(!transition_done && state_index == cur_state) { + using state_t = std::decay_t; + if constexpr (std::is_invocable_v) { + using result_t = std::invoke_result_t; + auto transition_res = this->operator()(state, std::forward(e)); + (void)transition_res; // remove unused variable warning (var is handled 'cause it may be used later) + if constexpr (!std::is_same_v) { // move to next state + cur_state = find(type_list{}); + transition_done = true; + } + } + } + ++state_index; + }); + } + + [[nodiscard]] std::size_t get_cur_state() const noexcept { + return cur_state; + } + + private: + flat_tuple states; + std::size_t cur_state{ 0 }; + }; + + template + constexpr auto make(Handlers&&... handlers) { + return fsm, Handlers...>(std::forward(handlers)...); + } + +} diff --git a/lib/hope_core/switch_expression/switch_expression.h b/lib/hope_core/switch_expression/switch_expression.h new file mode 100644 index 0000000..656920d --- /dev/null +++ b/lib/hope_core/switch_expression/switch_expression.h @@ -0,0 +1,102 @@ +/* Copyright (C) 2021 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include +#include "hope_core/type_traits/type_list.h" + +namespace hope { + + template + class switch_expression_member final { + static_assert(sizeof ...(Ts) > 0); + public: + explicit switch_expression_member(const Ts&... args) + : expression(args...) { + + } + + template + bool apply(TClass& instance, const TKey& key, TVs&&... args) { + return evaluate(instance, key, std::make_index_sequence{}, std::forward(args)...); + } + + private: + template + bool evaluate(TClass& instance, const TKey key, std::index_sequence, TVs&&... args) { + return (... || try_apply(instance, key, std::forward(args)...)); + } + + template + bool try_apply(TClass& Instance, const TKey key, TVs&&... args) { + if constexpr (I + 1 < sizeof ...(Ts)) { + // Even is a key, odd is a function + if constexpr (I % 2 == 0) { + // todo:: check if callable + if (key == std::get(expression)) { + auto* function = std::get(expression); + (Instance.*function)(std::forward(Args)...); + return true; + } + } + } + return false; + } + + std::tuple expression; + }; + + template + switch_expression_member(Ts...) -> switch_expression_member; + + + template + class switch_expression_lambda final { + static_assert(sizeof ...(Ts) > 0); + + public: + explicit switch_expression_lambda(const Ts&... args) + : expression(args...) { + + } + + template + bool apply(const TKey& key, TVs&&... vals) { + return evaluate(key, std::make_index_sequence{}, std::forward(vals)...); + } + + private: + template + bool evaluate(const TKey& key, std::index_sequence, TVs&&... vals) { + return (... || try_apply(key, std::forward(vals)...)); + } + + template + bool try_apply(const TKey& key, TVs&&... vals) { + if constexpr (I + 1 < sizeof ...(Ts)) { + // Even is a key, odd is a function + if constexpr (I % 2 == 0) { + // todo:: check if callable + if (key == std::get(expression)) { + auto&& function = std::get(expression); + function(std::forward(vals)...); + return true; + } + } + } + return false; + } + + std::tuple expression; + }; + + template + switch_expression_lambda(Ts...) -> switch_expression_lambda; + +} \ No newline at end of file diff --git a/lib/hope_core/tuple/compute_field_count_recursive.h b/lib/hope_core/tuple/compute_field_count_recursive.h new file mode 100644 index 0000000..130c5b2 --- /dev/null +++ b/lib/hope_core/tuple/compute_field_count_recursive.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope_core/tuple/tuple_from_struct.h" +#include "hope_core/tuple/tuple_from_struct_unsafe.h" +#include "hope_core/tuple/tuple_policy.h" +#include "hope_core/type_traits/user_defined_types.h" +#include "hope_core/type_traits/detector.h" + +/*! \defgroup Static reflection + @{ + \file + \brief the file contains several functions for recursively calculating the number of fields within the structure. + Only user-defined types are computed recursively, the classes of the standard library are considered a single whole +*/ + +namespace hope { + + /** + * Implementation of the compile - time fields count computer. Is intended to use with c++ aggregates + * @tparam TStructure Structure structure the number of fields to be calculated + * @return Number of fields + */ + template + constexpr std::size_t compute_field_count_recursive_constexpr() { + if constexpr (is_user_defined_type_v) { + constexpr auto fields_count = detect_fields_count(); + constexpr auto types = detail::extract_types(std::make_index_sequence()); + std::size_t count{0}; + for_each(types, [&](auto field) { + using type_t = typename decltype(field)::Type; + count += compute_field_count_recursive_constexpr(); + }); + return count; + } else { + return 1u; + } + } + + /** + * Implementation of the run - time fields count computer; NOTE: each subfield will be instantiated, + * be aware of usages of this function for heavy - weight objects. + * @tparam TStructure Structure structure the number of fields to be calculated + * @return Number of fields + */ + template + std::size_t compute_field_count_recursive() { + if constexpr(is_user_defined_type_v) { + const TStructure object{}; + auto tuple = tuple_from_struct(object, field_policy::reference{}); + std::size_t count{0}; + for_each(tuple, [&](auto &&field) { + using type_t = std::decay_t; + count += compute_field_count_recursive(); + }); + return count; + } else { + return 1u; + } + } + +} + +/*! @} */ diff --git a/lib/hope_core/tuple/detect_fields_count.h b/lib/hope_core/tuple/detect_fields_count.h new file mode 100644 index 0000000..f10c89b --- /dev/null +++ b/lib/hope_core/tuple/detect_fields_count.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include + +/*! \defgroup Static reflection + @{ + \file + \brief This file consists of helper functions which is used to compute fields count (in general) + And the only one function which computes count of the structure's fields (non - recursive) +*/ + +namespace hope { + namespace detail { + + /** + * The only one reason of existing of this class is initialization of object of different types. + * This is the same as ubiq from magic-get + * @tparam TStruct Type to be converted to + * @tparam I Index, is used to unambiguously define the type + */ + template + struct any_convertible { + template >> + constexpr operator T& () const noexcept; + }; + + /** + * This two functions is needed to determine whether object of corresponding type might be constructed with + * specified count of objects or not. NOTE: uses aggregate initialization, only aggregate initialisable + * classes are allowed. + * @tparam TStruct type of the structure to check + * @tparam Is Sequence of indexes to initialize + * @return true if the type is initialisable with sizeof(Is...) objects + */ + template + constexpr auto is_constructable_n(std::index_sequence) + ->decltype(TStruct{ any_convertible{}... }, bool()) { + return true; + } + template + constexpr auto is_constructable_n(...) { + return false; + } + + /** + * Implementation of the fields computation function. + * @tparam TStructure Desired type + * @tparam Is Indexes of the sequence + * @param sequence Helper sequence of the indexes which might be used to compute fields count + * @return Count of structure's fields + */ + template + constexpr std::size_t detect_fields_count_impl(std::index_sequence sequence) { + bool bs[] = { is_constructable_n(std::make_index_sequence())... }; + // since cxx20... msvc sucks + //return std::distance(std::begin(bs), std::find( + // std::begin(bs), std::end(bs), false) + //); + + for (std::size_t i{ 1 }; i < sequence.size(); ++i) { + if (!bs[i]) return i - 1; + } + return 0; + } + } + + /** + * Interface of computation function, is intended to catch all the errors and show error reason. + * @tparam TStructure Desired type to compute fields. + * @return Number of fields + */ + template + constexpr std::size_t detect_fields_count() { + static_assert(!std::is_polymorphic_v, "---- hope ---- Polymorphic types are not allowed"); + static_assert(std::is_aggregate_v, "---- hope ---- Only aggregate initializable types are allowed"); + + constexpr auto size = sizeof(TStructure); + return detail::detect_fields_count_impl(std::make_index_sequence()); + } +} + +/*! @} */ diff --git a/lib/hope_core/tuple/flat_sorted_tuple.h b/lib/hope_core/tuple/flat_sorted_tuple.h new file mode 100644 index 0000000..a6a0cee --- /dev/null +++ b/lib/hope_core/tuple/flat_sorted_tuple.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope/typelist/type_list.h" +#include "hope/typelist/typelistsort.h" +#include "hope/tuple/flat_tuple.h" + +/*! \defgroup Static reflection + @{ + \file + \brief This file contains function which might be used to create tuple of specified types. Before tuple creation all + the corresponding types sorts and reorders by predicate. +*/ + +namespace hope { + namespace detail { + + template + constexpr auto make_flat_tuple_from_type_list(type_list, Vs&&... args) { + return flat_tuple(std::forward(args)...); + } + } + + /** + * Function creates tuple of specified types with given values; Firstly types sorts by size (descending order). + * Then values reorder is required. + * \warning NOTE: This function is not implemented yet. And does not + * @tparam Ts + * @param args + * @return + */ + template + constexpr auto make_sorted_tuple(Ts&&... args) { + constexpr auto typeList = sort(type_list{}); + return detail::make_flat_tuple_from_type_list(typeList, std::forward(args)...); + } +} + +/*! @} */ \ No newline at end of file diff --git a/lib/hope_core/tuple/flat_tuple.h b/lib/hope_core/tuple/flat_tuple.h new file mode 100644 index 0000000..60a51b2 --- /dev/null +++ b/lib/hope_core/tuple/flat_tuple.h @@ -0,0 +1,345 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope_core/type_traits/type_list.h" + +/*! \defgroup Static reflection + @{ + \file + \brief Implementation of non - recursive tuple, tuple size and alignment is same as structure with fields of + specified types; Also this class contains a lot of useful methods. +*/ + +namespace hope { + namespace detail { + + /** + * \brief Tag is used to identify whether object of provided type is tuple or not + */ + struct tuple_tag { + }; + + /** + * \breaf Structure used to create non recursive tuple via inheritance. + * @tparam T Corresponding type, value of this type is stored as single field + * @tparam I Index of current field (transparent). Is used to unambiguously determine value + */ + template + struct indexed_value { + constexpr indexed_value() = default; + + constexpr indexed_value(indexed_value &&) = default; + + constexpr indexed_value(const indexed_value &) = default; + + ~indexed_value() = default; + + template + explicit constexpr indexed_value(Vt &&valueRef) + : value(std::forward(valueRef)) { + static_assert(std::is_constructible_v, + "hope::indexed_value: given object is not suitable as initializer" + ); + } + + T value; + }; + + template + class flat_tuple_impl; + + /** + * \breaf General class of the all static reflection module. + * @tparam Is Helper sequence of indexes, max(Is...) + is the count of the tuple's elements + * @tparam Ts Types stored in the tuple + */ + template + class flat_tuple_impl, Ts...> : public tuple_tag, public indexed_value ... { + using self_t = flat_tuple_impl, Ts...>; + constexpr static type_list...> types{}; // only clear types might be used, thus make it clear here + + template + using native_t = std::decay_t(types))::Type>; + protected: + using flat_tuple = flat_tuple_impl, Ts...>; + + constexpr flat_tuple_impl() = default; + constexpr flat_tuple_impl(const flat_tuple_impl &) = default; + constexpr flat_tuple_impl(flat_tuple_impl &&) = default; + + ~flat_tuple_impl() = default; + + template + constexpr flat_tuple_impl(VTs &&... elems) noexcept + : indexed_value(std::forward(elems))... {} + + public: + constexpr static std::size_t tuple_size{size(types)}; + + /** + * \brief Tries to find element of specified type, fails on static assert if element had not been found; method is not sensitive to the + * qualifiers, followed constructions are equal: get() get() , get(), get(); accessed value will be automatically deduced + * by tuple's type (regardless of field policy is being used to create the tuple). + * + * \tparam T : Type of element to be returned, const and reference qualifiers does not matter + * + * \tparam NativeT : clear type, used to deduce return type and check whether tuple has element with specified value or not + * + * \return reference to the containing element + */ + template> + [[nodiscard]] constexpr decltype(auto) + get() noexcept { + static_assert(contains(types)); + constexpr auto TypeIndex = find(types); + using value_t = typename decltype(deduce_type())::Type; + return get_impl(); + } + + /** + * \brief Tries to find element of specified type, fails on static assert if element had not been found; method is not sensitive to the + * qualifiers, followed constructions are equal: get() get() , get(), get(); accessed value will be automatically deduced + * by tuple's type (regardless of field policy is being used to create the tuple). + * + * \tparam T : Type of element to be returned, const and reference qualifiers does not matter + * + * \tparam NativeT : clear type, used to deduce return type and check whether tuple has element with specified value or not + * + * \return reference to the containing element + */ + template> + [[nodiscard]] constexpr decltype(auto) + get() const noexcept { + static_assert(contains(types)); + constexpr auto TypeIndex = find(types); + using value_t = typename decltype(deduce_type())::Type; + return get_impl(); + } + + /** + * \brief Tries to find element with given index + * \tparam N Index of the element to be found + * \return Reference to the containing element, const and ref qualifiers of the containing one are not change, + * ref will be returned "as is" + */ + template + [[nodiscard]] constexpr decltype(auto) + get() noexcept { + static_assert(tuple_size > N); + using nth_t = native_t; + using value_t = typename decltype(deduce_type())::Type; + return get_impl(); + } + + /** + * \brief Tries to find element with given index + * \tparam N Index of the element to be found + * \return Reference to the containing element, const and ref qualifiers of the containing one do not change, + * ref will be returned "as is" + */ + template + [[nodiscard]] constexpr decltype(auto) + get() const noexcept { + static_assert(tuple_size > N); + using nth_t = native_t; + using value_t = typename decltype(deduce_type())::Type; + return get_impl(); + } + + /** + * \brief Applies given functor to each value of tuple, more useful analogue of std::apply + * \tparam F type of functional object + * \param f functional object to be sequentially applied to each field of tuple + */ + template + constexpr void for_each(F &&f) const { + (f(get()), ...); + } + + /** + * \brief Applies given functor to each value of tuples + * \tparam F type of functional object + * \param tuple2 second tuple the function to be applied to + * \param f functional object to be sequentially applied to each field of tuple + */ + template + constexpr void for_each(const flat_tuple &tuple2, F &&f) const { + (f(get(), tuple2.template get()), ...); + } + + /** + * \brief Applies given functor to each value of given tuple, more useful analogue of std::apply + * \tparam F type of functional object + * \param f functional object to be sequentially applied to each field of tuple + */ + template + constexpr void for_each(F &&f) { + (f(get()), ...); + } + + /** + * \brief Applies given functor to each value of tuples + * \tparam F type of functional object + * \param tuple2 second tuple the function to be applied to + * \param f functional object to be sequentially applied to each field of tuple + */ + template + constexpr void for_each(flat_tuple &tuple2, F &&f) { + (f(get(), tuple2.template get()), ...); + } + + /** + * \brief just returns the size of the tuple (means number of fields) + * \return number of fields + */ + [[nodiscard]] static constexpr auto get_size() noexcept { + return tuple_size; + } + + private: + + /** + * \brief Cast self to the specified type (indexed value instantiated with N and NativeT) + * \tparam N index of value to be returned + * \tparam NativeT final type of value to be returned + * \return reference of the containing value + */ + template + [[nodiscard]] constexpr decltype(auto) + get_impl() const noexcept { + return static_cast( + static_cast &> (*this).value + ); + } + + /** + * \brief Cast self to the specified type (indexed value instantiated with N and NativeT) + * \tparam N index of value to be returned + * \tparam NativeT final type of value to be returned + * \return reference of the containing value + */ + template + constexpr decltype(auto) + get_impl() noexcept { + return static_cast( + static_cast &> (*this).value + ); + } + + /** + * \brief Tries to deduce final type of the value with specified type and given index + * \tparam T : clear type to be used to deduce final type + * \tparam I : index of element to be processed + * \return : final type of the first value which decayed type is match with given one + */ + template + [[nodiscard]] constexpr auto deduce_type() const noexcept { + // we cannot unambiguous determine holding type, thus try to cast to value and ref, and const ref... + if constexpr (std::is_base_of_v<::hope::detail::indexed_value, self_t>) //fixed crazy clion error + return type_holder{}; + else if constexpr (std::is_base_of_v<::hope::detail::indexed_value, self_t>) //fixed crazy clion error + return type_holder{}; + else + return type_holder{}; + } + }; + + template + using flat_tuple_t = flat_tuple_impl{})>, Ts...>; + } + + /** + * \brief Implementation of the struct like non recursive tuple which might be used to directly cast to struct with same fields + * because alignment of the structs's fields and tuple's fields are match + * \tparam Ts types which might be stored in the tuple + */ + template + class flat_tuple final : public detail::flat_tuple_t { + public: + template...>, type_list...>>>> + constexpr flat_tuple(VTs &&... elems) noexcept + : detail::flat_tuple_t(std::forward(elems)...) {} + + constexpr flat_tuple() + : detail::flat_tuple_t() {} + }; + + template + flat_tuple(Ts...)->flat_tuple; + + /** + * \brief Helper function, which should be used to create flat tuple with given arguments + * all given values will be forwarded to the tuple instance + * \tparam Ts type pack to be propagate to the flat tuple + * \param args arguments are used to initialize each field of the tuple + * \return created tuple + */ + template + constexpr auto make_flat_tuple(Ts &&... args) { + return flat_tuple...>(std::forward(args)...); + } + + /** + * \brief Helper function, should be used to create tuple of elements with specified bit size + * \tparam Ts type pack to be propagate to the flat tuple + * \param args arguments are used to initialize each field of the tuple + * \return created tuple + */ + template + constexpr auto make_flat_tuple_bitfield_friendly(Ts... args) { + return flat_tuple...>(std::forward(args)...); + } + + /** + * \brief Helper function, creates tuple with references to the given arguments; const quality of arguments do not changes + * \tparam Ts type pack to be propagate to the flat tuple + * \param args arguments to create references for + * \return tuple of references to given objects + */ + template + constexpr auto make_flat_ref_tuple(Ts &&... args) { + return flat_tuple(std::forward(args)...); + } + + /** + * Helper function, should be used to call corresponding function on each value of the provided tuple. + * SFINAE is used to disable this function to other types, which might be used in the functions with the + * same signature, such as type_list::for_each + * @tparam Tuple Type of the tuple the function to be applied to, only hope::flat_tuple is allowed + * @tparam F The type of the function + * @param tuple Instance of the tuple object(const ref and ref might be used) + * @param f Instance of the functor to be applied to + */ + template + constexpr std::enable_if_t>> + for_each(Tuple &&tuple, F &&f) { + tuple.for_each(std::forward(f)); + } + + /** + * Helper function, should be used to call corresponding function on each value of the provided tuples. + * SFINAE is used to disable this function to other types, which might be used in the functions with the + * same signature, such as type_list::for_each + * @tparam Tuple Type of the tuple the function to be applied to, only hope::flat_tuple is allowed + * @tparam F The type of the function + * @param tuple1 Instance of the first tuple object(const ref and ref might be used). Values from this object will be + * given as first argument to the desired function. + * @param tuple2 Same as tuple1, but values of this tuple will be provided to the desired function as second arg. + * @param f The instance of the function to be called + */ + template + constexpr std::enable_if_t>> + for_each(Tuple &&tuple1, Tuple &&tuple2, F &&f) { + tuple1.for_each(std::forward(tuple2), std::forward(f)); + } +} + +/*! @} */ \ No newline at end of file diff --git a/lib/hope_core/tuple/generated.h b/lib/hope_core/tuple/generated.h new file mode 100644 index 0000000..f3d868a --- /dev/null +++ b/lib/hope_core/tuple/generated.h @@ -0,0 +1,919 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope_core/tuple/flat_tuple.h" +#include "hope_core/tuple/tuple_policy.h" + +/* + \file + + This file is consists of the generated functions witch intended to be used to generate tuples with specified count + of values; +*/ + +namespace hope::detail { + + template + using Int = std::integral_constant; + + namespace generated { + + template + constexpr auto tuple_from_struct(T&& object, Int<1>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0); + else + return make_flat_ref_tuple(_0); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<2>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1); + else + return make_flat_ref_tuple(_0, _1); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<3>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2); + else + return make_flat_ref_tuple(_0, _1, _2); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<4>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3); + else + return make_flat_ref_tuple(_0, _1, _2, _3); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<5>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<6>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<7>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<8>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<9>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<10>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<11>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<12>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<13>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<14>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<15>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<16>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<17>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<18>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<19>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<20>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<21>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<22>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<23>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<24>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<25>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<26>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<27>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<28>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<29>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<30>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<31>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<32>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<33>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<34>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<35>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<36>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<37>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<38>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<39>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<40>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<41>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<42>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<43>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<44>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<45>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<46>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<47>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<48>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<49>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<50>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<51>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<52>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<53>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<54>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<55>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<56>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<57>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<58>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<59>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<60>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<61>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<62>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<63>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<64>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<65>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<66>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<67>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<68>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<69>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<70>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<71>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<72>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<73>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<74>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<75>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<76>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<77>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<78>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<79>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<80>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<81>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<82>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<83>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<84>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<85>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<86>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<87>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<88>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<89>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<90>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<91>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<92>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<93>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<94>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<95>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<96>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<97>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<98>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97); + } + + template + constexpr auto tuple_from_struct(T&& object, Int<99>, ValuePolicy value_policy = ValuePolicy{}) { + auto&& [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98] = object; + if constexpr (std::is_same_v) + return make_flat_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98); + else + return make_flat_ref_tuple(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98); + } + } +} \ No newline at end of file diff --git a/lib/hope_core/tuple/legacy/tuple.h b/lib/hope_core/tuple/legacy/tuple.h new file mode 100644 index 0000000..4d6c8f0 --- /dev/null +++ b/lib/hope_core/tuple/legacy/tuple.h @@ -0,0 +1,115 @@ +/* Copyright (C) 2020 - 2022 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +/* + \file + \brief File contains implementation of the classic recursive tuple. This class should never be used. + ANYMORE! NOWERE! + Compilation of this class is quit complicated deal. +*/ + +#pragma once + +#include +#include + +namespace hope { + + template + class tuple; + + template + class tuple { + public: + tuple() = default; + + template + && std::is_same_v...>> + tuple(Head&& head, tuple&& tail) + : m_head(std::forward(head)) + , m_tail(std::forward(tail)...) { } + + template + && std::is_same_v...>> + tuple(Head&& head, Tail&&... tail) + : m_head(std::forward(head)) + , m_tail(std::forward(tail)...) {} + + Head& head() { + return m_head; + } + + const Head& head() const { + return m_head; + } + + tuple& tail() { + return m_tail; + } + + const tuple& tail() const { + return m_tail; + } + private: + Head m_head; + tuple m_tail; + }; + + template <> + class tuple<> { + + }; + + namespace detail + { + template + struct tuple_get { + template + static auto apply(const tuple& tuple) { + return tuple_get::apply(tuple.GetTail()); + } + }; + + template <> + struct tuple_get<0> { + template + static const Head& apply(const tuple& tuple) { + return tuple.GetHead(); + } + }; + + inline void print_tuple(std::ostream& stream, tuple<> const&, bool isFirst = true) { + stream << (isFirst ? '(' : ')'); + } + + template + void print_tuple(std::ostream& stream, tuple const& tuple, bool isFirst = true) { + stream << '('; + stream << tuple.GetHead(); + print_tuple(stream, tuple.GetTail(), false); + } + } + + template + auto get(const tuple& tuple) { + return detail::tuple_get::apply(tuple); + } + + template + auto make_tuple(Ts&&... elems) { + return tuple...>(std::forward(elems)...); + } + + template + std::ostream& operator<<(std::ostream& stream, tuple tuple) { + detail::print_tuple(stream, tuple); + return stream; + } +} diff --git a/lib/hope_core/tuple/print_tuple.h b/lib/hope_core/tuple/print_tuple.h new file mode 100644 index 0000000..86436f0 --- /dev/null +++ b/lib/hope_core/tuple/print_tuple.h @@ -0,0 +1,51 @@ +/* Copyright (C) 2021 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope/tuple/flat_tuple.h" +#include "hope/tuple/tuple_from_struct.h" + +#include + +/*! \defgroup Static reflection + @{ + \file + \brief Implementation of helper print functions. This functions might be used to print any instance of the + aggregate type to the output stream; File contains a quit heavy include : iostream and should never be included + at the header. Be careful with usages of these operators +*/ + +namespace hope{ + + namespace detail { + + /** + * Prints tuple to the given stream + */ + template + void print_impl(std::ostream& stream, const flat_tuple& tuple, std::index_sequence) { + stream << "{ "; + ((stream << (VIs == 0 ? "" : ", ") << tuple.template get()), ...); + stream << " };"; + } + + } + + /** + * This overload of the stream operator is intended to be used in the hope namespace + * Or might bw called via adl; + */ + template + constexpr std::ostream& operator<< (std::ostream& stream, const flat_tuple& tuple) { + print_impl(stream, tuple, std::make_index_sequence{})>()); + return stream; + } +} + +/*! @} */ \ No newline at end of file diff --git a/lib/hope_core/tuple/tuple_from_struct.h b/lib/hope_core/tuple/tuple_from_struct.h new file mode 100644 index 0000000..6dc3062 --- /dev/null +++ b/lib/hope_core/tuple/tuple_from_struct.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2021 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope_core/tuple/tuple_policy.h" +#include "hope_core/tuple/generated.h" +#include "hope_core/tuple/detect_fields_count.h" + +/*! \defgroup Static reflection + @{ +*/ + +namespace hope { + + /** + * \brief Creates tuple from the given struct, type of each field of the result tuple depends on specified field policy (value or reference) + * \tparam T type of the passed struct + * \tparam FieldPolicy Policy of the struct's fields which have to be used to determine result type of each field of the result tuple + * \param object instance of the structure to be converted + * \param p just used to determine field policy (type) + * \return created tuple + */ + template + constexpr auto tuple_from_struct(T&& object, FieldPolicy p = FieldPolicy{}) { + constexpr auto fields_count = detect_fields_count>(); + return detail::generated::tuple_from_struct(std::forward(object), detail::Int{}, FieldPolicy{}); + } + +} + +/*! @} */ diff --git a/lib/hope_core/tuple/tuple_from_struct_unsafe.h b/lib/hope_core/tuple/tuple_from_struct_unsafe.h new file mode 100644 index 0000000..3b1469c --- /dev/null +++ b/lib/hope_core/tuple/tuple_from_struct_unsafe.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope_core/tuple/flat_tuple.h" +#include "hope_core/tuple/detect_fields_count.h" +#include "hope_core/type_traits/type_list.h" +#include "hope_core/type_traits/loophole.h" + +/*! \defgroup Static reflection + @{ +*/ + +namespace hope { + namespace detail{ + + template + constexpr T construct_helper() noexcept { + return {}; + } + + template + struct any_convertible_s { + + using struct_t = std::decay_t; + + template + constexpr operator Row () const noexcept { + using clean_t = std::decay_t; + loophole::inject(struct_t{}, Row{}); + return construct_helper(); + } + }; + + template + constexpr auto tuple_from_type_list(type_list) { + return flat_tuple{}; + } + + template + constexpr auto extract_types(std::index_sequence sequence) { + constexpr T object{ any_convertible_s{}... }; + (void)object; + return type_list(std::declval()))...>{}; + } + } + + template + constexpr auto make_tuple() { + constexpr auto fields_count = detect_fields_count(); + constexpr auto types = detail::extract_types(std::make_index_sequence()); + auto tuple = detail::tuple_from_type_list(types); + return tuple; + } + + template + auto tuple_from_struct_unsafe(const T& object) { + constexpr auto tuple = make_tuple(); + (T&)tuple = object; + return tuple; + } +} diff --git a/lib/hope_core/tuple/tuple_policy.h b/lib/hope_core/tuple/tuple_policy.h new file mode 100644 index 0000000..653c941 --- /dev/null +++ b/lib/hope_core/tuple/tuple_policy.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2021 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +/*! \defgroup Static reflection + @{ +*/ + +namespace hope { + + /** + * \brief struct used as namespace to policies which is used for tuple creation functions + */ + struct field_policy final { + /** + * \brief Policy, used to specify how to convert struct to tuple. If instance of this structure is used, + * all the fields from an object will be copied to the tuple + */ + struct value final {}; + + /** + * \brief Policy, used to specify how to convert struct to tuple. If instance of this structure is used, + * all the fields of resulting tuple will be references to the related fields of initial object(POD) + */ + struct reference final {}; + }; + +} + +/*! @} */ \ No newline at end of file diff --git a/lib/hope_core/tuple/tuple_utils.h b/lib/hope_core/tuple/tuple_utils.h new file mode 100644 index 0000000..b81e62e --- /dev/null +++ b/lib/hope_core/tuple/tuple_utils.h @@ -0,0 +1,131 @@ +/* Copyright (C) 2021 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope_core/tuple/flat_tuple.h" +#include "hope_core/tuple/tuple_from_struct.h" +#include "hope_core/type_traits/user_defined_types.h" +#include "hope_core/type_traits/detector.h" + +#include + +/*! \defgroup Static reflection + @{ +*/ + +namespace hope { + + namespace detail { + + template + constexpr std::enable_if_t, bool> + is_equal(const T& left, const T& right); + + template + constexpr bool is_equal(const flat_tuple& left, const flat_tuple& right, std::index_sequence); + + template + constexpr std::enable_if_t, bool> + is_equal(const T& left, const T& right); + + template + constexpr std::enable_if_t, bool> + is_equal(const T& left, const T& right) { + return left == right; + } + + template + constexpr bool is_equal(const flat_tuple& left, const flat_tuple& right, std::index_sequence) { + return (is_equal(left.template get(), right.template get()) && ...); + } + + template + constexpr std::enable_if_t, bool> + is_equal(const T& left, const T& right) { + return tuple_from_struct(left, field_policy::reference{}) == tuple_from_struct(right, field_policy::reference{}); + } + + template + constexpr std::size_t hash(const T& val) { + return std::hash{}(val); + } + + template + constexpr std::size_t hash(const flat_tuple& tuple, std::index_sequence) { + constexpr auto tuple_size = size(type_list{}); + return (std::size_t(hash(tuple. template get()) / tuple_size) + ...); + } + + template + using equal_operation_t = decltype(std::declval() == std::declval()); + } + + template + constexpr bool operator==(const flat_tuple& left, const flat_tuple& right) { + using tuple_t = flat_tuple; + return detail::is_equal(left, right, std::make_index_sequence()); + } + + template + constexpr bool operator!=(const flat_tuple& left, const flat_tuple& right) { + return !(left == right); + } + + template + constexpr bool operator<(const flat_tuple& left, const flat_tuple& right) { + return detail::is_equal(left, right, std::make_index_sequence::size>()); + } + + template + struct hash final { + constexpr std::size_t operator()(const flat_tuple& tuple) { + return detail::hash(tuple, std::make_index_sequence < size(type_list{})() > ()); + } + }; + + template + bool compare(const TStruct& lhs, const TStruct& rhs, + float float_eps = std::numeric_limits::epsilon(), + double double_eps = std::numeric_limits::epsilon()) noexcept { + + static_assert(std::is_class_v, + "hope::compare: Inbuilt type has been provided, only structures and classes are allowed"); + + auto&& left = tuple_from_struct(lhs, hope::field_policy::reference{}); + auto&& right = tuple_from_struct(rhs, hope::field_policy::reference{}); + auto equal = true; + hope::for_each( // NOTE: do not remove hope::, 'cause utility like foreach is in conflict with stl for_each. + left, right, + [&](auto&& l, auto&& r){ + if (!equal) return; + using value_t = std::decay_t; + // msvc sucks and tries to compile else branch in constexpr statement (is is legal?) + constexpr bool has_equal_operator = is_detected_v; + if constexpr (std::is_same_v){ + equal = std::abs(l - r) < float_eps; + } else if constexpr (std::is_floating_point_v){ + equal = std::abs(l - r) < (value_t)double_eps; + } else if constexpr (has_equal_operator){ + equal = l == r; + } else if constexpr (!has_equal_operator){ + equal = compare(l, r, float_eps, double_eps); + } + } + ); + return equal; + } +} + +template +constexpr std::enable_if_t, bool> +operator==(const TStruct& left, const TStruct& right) { + return hope::tuple_from_struct(left, hope::field_policy::reference{}) == hope::tuple_from_struct(right, hope::field_policy::reference{}); +} + +/*! @} */ \ No newline at end of file diff --git a/lib/hope_core/type_traits/any_convertible.h b/lib/hope_core/type_traits/any_convertible.h new file mode 100644 index 0000000..acb8947 --- /dev/null +++ b/lib/hope_core/type_traits/any_convertible.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include + +#include "hope_core/type_traits/detector.h" + +namespace hope { + + template + struct any_convertible { + + template + using from_t = decltype(std::declval().from(std::declval())); + + template + using assign_t = decltype(std::declval().operator=(std::declval())); + + template + using static_from_t = decltype(T::from(std::declval())); + + template + constexpr operator T() { + check_type(); + if constexpr (is_detected::value) { + return T::from(child()); + } + if constexpr (is_detected::value){ + T res{ }; + res.from(child()); + return res; + } + if constexpr (is_detected::value) { + T res{ }; + return res.operator=(child()); + } + return T{ }; + } + + private: + constexpr const Child& child() { + return static_cast(*this); + } + + template + constexpr static void check_type() { + static_assert(std::is_convertible_v + || is_detected::value + || is_detected::value + || is_detected::value); + } + }; +} \ No newline at end of file diff --git a/lib/hope_core/type_traits/detector.h b/lib/hope_core/type_traits/detector.h new file mode 100644 index 0000000..6e4e283 --- /dev/null +++ b/lib/hope_core/type_traits/detector.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include + +namespace hope { + + namespace detail { + + template class Op, class... Args> + struct detector { + using value_t = std::false_type; + using type = Default; + }; + + template class Op, class... Args> + struct detector>, Op, Args...> { + using value_t = std::true_type; + using type = Op; + }; + + } + + struct nonesuch final { + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + void operator=(nonesuch const&) = delete; + }; + + template class Op, class... Args> + using is_detected = typename detail::detector::value_t; + + template class Op, class... Args> + constexpr bool is_detected_v = detail::detector::value_t::value; + + template class Op, class... Args> + using detected_t = typename detail::detector::type; + + template class Op, class... Args> + using detected_or = detail::detector; + + template + constexpr bool is_constexpr(Lambda) { return true; } + constexpr bool is_constexpr(...) { return false; } +} \ No newline at end of file diff --git a/lib/hope_core/type_traits/integraltypes.h b/lib/hope_core/type_traits/integraltypes.h new file mode 100644 index 0000000..7d291ed --- /dev/null +++ b/lib/hope_core/type_traits/integraltypes.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope/typelist/type_list.h" + +namespace hope { + constexpr static type_list + + IntegralTypes { }; + + constexpr static std::size_t IntegralTypesCount{ size(IntegralTypes) }; +} + diff --git a/lib/hope_core/type_traits/is_invokable.h b/lib/hope_core/type_traits/is_invokable.h new file mode 100644 index 0000000..a30295a --- /dev/null +++ b/lib/hope_core/type_traits/is_invokable.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once +#include + +namespace detail { + + template ()(std::declval()...))> + std::true_type is_valid_impl(void*); + + template + std::false_type is_valid_impl(...); + + constexpr auto is_valid = [](auto f) { + return [](auto&&... args) { + return + decltype(is_valid_impl(nullptr)){}; + }; + }; + + template + struct just_type { + using Type = T; + }; + + template + constexpr auto type = just_type{}; + + template + T value(just_type); +} + +namespace hope { + constexpr auto is_default_constructable + = detail::is_valid([](auto x)->decltype((void)decltype(detail::value(x))()) {}); +} + diff --git a/lib/hope_core/type_traits/loophole.h b/lib/hope_core/type_traits/loophole.h new file mode 100644 index 0000000..7ad0ab8 --- /dev/null +++ b/lib/hope_core/type_traits/loophole.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +namespace hope::loophole { + + namespace detail { + template + struct def_inserter_i { + friend constexpr auto get_impl(def_inserter_i); + }; + + template + struct def_inserter { + friend constexpr auto get_impl(def_inserter); + }; + + template + struct decl_inserter { + friend constexpr auto get_impl(K) { + return V{}; + } + }; + } + + template + constexpr void inject(K, V) { + (void)sizeof(detail::decl_inserter, V>); + } + + template + constexpr void inject(K, V) { + (void)sizeof(detail::decl_inserter, V>); + } + + template + constexpr auto get(K) { + return get_impl(detail::def_inserter{}); + } + + template + constexpr auto get(K) { + return get_impl(detail::def_inserter_i{}); + } + +} diff --git a/lib/hope_core/type_traits/type_list.h b/lib/hope_core/type_traits/type_list.h new file mode 100644 index 0000000..1830555 --- /dev/null +++ b/lib/hope_core/type_traits/type_list.h @@ -0,0 +1,190 @@ +/* Copyright (C) 2020 - 2024 Gleb Bezborodov - All Rights Reserved + * You may use, distribute and modify this code under the + * terms of the MIT license. + * + * You should have received a copy of the MIT license with + * this file. If not, please write to: bezborodoff.gleb@gmail.com, or visit : https://github.com/glensand/hope-core + */ + +#pragma once + +#include "hope_core/type_traits/type_list_detail.h" + +#include +#include +#include + +namespace hope { + + template + struct type_holder final { + using Type = T; + }; + + template + class type_list final { + + }; + + template + constexpr size_t size(type_list) { + return sizeof...(Ts); + } + + template + constexpr type_holder front(type_list) { + return {}; + } + + template + constexpr type_list pop_front(type_list) { + return {}; + } + + template + constexpr type_list push_front(type_list, type_holder) { + return {}; + } + + template + constexpr type_list concat(type_list, type_list) { + return {}; + } + template + constexpr type_holder back(type_list) { + return {}; + } + + template + constexpr bool contains(type_list) { + return (... || std::is_same_v); + } + + template + constexpr bool contains14(type_list) { + constexpr bool bs[] = { std::is_same_v... }; + bool result = false; + for (bool b : bs) + result |= b; + + return result; + } + + template + constexpr std::size_t find(type_list list) { + constexpr bool bs[] = { std::is_same_v... }; + constexpr size_t list_size = size(list); + + for (size_t i = 0; i < list_size; ++i) { + if (bs[i]) + return i; + } + return list_size; + } + + template + constexpr std::size_t find_nth_of(type_list list) { + constexpr bool bs[] = { std::is_same_v... }; + constexpr size_t list_size = size(list); + std::size_t index{ 0 }; + for (size_t i = 0; i < list_size; ++i) { + if (bs[i]) { + if (index == I) + return i; + ++index; + } + } + return list_size; + } + + template + constexpr std::size_t find_cxx20(type_list) { + constexpr bool bs[] = { std::is_same_v... }; + return std::find(bs, true) - bs; + } + + template