#ifndef RFL_MOVE_FROM_NAMED_TUPLE_HPP_ #define RFL_MOVE_FROM_NAMED_TUPLE_HPP_ #include #include "../Tuple.hpp" #include "../named_tuple_t.hpp" #include "is_field.hpp" #include "is_named_tuple.hpp" #include "nt_to_ptr_named_tuple.hpp" #include "ptr_field_tuple_t.hpp" namespace rfl { namespace internal { template auto make_ptr_fields(PtrNamedTupleType& _n) { const auto get_one = [&](std::integral_constant) { using Field = std::remove_cvref_t>; using T = std::remove_cvref_t>; if constexpr (is_named_tuple_v) { using SubPtrNamedTupleType = typename std::invoke_result), T>::type; return SubPtrNamedTupleType(_n).fields(); } else if constexpr (is_flatten_field::value) { using SubPtrFieldTupleType = std::remove_cvref_t>; return make_ptr_fields(_n); } else { return _n.template get_field(); } }; constexpr auto size = rfl::tuple_size_v>; return [&](std::integer_sequence) { return rfl::make_tuple(get_one(std::integral_constant{})...); } (std::make_integer_sequence()); } template auto move_from_ptr_fields(Pointers& _ptrs) { const auto get_one = [&](std::integral_constant) { using FieldType = tuple_element_t<_i, std::remove_cvref_t>; if constexpr (is_field_v) { return rfl::make_field( std::move(*rfl::get<_i>(_ptrs).value())); } else { using PtrFieldTupleType = std::remove_cvref_t>; using U = std::remove_cvref_t::Type>>; return move_from_ptr_fields(rfl::get<_i>(_ptrs)); } }; constexpr auto size = rfl::tuple_size_v>; return [&](std::integer_sequence) { return T{std::move(get_one(std::integral_constant{}))...}; } (std::make_integer_sequence()); } /// Creates a struct of type T from a named tuple by moving the underlying /// fields. template T move_from_named_tuple(NamedTupleType&& _n) { using RequiredType = std::remove_cvref_t>; if constexpr (is_named_tuple_v>) { return std::move(_n); } else if constexpr (std::is_same, RequiredType>()) { auto ptr_named_tuple = nt_to_ptr_named_tuple(_n); using PtrFieldTupleType = std::remove_cvref_t>; auto pointers = make_ptr_fields(ptr_named_tuple); return move_from_ptr_fields(pointers); } else { return move_from_named_tuple(RequiredType(std::move(_n))); } } } // namespace internal } // namespace rfl #endif