Workaround for MSVC compilers, that fail to properly handle template specializations with constness subtleties.

This commit is contained in:
Ion Gaztañaga
2014-08-03 22:08:59 +02:00
parent fab3df0a04
commit 03582c4498
2 changed files with 39 additions and 21 deletions

View File

@@ -23,6 +23,7 @@
#include <boost/aligned_storage.hpp> #include <boost/aligned_storage.hpp>
#include <boost/move/utility.hpp> #include <boost/move/utility.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <iterator> //std::iterator_traits #include <iterator> //std::iterator_traits
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/detail/no_exceptions_support.hpp> #include <boost/detail/no_exceptions_support.hpp>
@@ -280,6 +281,20 @@ struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_tr
{} {}
}; };
//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
//compiler error C2752 (<28>more than one partial specialization matches<65>).
//Any problem is solvable with an extra layer of indirection? ;-)
template<class A, class Iterator>
struct insert_emplace_proxy<A, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type
>
: public insert_copy_proxy<A, Iterator>
{
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
{}
};
template<class A, class Iterator> template<class A, class Iterator>
struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_traits<A>::value_type &> struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_traits<A>::value_type &>
: public insert_copy_proxy<A, Iterator> : public insert_copy_proxy<A, Iterator>
@@ -290,7 +305,9 @@ struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_tr
}; };
template<class A, class Iterator> template<class A, class Iterator>
struct insert_emplace_proxy<A, Iterator, const typename boost::container::allocator_traits<A>::value_type &> struct insert_emplace_proxy<A, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type &
>
: public insert_copy_proxy<A, Iterator> : public insert_copy_proxy<A, Iterator>
{ {
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v) explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
@@ -298,16 +315,6 @@ struct insert_emplace_proxy<A, Iterator, const typename boost::container::alloca
{} {}
}; };
template<class A, class Iterator>
struct insert_emplace_proxy<A, Iterator, const typename boost::container::allocator_traits<A>::value_type>
: public insert_copy_proxy<A, Iterator>
{
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
{}
};
}}} //namespace boost { namespace container { namespace container_detail { }}} //namespace boost { namespace container { namespace container_detail {
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -419,6 +426,20 @@ struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocat
{} {}
}; };
//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
//compiler error C2752 (<28>more than one partial specialization matches<65>).
//Any problem is solvable with an extra layer of indirection? ;-)
template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type
>
: public insert_copy_proxy<A, Iterator>
{
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
{}
};
template<class A, class Iterator> template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type &> struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type &>
: public insert_copy_proxy<A, Iterator> : public insert_copy_proxy<A, Iterator>
@@ -429,16 +450,9 @@ struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocat
}; };
template<class A, class Iterator> template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, const typename boost::container::allocator_traits<A>::value_type &> struct insert_emplace_proxy_arg1<A, Iterator
: public insert_copy_proxy<A, Iterator> , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type &
{ >
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
{}
};
template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, const typename boost::container::allocator_traits<A>::value_type>
: public insert_copy_proxy<A, Iterator> : public insert_copy_proxy<A, Iterator>
{ {
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v) explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)

View File

@@ -165,6 +165,10 @@ template <class T>
struct add_const_reference<T&> struct add_const_reference<T&>
{ typedef T& type; }; { typedef T& type; };
template <class T>
struct add_const
{ typedef const T type; };
template <typename T, typename U> template <typename T, typename U>
struct is_same struct is_same
{ {