diff --git a/include/boost/fusion/support/detail/is_trivially_copyable.hpp b/include/boost/fusion/support/detail/is_trivially_copyable.hpp new file mode 100644 index 00000000..87ef244b --- /dev/null +++ b/include/boost/fusion/support/detail/is_trivially_copyable.hpp @@ -0,0 +1,95 @@ +/*============================================================================= + Copyright (c) 2018 Kohei Takahashi + + 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) +==============================================================================*/ +#ifndef BOOST_FUSION_SUPPORT_DETAIL_IS_TRIVIALLY_COPYABLE +#define BOOST_FUSION_SUPPORT_DETAIL_IS_TRIVIALLY_COPYABLE + +#include + +#if BOOST_WORKAROUND(BOOST_GCC, BOOST_TESTED_AT(90000)) + // GCC treats volatile qualified scalar type as non trivially copyable, + // so to be fail safe, we also treat it as non trivially copyable type. + // http://wg21.link/cwg2094 + // https://gcc.gnu.org/PR85679 +# define BOOST_FUSION_DETAIL_VOLATILE_SCALAR_IS_NON_TRIVIALLY_COPYABLE +#endif + +#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS +# include +#else +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +# include +# include +#endif +#ifdef BOOST_FUSION_DETAIL_VOLATILE_SCALAR_IS_NON_TRIVIALLY_COPYABLE +# include +# include +#endif +#endif // + +#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_FUSION_DETAIL_IS_TRIVIALLY_COPYABLE_CONFORMING 2 +#elif defined(BOOST_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_DECLTYPE) && \ + defined(BOOST_HAS_TRIVIAL_ASSIGN) && defined(BOOST_HAS_TRIVIAL_COPY) && \ + defined(BOOST_HAS_TRIVIAL_MOVE_ASSIGN) && defined(BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR) && \ + defined(BOOST_HAS_TRIVIAL_DESTRUCTOR) && defined(BOOST_TT_IS_CONSTRUCTIBLE_CONFORMING) +# define BOOST_FUSION_DETAIL_IS_TRIVIALLY_COPYABLE_CONFORMING 1 +#endif + +namespace boost { namespace fusion { namespace detail +{ + +#ifdef BOOST_NO_CXX11_HDR_TYPE_TRAITS +template +struct is_trivially_copyable_class + : mpl::bool_< + (has_trivial_copy::value || !is_copy_constructible::value) && + (has_trivial_assign::value || !is_copy_assignable::value) && +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + (has_trivial_move_constructor::value || !is_constructible::value) && + (has_trivial_move_assign::value || !is_assignable::value) && +#endif // rv-ref + (is_constructible::value || is_assignable::value) && + has_trivial_destructor::value + > { }; + +template +struct is_trivially_copyable_impl + : mpl::if_c::value +#ifdef BOOST_FUSION_DETAIL_VOLATILE_SCALAR_IS_NON_TRIVIALLY_COPYABLE + , mpl::not_ > +#else + , mpl::true_ +#endif + , is_trivially_copyable_class::type> >::type { }; +#endif // + +template +struct is_trivially_copyable +#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS + : std::is_trivially_copyable +#else + : is_trivially_copyable_impl::type> +#endif // +{ }; + +}}} // namespace boost::fusion::detail + +#endif + diff --git a/test/Jamfile b/test/Jamfile index 9289033c..00e7208b 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -268,6 +268,7 @@ project : [ requires cxx11_variadic_templates ] ] [ compile support/tag_of.cpp ] [ compile support/unused.cpp ] + [ compile support/is_trivially_copyable.cpp ] # [ compile-fail xxx.cpp ] diff --git a/test/support/is_trivially_copyable.cpp b/test/support/is_trivially_copyable.cpp new file mode 100644 index 00000000..d4c4ce84 --- /dev/null +++ b/test/support/is_trivially_copyable.cpp @@ -0,0 +1,219 @@ +/*============================================================================= + Copyright (c) 2018 Kohei Takahashi + 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 +#include + +#ifndef BOOST_FUSION_DETAIL_VOLATILE_SCALAR_IS_NON_TRIVIALLY_COPYABLE +# define BOOST_FUSION_ASSERT_WA BOOST_MPL_ASSERT +#else +# define BOOST_FUSION_ASSERT_WA BOOST_MPL_ASSERT_NOT +#endif + +#ifdef BOOST_FUSION_DETAIL_IS_TRIVIALLY_COPYABLE_CONFORMING +# define BOOST_FUSION_ASSERT_FALLBACK BOOST_MPL_ASSERT +#else +# define BOOST_FUSION_ASSERT_FALLBACK(cond) BOOST_MPL_ASSERT((mpl::true_)) +#endif + +using namespace boost; +using namespace boost::fusion::detail; + + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +#endif + +typedef int function_type(); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +#endif + +struct S; +typedef int (S::*member_type); +typedef int (S::*member_function_type)(); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + + +struct trivial { }; + +BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable)); +BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable)); +BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable)); +BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable)); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +#endif + + +struct user_provided_copy +{ + user_provided_copy(user_provided_copy const&); + user_provided_copy& operator=(user_provided_copy const&); +}; + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +#endif + + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +struct user_provided_move +{ + user_provided_move(user_provided_move const&); + user_provided_move& operator=(user_provided_move const&); +}; + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +#endif + + +struct user_provided_dtor +{ + ~user_provided_dtor(); +}; + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_MPL_ASSERT((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); +BOOST_FUSION_ASSERT_WA((is_trivially_copyable)); + +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +BOOST_MPL_ASSERT_NOT((is_trivially_copyable)); +#endif