// Copyright (c) 2019-2021 Antony Polukhin // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include template struct unconstrained_forwarding_ref { unconstrained_forwarding_ref() = default; unconstrained_forwarding_ref(const unconstrained_forwarding_ref&) = default; unconstrained_forwarding_ref(unconstrained_forwarding_ref&&) = default; unconstrained_forwarding_ref& operator=(const unconstrained_forwarding_ref&) = default; unconstrained_forwarding_ref& operator=(unconstrained_forwarding_ref&&) = default; template constexpr unconstrained_forwarding_ref(U&& val) : value_{std::forward(val)} {} T value_{}; }; struct int_element { int value_; }; struct aggregate_unconstrained { unconstrained_forwarding_ref a; unconstrained_forwarding_ref b; }; int main() { using sanity = decltype(aggregate_unconstrained{ boost::pfr::detail::ubiq_lref_constructor{0}, boost::pfr::detail::ubiq_lref_constructor{1}, }); static_assert( std::is_same< sanity, aggregate_unconstrained >::value, "Precise reflection with template constructors sanity check fails" ); boost::pfr::detail::enable_if_constructible_helper_t foo; (void)foo; static_assert( std::is_same< boost::pfr::tuple_element_t<0, aggregate_unconstrained>, unconstrained_forwarding_ref >::value, "Precise reflection with template constructors fails to work" ); static_assert( std::is_same< boost::pfr::tuple_element_t<1, aggregate_unconstrained>, unconstrained_forwarding_ref >::value, "Precise reflection with template constructors fails to work" ); aggregate_unconstrained aggr{3, 4}; return boost::pfr::get<1>(aggr).value_.value_ - 4; }