Fixes Issue #97

This commit is contained in:
Ion Gaztañaga
2019-01-07 00:38:15 +01:00
parent a9ceb4d9c6
commit 2b5197a5cb
2 changed files with 84 additions and 18 deletions

View File

@@ -1246,6 +1246,7 @@ use [*Boost.Container]? There are several reasons for that:
* Removed support for already deprecated GCC < 4.3 and MSVC < 9.0 (Visual 2008) compilers. * Removed support for already deprecated GCC < 4.3 and MSVC < 9.0 (Visual 2008) compilers.
* Fixed bugs: * Fixed bugs:
* [@https://github.com/boostorg/container/pull/96 GitHub #96: ['"Workaround: Intel compilers do not offer CTAD yet"]]. * [@https://github.com/boostorg/container/pull/96 GitHub #96: ['"Workaround: Intel compilers do not offer CTAD yet"]].
* [@https://github.com/boostorg/container/issues/97 GitHub #97: ['"buffer overflow in boost::container::flat_map on FreeBSD"]].
[endsect] [endsect]

View File

@@ -24,6 +24,7 @@
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/static_assert.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
@@ -188,8 +189,36 @@ void get(T); //to enable ADL
///@endcond ///@endcond
#ifdef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
//Libc++, in some versions, has an ABI breakage that needs some
//padding in dtl::pair, as "std::pair::first" is not at offset zero.
//See: https://reviews.llvm.org/D56357 for more information.
//
template <class T1, class T2, std::size_t N>
struct pair_padding
{
char padding[N];
};
template <class T1, class T2>
struct pair_padding<T1, T2, 0>
{
};
template <class T1, class T2>
struct simple_pair
{
T1 first;
T2 second;
};
#endif
template <class T1, class T2> template <class T1, class T2>
struct pair struct pair
#ifdef _LIBCPP_VERSION
: pair_padding<T1, T2, sizeof(std::pair<T1, T2>) - sizeof(simple_pair<T1, T2>)>
#endif
{ {
private: private:
BOOST_COPYABLE_AND_MOVABLE(pair) BOOST_COPYABLE_AND_MOVABLE(pair)
@@ -204,64 +233,88 @@ struct pair
//Default constructor //Default constructor
pair() pair()
: first(), second() : first(), second()
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
//pair copy assignment //pair copy assignment
pair(const pair& x) pair(const pair& x)
: first(x.first), second(x.second) : first(x.first), second(x.second)
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
//pair move constructor //pair move constructor
pair(BOOST_RV_REF(pair) p) pair(BOOST_RV_REF(pair) p)
: first(::boost::move(p.first)), second(::boost::move(p.second)) : first(::boost::move(p.first)), second(::boost::move(p.second))
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
template <class D, class S> template <class D, class S>
pair(const pair<D, S> &p) pair(const pair<D, S> &p)
: first(p.first), second(p.second) : first(p.first), second(p.second)
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
template <class D, class S> template <class D, class S>
pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p) pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second)) : first(::boost::move(p.first)), second(::boost::move(p.second))
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
//pair from two values //pair from two values
pair(const T1 &t1, const T2 &t2) pair(const T1 &t1, const T2 &t2)
: first(t1) : first(t1)
, second(t2) , second(t2)
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
template<class U, class V> template<class U, class V>
pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v) pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
: first(::boost::forward<U>(u)) : first(::boost::forward<U>(u))
, second(::boost::forward<V>(v)) , second(::boost::forward<V>(v))
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
//And now compatibility with std::pair //And now compatibility with std::pair
pair(const std::pair<T1, T2>& x) pair(const std::pair<T1, T2>& x)
: first(x.first), second(x.second) : first(x.first), second(x.second)
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
template <class D, class S> template <class D, class S>
pair(const std::pair<D, S>& p) pair(const std::pair<D, S>& p)
: first(p.first), second(p.second) : first(p.first), second(p.second)
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p) pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second)) : first(::boost::move(p.first)), second(::boost::move(p.second))
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
template <class D, class S> template <class D, class S>
pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p) pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second)) : first(::boost::move(p.first)), second(::boost::move(p.second))
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template< class KeyType, class ...Args> template< class KeyType, class ...Args>
pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args) pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args)
: first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\ : first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
#else #else
//piecewise construction from boost::tuple //piecewise construction from boost::tuple
@@ -269,7 +322,9 @@ struct pair
template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\ pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
: first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\ : first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\
{}\ {\
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
}\
// //
BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE) BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE)
#undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE #undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE
@@ -289,7 +344,9 @@ struct pair
>::type* = 0\ >::type* = 0\
)\ )\
: first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\ : first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\
{ (void)p; (void)q; }\ { (void)p; (void)q;\
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
}\
// //
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE) BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
@@ -309,7 +366,9 @@ struct pair
, class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type> , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2) pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
: pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type()) : pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type())
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
# else # else
//piecewise construction from variadic tuple (suboptimal, without delegating constructors) //piecewise construction from variadic tuple (suboptimal, without delegating constructors)
private: private:
@@ -327,7 +386,9 @@ struct pair
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2) pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
: first (build_from_args<first_type> (::boost::move(t1))) : first (build_from_args<first_type> (::boost::move(t1)))
, second (build_from_args<second_type>(::boost::move(t2))) , second (build_from_args<second_type>(::boost::move(t2)))
{} {
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
}
# endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES # endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520) #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
//MSVC 2010 tuple implementation //MSVC 2010 tuple implementation
@@ -338,7 +399,9 @@ struct pair
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\ , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\ , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\ : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
{ (void)p; (void)q; }\ { (void)p; (void)q;\
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
}\
// //
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE) BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
@@ -357,7 +420,9 @@ struct pair
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\ , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\ , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\ : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
{ (void)p; (void)q; }\ { (void)p; (void)q;\
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
}\
// //
BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE) BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE