From cdb022fda2b72b47171dd743b823a8ef31258b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Wed, 5 Apr 2017 16:04:53 +0200 Subject: [PATCH] Fix ambiguous constructor calls for piecewise_construct and Boost vs std tuples --- include/boost/container/detail/pair.hpp | 61 +++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/include/boost/container/detail/pair.hpp b/include/boost/container/detail/pair.hpp index 4abff4b..4755e56 100644 --- a/include/boost/container/detail/pair.hpp +++ b/include/boost/container/detail/pair.hpp @@ -35,16 +35,62 @@ #include //pair #include -#include +#include namespace boost { namespace tuples { struct null_type; +template < + class T0, class T1, class T2, + class T3, class T4, class T5, + class T6, class T7, class T8, + class T9> +class tuple; + } //namespace tuples { } //namespace boost { +namespace boost { +namespace container { +namespace pair_impl { + +template +struct is_boost_tuple +{ + static const bool value = false; +}; + +template < + class T0, class T1, class T2, + class T3, class T4, class T5, + class T6, class T7, class T8, + class T9> +struct is_boost_tuple< boost::tuples::tuple > +{ + static const bool value = true; +}; + +template +struct disable_if_boost_tuple + : boost::container::container_detail::disable_if< is_boost_tuple > +{}; + +template +struct is_tuple_null +{ + static const bool value = false; +}; + +template<> +struct is_tuple_null +{ + static const bool value = true; +}; + +}}} + #if defined(BOOST_MSVC) && (_CPPLIB_VER == 520) //MSVC 2010 tuple marker namespace std { namespace tr1 { struct _Nil; }} @@ -236,7 +282,12 @@ struct pair BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ pair( piecewise_construct_t\ , BoostTuple p\ - , BoostTuple q)\ + , BoostTuple q\ + , typename container_detail::enable_if_c\ + < pair_impl::is_boost_tuple< BoostTuple >::value &&\ + !(pair_impl::is_tuple_null::value || pair_impl::is_tuple_null::value) \ + >::type* = 0\ + )\ : first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\ { (void)p; (void)q; }\ // @@ -254,7 +305,8 @@ struct pair { (void) t1; (void)t2; } public: - template class Tuple, class... Args1, class... Args2> + template< template class Tuple, class... Args1, class... Args2 + , class = typename pair_impl::disable_if_boost_tuple< Tuple >::type> pair(piecewise_construct_t, Tuple t1, Tuple t2) : pair(t1, t2, typename build_number_seq::type(), typename build_number_seq::type()) {} @@ -270,7 +322,8 @@ struct pair { (void)t; return T(::boost::forward(get(t))...); } public: - template class Tuple, class... Args1, class... Args2> + template< template class Tuple, class... Args1, class... Args2 + , class = typename pair_impl::disable_if_boost_tuple< Tuple >::type> pair(piecewise_construct_t, Tuple t1, Tuple t2) : first (build_from_args (::boost::move(t1))) , second (build_from_args(::boost::move(t2)))