diff --git a/include/boost/pfr/detail/core17_generated.hpp b/include/boost/pfr/detail/core17_generated.hpp index f54febb..aa836f3 100644 --- a/include/boost/pfr/detail/core17_generated.hpp +++ b/include/boost/pfr/detail/core17_generated.hpp @@ -73,7 +73,7 @@ constexpr decltype(auto) workaround_cast(Arg& arg) noexcept { } template -constexpr auto tie_as_tuple(T&& /*val*/, size_t_<0>) noexcept { +constexpr auto tie_as_tuple(const T& /*val*/, size_t_<0>) noexcept { return sequence_tuple::tuple<>{}; } @@ -86,7 +86,7 @@ constexpr auto tie_as_tuple(T&& val, size_t_<1>, std::enable_if_t constexpr auto tie_as_tuple(T&& val, size_t_<1>, std::enable_if_t >::value>* = nullptr) noexcept { - return ::boost::pfr::detail::make_tuple_of_references( val ); + return ::boost::pfr::detail::make_tuple_of_references( std::forward(val) ); } diff --git a/misc/generate_cpp17.py b/misc/generate_cpp17.py index 9013045..899bdd7 100644 --- a/misc/generate_cpp17.py +++ b/misc/generate_cpp17.py @@ -44,47 +44,66 @@ namespace boost { namespace pfr { namespace detail { template constexpr auto make_tuple_of_references(Args&&... args) noexcept { - return sequence_tuple::tuple{ args... }; + return sequence_tuple::tuple{ static_cast(args)... }; } template constexpr decltype(auto) add_cv_like(Arg& arg) noexcept { - if constexpr (std::is_const::value && std::is_volatile::value) { - return const_cast(arg); - } - else if constexpr (std::is_const::value) { - return const_cast(arg); - } - else if constexpr (std::is_volatile::value) { - return const_cast(arg); - } - else { - return const_cast(arg); + if constexpr (std::is_rvalue_reference::value) { + if constexpr (std::is_const::value && std::is_volatile::value) { + return const_cast(arg); + } + else if constexpr (std::is_const::value) { + return const_cast(arg); + } + else if constexpr (std::is_volatile::value) { + return const_cast(arg); + } + else { + return const_cast(arg); + } + } else { + if constexpr (std::is_const::value && std::is_volatile::value) { + return const_cast(arg); + } + else if constexpr (std::is_const::value) { + return const_cast(arg); + } + else if constexpr (std::is_volatile::value) { + return const_cast(arg); + } + else { + return const_cast(arg); + } } } // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78939 template constexpr decltype(auto) workaround_cast(Arg& arg) noexcept { - using output_arg_t = std::conditional_t(), decltype(detail::add_cv_like(arg)), Sb>; + using output_arg_t = std::conditional_t< + !std::is_reference(), + decltype(detail::add_cv_like(arg)), + std::conditional_t::value, Sb&&, Sb&> + >; return const_cast(arg); } template -constexpr auto tie_as_tuple(T& /*val*/, size_t_<0>) noexcept { +constexpr auto tie_as_tuple(const T& /*val*/, size_t_<0>) noexcept { return sequence_tuple::tuple<>{}; } template -constexpr auto tie_as_tuple(T& val, size_t_<1>, std::enable_if_t >::value>* = nullptr) noexcept { - auto& [a] = const_cast&>(val); // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. +constexpr auto tie_as_tuple(T&& val, size_t_<1>, std::enable_if_t >::value>* = nullptr) noexcept { + auto&& [a] = const_cast&>(val); // ====================> Boost.PFR: User-provided type is not a SimpleAggregate. return ::boost::pfr::detail::make_tuple_of_references(detail::workaround_cast(a)); } template -constexpr auto tie_as_tuple(T& val, size_t_<1>, std::enable_if_t >::value>* = nullptr) noexcept { - return ::boost::pfr::detail::make_tuple_of_references( val ); +constexpr auto tie_as_tuple(T&& val, size_t_<1>, std::enable_if_t >::value>* = nullptr) noexcept { + return ::boost::pfr::detail::make_tuple_of_references( std::forward(val) ); } """ @@ -92,7 +111,7 @@ constexpr auto tie_as_tuple(T& val, size_t_<1>, std::enable_if_t -constexpr void tie_as_tuple(T& /*val*/, size_t_) noexcept { +constexpr void tie_as_tuple(T&& /*val*/, size_t_) noexcept { static_assert(sizeof(T) && false, "====================> Boost.PFR: Too many fields in a structure T. Regenerate include/boost/pfr/detail/core17_generated.hpp file for appropriate count of fields. For example: `python ./misc/generate_cpp17.py 300 > include/boost/pfr/detail/core17_generated.hpp`"); } @@ -151,11 +170,11 @@ for i in range(1, funcs_count): empty_printer = EmptyLinePrinter() print("template ") - print("constexpr auto tie_as_tuple(T& val, size_t_<" + str(i + 1) + ">) noexcept {") + print("constexpr auto tie_as_tuple(T&& val, size_t_<" + str(i + 1) + ">) noexcept {") if i < max_args_on_a_line: - print(" auto& [" + indexes.strip() + "] = const_cast&>(val); // ====================> Boost.PFR: User-provided type is not a SimpleAggregate.") + print(" auto&& [" + indexes.strip() + "] = const_cast&>(val); // ====================> Boost.PFR: User-provided type is not a SimpleAggregate.") else: - print(" auto& [") + print(" auto&& [") print(indexes) print(" ] = const_cast&>(val); // ====================> Boost.PFR: User-provided type is not a SimpleAggregate.") empty_printer.print_once()