Compare commits

...

2 Commits

Author SHA1 Message Date
Kohei Takahashi
4e57acbce7 Make fusion::pair trivially copyable if possible 2018-03-23 02:26:05 +09:00
Kohei Takahashi
44ef9e56e6 Added tests for support/pair 2018-03-23 02:25:38 +09:00
5 changed files with 128 additions and 35 deletions

View File

@@ -8,15 +8,16 @@
#if !defined(FUSION_PAIR_07222005_1203) #if !defined(FUSION_PAIR_07222005_1203)
#define FUSION_PAIR_07222005_1203 #define FUSION_PAIR_07222005_1203
#include <boost/fusion/support/config.hpp>
#include <iosfwd> #include <iosfwd>
#include <utility>
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/support/detail/as_fusion_element.hpp> #include <boost/fusion/support/detail/as_fusion_element.hpp>
#include <boost/config.hpp> #include <boost/fusion/support/detail/enabler.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp> #include <boost/type_traits/remove_cv_ref.hpp>
#if defined (BOOST_MSVC) #if defined (BOOST_MSVC)
# pragma warning(push) # pragma warning(push)
@@ -33,54 +34,46 @@ namespace boost { namespace fusion
pair() pair()
: second() {} : second() {}
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair(pair const& rhs)
: second(rhs.second) {}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair(pair&& rhs)
: second(BOOST_FUSION_FWD_ELEM(Second, rhs.second)) {}
#endif
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair(typename detail::call_param<Second>::type val) pair(typename detail::call_param<Second>::type val)
: second(val) {} : second(val) {}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Second2>
BOOST_FUSION_GPU_ENABLED BOOST_FUSION_GPU_ENABLED
pair(Second2&& val pair(typename remove_cv_ref<Second>::type&& val)
, typename boost::disable_if<is_lvalue_reference<Second2> >::type* /* dummy */ = 0 : second(BOOST_FUSION_FWD_ELEM(Second, val)) {}
, typename boost::enable_if<is_convertible<Second2, Second> >::type* /*dummy*/ = 0
) : second(BOOST_FUSION_FWD_ELEM(Second, val)) {}
#endif #endif
template <typename Second2> template <typename Second2>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair(pair<First, Second2> const& rhs) pair(pair<First, Second2> const& rhs,
typename disable_if<is_same<Second, Second2>, detail::enabler_>::type = detail::enabler,
typename enable_if<is_convertible<Second2, Second>, detail::enabler_>::type = detail::enabler)
: second(rhs.second) {} : second(rhs.second) {}
template <typename Second2> template <typename Second2>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair& operator=(pair<First, Second2> const& rhs) typename disable_if<is_same<Second, Second2>, pair&>::type
{ operator=(pair<First, Second2> const& rhs)
second = rhs.second;
return *this;
}
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair& operator=(pair const& rhs)
{ {
second = rhs.second; second = rhs.second;
return *this; return *this;
} }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Second2>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair(pair<First, Second2>&& rhs,
typename disable_if<is_same<Second, Second2>, detail::enabler_>::type = detail::enabler,
typename enable_if<is_convertible<Second2, Second>, detail::enabler_>::type = detail::enabler)
: second(std::move(rhs.second)) {}
template <typename Second2>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair& operator=(pair&& rhs) typename disable_if<is_same<Second, Second2>, pair&>::type
operator=(pair<First, Second2>&& rhs)
{ {
second = BOOST_FUSION_FWD_ELEM(Second, rhs.second); second = std::move(rhs.second);
return *this; return *this;
} }
#endif #endif

View File

@@ -255,6 +255,7 @@ project
[ run sequence/swap.cpp ] [ run sequence/swap.cpp ]
[ compile support/is_sequence.cpp ] [ compile support/is_sequence.cpp ]
[ compile support/pair_conversion.cpp ]
[ compile support/pair_deque.cpp ] [ compile support/pair_deque.cpp ]
[ compile support/pair_list.cpp ] [ compile support/pair_list.cpp ]
[ compile support/pair_map.cpp ] [ compile support/pair_map.cpp ]
@@ -266,6 +267,8 @@ project
[ compile support/and.cpp [ compile support/and.cpp
: [ requires cxx11_variadic_templates ] ] : [ requires cxx11_variadic_templates ] ]
[ compile support/tag_of.cpp ] [ compile support/tag_of.cpp ]
[ compile support/pair_trivially_copyable.cpp
: [ requires cxx11_hdr_type_traits ] ]
# [ compile-fail xxx.cpp ] # [ compile-fail xxx.cpp ]

View File

@@ -0,0 +1,42 @@
/*=============================================================================
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 <utility>
#include <boost/config.hpp>
#include <boost/fusion/support/pair.hpp>
using namespace boost::fusion;
struct eat_int
{
eat_int(int);
};
struct eat_pair
{
template <typename K, typename V>
eat_pair(pair<K, V>);
};
int main()
{
pair<void, int> p;
pair<void, eat_int> ci(p);
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
pair<void, eat_int> mi(std::move(p));
#endif
// eat_pair can't be converted from int, but can be pair.
// So pair(eat_pair) should be called rather than pair(pair<void, eat_pair>).
pair<void, eat_pair> cp(p);
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
pair<void, eat_pair> mp(std::move(p));
#endif
}

View File

@@ -1,5 +1,5 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2015 Kohei Takahashi Copyright (c) 2015,2018 Kohei Takahashi
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,15 +10,20 @@
using namespace boost::fusion; using namespace boost::fusion;
template <typename C> template <typename C>
void copy() void copy(C value)
{ {
pair<int, C> src; pair<int, C> src(value);
pair<int, C> dest = src; pair<int, C> dest = src;
boost::ignore_unused(dest); boost::ignore_unused(dest);
} }
int main() int main()
{ {
copy<pair<void, float> >(); copy<pair<void, float> >(42.195f);
copy<pair<int, float> >(42.195f);
float f;
pair<void, float&> r(f);
copy<pair<void, float&> >(r);
} }

View File

@@ -0,0 +1,50 @@
/*=============================================================================
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 <type_traits>
#include <boost/fusion/support/pair.hpp>
#include <boost/mpl/assert.hpp>
using namespace boost::fusion;
struct non_trivially_copyable
{
non_trivially_copyable(const non_trivially_copyable&);
non_trivially_copyable operator=(const non_trivially_copyable&);
};
struct pod { };
BOOST_MPL_ASSERT_NOT((std::is_trivially_copyable<void>));
BOOST_MPL_ASSERT((std::is_trivially_copyable<int>));
BOOST_MPL_ASSERT_NOT((std::is_trivially_copyable<non_trivially_copyable>));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pod>));
BOOST_MPL_ASSERT_NOT((std::is_trivially_copyable<int&>));
BOOST_MPL_ASSERT((std::is_trivially_copyable<void*>));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<void, int> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, int> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<non_trivially_copyable, int> >));
BOOST_MPL_ASSERT_NOT((std::is_trivially_copyable<pair<int, non_trivially_copyable> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<pod, int> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, pod> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<void, int&> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, int&> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<non_trivially_copyable, int&> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, non_trivially_copyable&> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, pod&> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, pod&> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<void, int*> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, int*> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<non_trivially_copyable, int*> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, non_trivially_copyable*> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, pod*> >));
BOOST_MPL_ASSERT((std::is_trivially_copyable<pair<int, pod*> >));