Compare commits

...

2 Commits

Author SHA1 Message Date
4e57acbce7 Make fusion::pair trivially copyable if possible 2018-03-23 02:26:05 +09:00
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)
#define FUSION_PAIR_07222005_1203
#include <boost/fusion/support/config.hpp>
#include <iosfwd>
#include <utility>
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/support/detail/as_fusion_element.hpp>
#include <boost/config.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/fusion/support/detail/enabler.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_lvalue_reference.hpp>
#include <boost/type_traits/remove_cv_ref.hpp>
#if defined (BOOST_MSVC)
# pragma warning(push)
@ -33,54 +34,46 @@ namespace boost { namespace fusion
pair()
: 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
pair(typename detail::call_param<Second>::type val)
: second(val) {}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Second2>
BOOST_FUSION_GPU_ENABLED
pair(Second2&& val
, typename boost::disable_if<is_lvalue_reference<Second2> >::type* /* dummy */ = 0
, typename boost::enable_if<is_convertible<Second2, Second> >::type* /*dummy*/ = 0
) : second(BOOST_FUSION_FWD_ELEM(Second, val)) {}
pair(typename remove_cv_ref<Second>::type&& val)
: second(BOOST_FUSION_FWD_ELEM(Second, val)) {}
#endif
template <typename Second2>
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) {}
template <typename Second2>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair& operator=(pair<First, Second2> const& rhs)
{
second = rhs.second;
return *this;
}
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
pair& operator=(pair const& rhs)
typename disable_if<is_same<Second, Second2>, pair&>::type
operator=(pair<First, Second2> const& rhs)
{
second = rhs.second;
return *this;
}
#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
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;
}
#endif

View File

@ -255,6 +255,7 @@ project
[ run sequence/swap.cpp ]
[ compile support/is_sequence.cpp ]
[ compile support/pair_conversion.cpp ]
[ compile support/pair_deque.cpp ]
[ compile support/pair_list.cpp ]
[ compile support/pair_map.cpp ]
@ -266,6 +267,8 @@ project
[ compile support/and.cpp
: [ requires cxx11_variadic_templates ] ]
[ compile support/tag_of.cpp ]
[ compile support/pair_trivially_copyable.cpp
: [ requires cxx11_hdr_type_traits ] ]
# [ 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
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -10,15 +10,20 @@
using namespace boost::fusion;
template <typename C>
void copy()
void copy(C value)
{
pair<int, C> src;
pair<int, C> src(value);
pair<int, C> dest = src;
boost::ignore_unused(dest);
}
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*> >));