2
0
mirror of https://github.com/boostorg/pfr.git synced 2026-01-19 04:22:13 +00:00

Simplifications and more work for core14 loophole

This commit is contained in:
Antony Polukhin
2017-09-06 21:51:43 +03:00
parent 7b0939289f
commit a6d655e064
4 changed files with 27 additions and 25 deletions

View File

@@ -526,14 +526,14 @@ constexpr bool is_flat_refelectable(std::index_sequence<I...>) noexcept {
}
template <class T>
decltype(auto) tie_as_flat_tuple(T&& val) noexcept {
auto tie_as_flat_tuple(T&& val) noexcept {
typedef internal_tuple_with_same_alignment_t<std::remove_reference_t<T>> tuple_type;
auto&& t = cast_to_layout_compatible<tuple_type>(std::forward<T>(val));
return make_flat_tuple_of_references(std::forward<decltype(t)>(t), size_t_<0>{}, size_t_<tuple_type::size_v>{});
}
template <class T>
decltype(auto) tie_as_tuple(T&& val) noexcept {
auto tie_as_tuple(T&& val) noexcept {
typedef std::remove_reference_t<T> type;
static_assert(
boost::pfr::detail::is_flat_refelectable<type>( std::make_index_sequence<fields_count<type>()>{} ),

View File

@@ -100,8 +100,8 @@ void for_each_field_dispatcher(T&& t, F&& f, std::index_sequence<I...>) {
);
}
template <class T, class F, std::size_t... I>
void tie_as_flat_tuple(T&& t) {
template <class T>
decltype(auto) tie_as_flat_tuple(T&& t) {
return flatten_tuple_recursively(
tie_as_tuple(std::forward<T>(t))
);

View File

@@ -16,30 +16,32 @@
namespace boost { namespace pfr { namespace detail {
// Forward declarations:
template <class T> decltype(auto) flatten_tuple_recursively(T&& val) noexcept;
template <class T> auto flatten_tuple_recursively(T&& val) noexcept;
template <class T> decltype(auto) tie_as_tuple(T&& val) noexcept;
template <class T>
decltype(auto) tie_or_value(T&& val, std::enable_if_t<std::is_class< std::remove_reference_t<T> >::value>* = 0) noexcept {
return flatten_tuple(std::forward<T>(val));
auto tie_or_value(T&& val, std::enable_if_t<std::is_class< std::remove_reference_t<T> >::value>* = 0) noexcept {
return flatten_tuple_recursively(
tie_as_tuple(std::forward<T>(val))
);
}
template <class T>
decltype(auto) tie_or_value(T&& val, std::enable_if_t<!std::is_class< std::remove_reference_t<T> >::value>* = 0) noexcept {
decltype(auto) tie_or_value(T&& val, std::enable_if_t<!std::is_class< std::remove_reference_t<T> >::value && !std::is_array< std::remove_reference_t<T> >::value>* = 0) noexcept {
return std::forward<T>(val);
}
template <class T, std::size_t... I>
decltype(auto) flatten_tuple_recursively_impl(T&& tup, std::index_sequence<I...> ) noexcept {
auto flatten_tuple_recursively_impl(T&& tup, std::index_sequence<I...> ) noexcept {
return sequence_tuple::tuple<
decltype(tie_or_value(sequence_tuple::get<I>(std::forward<T>(tup))))...
>{tie_or_value(sequence_tuple::get<I>(std::forward<T>(tup)))...};
}
template <class T>
decltype(auto) flatten_tuple_recursively(T&& tup) noexcept {
auto flatten_tuple_recursively(T&& tup) noexcept {
using indexes = std::make_index_sequence<T::size_v>;
return flatten_tuple_impl(std::forward<T>(tup), indexes{});
return flatten_tuple_recursively_impl(std::forward<T>(tup), indexes{});
}
}}} // namespace boost::pfr::detail

View File

@@ -44,19 +44,19 @@ constexpr auto make_tuple_of_references(Args&&... args) noexcept {
}
template <class T>
constexpr auto as_tuple_impl(T&& /*val*/, size_t_<0>) noexcept {
constexpr auto tie_as_tuple(T&& /*val*/, size_t_<0>) noexcept {
return sequence_tuple::tuple<>{};
}
template <class T>
constexpr auto as_tuple_impl(T&& val, size_t_<1>, std::enable_if_t<std::is_class< std::remove_cv_t<std::remove_reference_t<T>> >::value>* = 0) noexcept {
constexpr auto tie_as_tuple(T&& val, size_t_<1>, std::enable_if_t<std::is_class< std::remove_cv_t<std::remove_reference_t<T>> >::value>* = 0) noexcept {
auto& [a] = std::forward<T>(val);
return ::boost::pfr::detail::make_tuple_of_references(a);
}
template <class T>
constexpr auto as_tuple_impl(T&& val, size_t_<1>, std::enable_if_t<!std::is_class< std::remove_cv_t<std::remove_reference_t<T>> >::value>* = 0) noexcept {
constexpr auto tie_as_tuple(T&& val, size_t_<1>, std::enable_if_t<!std::is_class< std::remove_cv_t<std::remove_reference_t<T>> >::value>* = 0) noexcept {
return ::boost::pfr::detail::make_tuple_of_references( std::forward<T>(val) );
}
@@ -67,19 +67,19 @@ EPILOGUE = """
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <class T>
constexpr auto as_tuple(const T& val) noexcept {
constexpr auto tie_as_tuple(const T& val) noexcept {
typedef size_t_<fields_count<T>()> fields_count_tag;
return boost::pfr::detail::as_tuple_impl(val, fields_count_tag{});
return boost::pfr::detail::tie_as_tuple(val, fields_count_tag{});
}
template <class T>
constexpr auto as_tuple(T& val) noexcept {
constexpr auto tie_as_tuple(T& val) noexcept {
typedef size_t_<fields_count<T>()> fields_count_tag;
return boost::pfr::detail::as_tuple_impl(val, fields_count_tag{});
return boost::pfr::detail::tie_as_tuple(val, fields_count_tag{});
}
template <class T>
using as_tuple_t = decltype( ::boost::pfr::detail::as_tuple(std::declval<T&>()) );
using tie_as_tuple_t = decltype( ::boost::pfr::detail::tie_as_tuple(std::declval<T&>()) );
}}} // namespace boost::pfr::detail
@@ -93,8 +93,8 @@ generate_sfinae_attempts = False
if generate_sfinae_attempts:
print """
template <class T, std::size_t I>
constexpr auto as_tuple_impl(T&& val, size_t_<I>) noexcept {
return as_tuple_impl( std::forward<T>(val), size_t_<I - 1>{});
constexpr auto tie_as_tuple(T&& val, size_t_<I>) noexcept {
return tie_as_tuple( std::forward<T>(val), size_t_<I - 1>{});
}
"""
@@ -114,7 +114,7 @@ for i in xrange(1, funcs_count):
indexes += ascii_letters[i % max_args_on_a_line]
print "template <class T>"
print "constexpr auto as_tuple_impl(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() + "] = std::forward<T>(val);"
print " return ::boost::pfr::detail::make_tuple_of_references(" + indexes.strip() + ");"
@@ -131,8 +131,8 @@ for i in xrange(1, funcs_count):
if generate_sfinae_attempts:
print "template <class T>"
print "constexpr auto as_tuple_impl(T&& val, size_t_<" + str(i + 1) + "> v) noexcept"
print " ->decltype( ::boost::pfr::detail::as_tuple_impl0(std::forward<T>(val), v) )"
print "{ return ::boost::pfr::detail::as_tuple_impl0(std::forward<T>(val), v); }\n"
print "constexpr auto tie_as_tuple(T&& val, size_t_<" + str(i + 1) + "> v) noexcept"
print " ->decltype( ::boost::pfr::detail::tie_as_tuple0(std::forward<T>(val), v) )"
print "{ return ::boost::pfr::detail::tie_as_tuple0(std::forward<T>(val), v); }\n"
print EPILOGUE