diff --git a/include/boost/pfr/detail/fields_count.hpp b/include/boost/pfr/detail/fields_count.hpp index 6b4483d..5348e4d 100644 --- a/include/boost/pfr/detail/fields_count.hpp +++ b/include/boost/pfr/detail/fields_count.hpp @@ -26,26 +26,41 @@ namespace boost { namespace pfr { namespace detail { +template +constexpr void static_assert_non_inherited() noexcept { + static_assert( + std::is_same, std::remove_cv_t>::value + || !std::is_base_of::value, + "====================> Boost.PFR: Boost.PFR: Inherited types are not supported." + ); +} + ///////////////////// Structure that can be converted to reference to anything -struct ubiq_lref_constructor { +template +struct ubiq_lref_constructor_ { std::size_t ignore; template constexpr operator Type&() const && noexcept { // tweak for template_unconstrained.cpp like cases + static_assert_non_inherited(); return detail::unsafe_declval(); }; template constexpr operator Type&() const & noexcept { // tweak for optional_chrono.cpp like cases + static_assert_non_inherited(); return detail::unsafe_declval(); }; }; +using ubiq_lref_constructor = ubiq_lref_constructor_<>; ///////////////////// Structure that can be converted to rvalue reference to anything -struct ubiq_rref_constructor { +template +struct ubiq_rref_constructor_ { std::size_t ignore; template /*constexpr*/ operator Type() const && noexcept { // Allows initialization of rvalue reference fields and move-only types + static_assert_non_inherited(); return detail::unsafe_declval(); }; }; - +using ubiq_rref_constructor = ubiq_rref_constructor_<>; #ifndef __cpp_lib_is_aggregate ///////////////////// Hand-made is_aggregate_initializable_n trait @@ -78,7 +93,7 @@ template struct is_aggregate_initializable_n { template static constexpr bool is_not_constructible_n(std::index_sequence) noexcept { - return (!std::is_constructible::value && !std::is_constructible::value) + return (!std::is_constructible{I})...>::value && !std::is_constructible{I})...>::value) || is_single_field_and_aggregate_initializable::value ; } @@ -96,11 +111,11 @@ struct is_aggregate_initializable_n { ///////////////////// Helper for SFINAE on fields count template ::value>::type> constexpr auto enable_if_constructible_helper(std::index_sequence) noexcept - -> typename std::add_pointer::type; + -> typename std::add_pointer{I}... })>::type; template ::value>::type> constexpr auto enable_if_constructible_helper(std::index_sequence) noexcept - -> typename std::add_pointer::type; + -> typename std::add_pointer{I}... })>::type; template (detail::make_index_sequence()) ) > using enable_if_constructible_helper_t = std::size_t; diff --git a/test/compile-fail/inherited.cpp b/test/compile-fail/inherited.cpp new file mode 100644 index 0000000..a867c08 --- /dev/null +++ b/test/compile-fail/inherited.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2021 Denis Mikhailov +// +// 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 + +struct A +{}; + +struct B : A +{ + int one; + int two; +}; + +int main() { +#ifndef __cpp_lib_is_aggregate +// TODO: No known way to detect inherited +# error No known way to detect inherited. +#endif + (void)boost::pfr::tuple_size::value; // Must be a compile time error + return boost::report_errors(); +} + + +