Added utility for forcing to be non trivial copyable

This commit is contained in:
Kohei Takahashi
2018-05-07 23:17:25 +09:00
parent c7ba5595fc
commit b03d1e9458
5 changed files with 275 additions and 34 deletions

View File

@ -0,0 +1,37 @@
/*=============================================================================
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_PROPAGATE_TRIVIALNESS
#define BOOST_FUSION_SUPPORT_DETAIL_PROPAGATE_TRIVIALNESS
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/support/detail/and.hpp>
#include <boost/fusion/support/detail/is_trivially_copyable.hpp>
#include <boost/mpl/if.hpp>
namespace boost { namespace fusion { namespace detail
{
struct trivial_base { };
struct non_trivial_base
{
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
non_trivial_base(non_trivial_base const&) BOOST_NOEXCEPT { }
};
template <typename... T>
struct propagate_trivialness
: mpl::if_c<and_<is_trivially_copyable<T>...>::value
, trivial_base
, non_trivial_base
>::type
{ };
}}} // namespace boost::fusion::detail
#endif

View File

@ -269,6 +269,8 @@ project
[ compile support/tag_of.cpp ] [ compile support/tag_of.cpp ]
[ compile support/unused.cpp ] [ compile support/unused.cpp ]
[ compile support/is_trivially_copyable.cpp ] [ compile support/is_trivially_copyable.cpp ]
[ compile support/propagate_trivialness.cpp
: [ requires cxx11_variadic_templates ] ]
# [ compile-fail xxx.cpp ] # [ compile-fail xxx.cpp ]

View File

@ -8,18 +8,7 @@
#include <boost/fusion/support/detail/is_trivially_copyable.hpp> #include <boost/fusion/support/detail/is_trivially_copyable.hpp>
#include <boost/mpl/assert.hpp> #include <boost/mpl/assert.hpp>
#include "trivial.hpp"
#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;
using namespace boost::fusion::detail; using namespace boost::fusion::detail;
@ -81,9 +70,6 @@ BOOST_MPL_ASSERT_NOT((is_trivially_copyable<function_type volatile&&>));
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<function_type const volatile&&>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<function_type const volatile&&>));
#endif #endif
struct S;
typedef int (S::*member_type);
typedef int (S::*member_function_type)();
BOOST_MPL_ASSERT((is_trivially_copyable<member_type>)); BOOST_MPL_ASSERT((is_trivially_copyable<member_type>));
BOOST_MPL_ASSERT((is_trivially_copyable<member_type const>)); BOOST_MPL_ASSERT((is_trivially_copyable<member_type const>));
@ -96,8 +82,6 @@ BOOST_FUSION_ASSERT_WA((is_trivially_copyable<member_function_type volatile>));
BOOST_FUSION_ASSERT_WA((is_trivially_copyable<member_function_type const volatile>)); BOOST_FUSION_ASSERT_WA((is_trivially_copyable<member_function_type const volatile>));
struct trivial { };
BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable<trivial>)); BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable<trivial>));
BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable<trivial const>)); BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable<trivial const>));
BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable<trivial volatile>)); BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable<trivial volatile>));
@ -124,12 +108,6 @@ BOOST_MPL_ASSERT_NOT((is_trivially_copyable<trivial const volatile&&>));
#endif #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<user_provided_copy>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_copy>));
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_copy const>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_copy const>));
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_copy volatile>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_copy volatile>));
@ -157,12 +135,6 @@ BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_copy const volatile&&>
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #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<user_provided_move>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_move>));
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_move const>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_move const>));
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_move volatile>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_move volatile>));
@ -188,11 +160,6 @@ BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_move const volatile&&>
#endif #endif
struct user_provided_dtor
{
~user_provided_dtor();
};
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_dtor>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_dtor>));
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_dtor const>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_dtor const>));
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_dtor volatile>)); BOOST_MPL_ASSERT_NOT((is_trivially_copyable<user_provided_dtor volatile>));

View File

@ -0,0 +1,179 @@
/*=============================================================================
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 <boost/config.hpp>
#include <boost/fusion/support/detail/propagate_trivialness.hpp>
#include <boost/fusion/support/detail/is_trivially_copyable.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include "trivial.hpp"
using namespace boost;
using namespace boost::fusion::detail;
BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable<trivial_base>));
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<non_trivial_base>));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<int> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<int const> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<int volatile> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<int const volatile> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<int*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<int const*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<int volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<int const volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<int* const> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<int* volatile> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<int* const volatile> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int const&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int volatile&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int const volatile&> >));
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int const&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int volatile&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int const volatile&&> >));
#endif
BOOST_FUSION_ASSERT_FALLBACK((is_base_of<trivial_base, propagate_trivialness<trivial> >));
BOOST_FUSION_ASSERT_FALLBACK((is_base_of<trivial_base, propagate_trivialness<trivial const> >));
BOOST_FUSION_ASSERT_FALLBACK((is_base_of<trivial_base, propagate_trivialness<trivial volatile> >));
BOOST_FUSION_ASSERT_FALLBACK((is_base_of<trivial_base, propagate_trivialness<trivial const volatile> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<trivial*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<trivial const*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<trivial volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<trivial const volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<trivial* const> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<trivial* volatile> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<trivial* const volatile> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<trivial&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<trivial const&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<trivial volatile&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<trivial const volatile&> >));
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<trivial&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<trivial const&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<trivial volatile&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<trivial const volatile&&> >));
#endif
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy const> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy volatile> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy const volatile> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_copy*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_copy const*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_copy volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_copy const volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_copy* const> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<user_provided_copy* volatile> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<user_provided_copy* const volatile> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy const&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy volatile&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy const volatile&> >));
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy const&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy volatile&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_copy const volatile&&> >));
#endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move const> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move volatile> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move const volatile> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_move*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_move const*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_move volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_move const volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_move* const> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<user_provided_move* volatile> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<user_provided_move* const volatile> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move const&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move volatile&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move const volatile&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move const&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move volatile&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_move const volatile&&> >));
#endif
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor const> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor volatile> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor const volatile> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_dtor*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_dtor const*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_dtor volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_dtor const volatile*> >));
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<user_provided_dtor* const> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<user_provided_dtor* volatile> >));
BOOST_FUSION_ASSERT_WA((is_base_of<trivial_base, propagate_trivialness<user_provided_dtor* const volatile> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor const&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor volatile&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor const volatile&> >));
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor const&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor volatile&&> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<user_provided_dtor const volatile&&> >));
#endif
BOOST_MPL_ASSERT((is_base_of<trivial_base, propagate_trivialness<int, float, void*> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int, float&, void*> >));
BOOST_FUSION_ASSERT_FALLBACK((is_base_of<trivial_base, propagate_trivialness<int, float, trivial> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int, float, user_provided_copy> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int, float, user_provided_move> >));
BOOST_MPL_ASSERT((is_base_of<non_trivial_base, propagate_trivialness<int, float, user_provided_dtor> >));
struct S1 : private propagate_trivialness<int, float, void*> { };
BOOST_MPL_ASSERT((is_trivially_copyable<S1>));
struct S2 : private propagate_trivialness<int, float&, void*> { };
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<S2>));
struct S3 : private propagate_trivialness<int, float, trivial> { };
BOOST_FUSION_ASSERT_FALLBACK((is_trivially_copyable<S3>));
struct S4 : private propagate_trivialness<int, float, user_provided_copy> { };
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<S4>));
struct S5 : private propagate_trivialness<int, float, user_provided_move> { };
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<S5>));
struct S6 : private propagate_trivialness<int, float, user_provided_dtor> { };
BOOST_MPL_ASSERT_NOT((is_trivially_copyable<S6>));

56
test/support/trivial.hpp Normal file
View File

@ -0,0 +1,56 @@
/*=============================================================================
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 TRIVIAL_HPP
#define TRIVIAL_HPP
#include <boost/fusion/support/detail/is_trivially_copyable.hpp>
#include <boost/mpl/assert.hpp>
#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
struct S;
typedef int (S::*member_type);
typedef int (S::*member_function_type)();
struct trivial { };
struct user_provided_copy
{
user_provided_copy(user_provided_copy const&);
user_provided_copy& operator=(user_provided_copy const&);
};
#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&);
};
#endif
struct user_provided_dtor
{
~user_provided_dtor();
};
#endif