mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Complete support for user-provided containers to flat_[multi]map/set containers, and instantiate them with several container types.
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2017-2017. 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)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
||||||
|
#define BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
||||||
|
|
||||||
|
#ifndef BOOST_CONFIG_HPP
|
||||||
|
# include <boost/config.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/container/allocator_traits.hpp>
|
||||||
|
#include <boost/container/detail/container_rebind.hpp>
|
||||||
|
#include <boost/container/detail/is_container.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace container {
|
||||||
|
namespace container_detail {
|
||||||
|
|
||||||
|
template<class AllocatorOrContainer, class ToType, bool = is_container<AllocatorOrContainer>::value>
|
||||||
|
struct container_or_allocator_rebind_impl
|
||||||
|
: container_rebind<AllocatorOrContainer, ToType>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<class AllocatorOrContainer, class ToType>
|
||||||
|
struct container_or_allocator_rebind_impl<AllocatorOrContainer, ToType, false>
|
||||||
|
: allocator_traits<AllocatorOrContainer>::template portable_rebind_alloc<ToType>
|
||||||
|
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<class AllocatorOrContainer, class ToType>
|
||||||
|
struct container_or_allocator_rebind
|
||||||
|
: container_or_allocator_rebind_impl<AllocatorOrContainer, ToType>
|
||||||
|
{};
|
||||||
|
|
||||||
|
} //namespace container_detail {
|
||||||
|
} //namespace container {
|
||||||
|
} //namespace boost {
|
||||||
|
|
||||||
|
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
258
include/boost/container/detail/container_rebind.hpp
Normal file
258
include/boost/container/detail/container_rebind.hpp
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2017-2017. 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)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
|
||||||
|
#define BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
|
||||||
|
|
||||||
|
#ifndef BOOST_CONFIG_HPP
|
||||||
|
# include <boost/config.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/container/allocator_traits.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace container {
|
||||||
|
namespace container_detail {
|
||||||
|
|
||||||
|
template <class Cont, class U>
|
||||||
|
struct container_rebind;
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <template <class, class, class...> class Cont, typename V, typename A, class... An, class U>
|
||||||
|
struct container_rebind<Cont<V, A, An...>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, An...> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Needed for non-conforming compilers like GCC 4.3
|
||||||
|
template <template <class, class> class Cont, typename V, typename A, class U>
|
||||||
|
struct container_rebind<Cont<V, A>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class> class Cont, typename V, class U>
|
||||||
|
struct container_rebind<Cont<V>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//for small_vector,static_vector
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class...> class Cont, typename V, std::size_t N, typename A, class... An, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, An...>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, An...> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Needed for non-conforming compilers like GCC 4.3
|
||||||
|
template <template <class, std::size_t, class> class Cont, typename V, std::size_t N, typename A, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t> class Cont, typename V, std::size_t N, class U>
|
||||||
|
struct container_rebind<Cont<V, N>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else //C++03 compilers
|
||||||
|
|
||||||
|
template <template <class> class Cont //0arg
|
||||||
|
, typename V
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class> class Cont //0arg
|
||||||
|
, typename V, typename A
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class> class Cont //1arg
|
||||||
|
, typename V, typename A, class P0
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class, class> class Cont //2arg
|
||||||
|
, typename V, typename A, class P0, class P1
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0, P1>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class, class, class> class Cont //3arg
|
||||||
|
, typename V, typename A, class P0, class P1, class P2
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0, P1, P2>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class, class, class, class> class Cont //4arg
|
||||||
|
, typename V, typename A, class P0, class P1, class P2, class P3
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0, P1, P2, P3>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class, class, class, class, class> class Cont //5arg
|
||||||
|
, typename V, typename A, class P0, class P1, class P2, class P3, class P4
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class, class, class, class, class, class> class Cont //6arg
|
||||||
|
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class, class, class, class, class, class, class> class Cont //7arg
|
||||||
|
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class, class, class, class, class, class, class, class> class Cont //8arg
|
||||||
|
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, class, class, class, class, class, class, class, class, class, class> class Cont //9arg
|
||||||
|
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//For small_vector/static_vector
|
||||||
|
template <template <class, std::size_t> class Cont //0arg
|
||||||
|
, typename V, std::size_t N
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class> class Cont //0arg
|
||||||
|
, typename V, std::size_t N, typename A
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class> class Cont //1arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class, class> class Cont //2arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0, class P1
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0, P1>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class, class, class> class Cont //3arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0, class P1, class P2
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0, P1, P2>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class, class, class, class> class Cont //4arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0, P1, P2, P3>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class, class, class, class, class> class Cont //5arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class, class, class, class, class, class> class Cont //6arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class, class, class, class, class, class, class> class Cont //7arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class, class, class, class, class, class, class, class> class Cont //8arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6, P7>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <class, std::size_t, class, class, class, class, class, class, class, class, class, class> class Cont //9arg
|
||||||
|
, typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
|
||||||
|
, class U>
|
||||||
|
struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U>
|
||||||
|
{
|
||||||
|
typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
} //namespace container_detail {
|
||||||
|
} //namespace container {
|
||||||
|
} //namespace boost {
|
||||||
|
|
||||||
|
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
|
@@ -86,60 +86,87 @@
|
|||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
|
||||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||||
|
|
||||||
|
//reserve
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME reserve
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
|
||||||
|
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||||
|
|
||||||
|
//capacity
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME capacity
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
||||||
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
||||||
|
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||||
|
|
||||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace container {
|
namespace container {
|
||||||
namespace container_detail {
|
namespace container_detail {
|
||||||
|
|
||||||
|
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(stored_allocator_type)
|
||||||
|
|
||||||
template<class SequenceContainer, class Iterator, class Compare>
|
template<class SequenceContainer, class Iterator, class Compare>
|
||||||
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal
|
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal
|
||||||
(SequenceContainer& dest, Iterator begin, Iterator end, Compare comp, container_detail::false_)
|
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, container_detail::true_)
|
||||||
|
{
|
||||||
|
dest.merge(first, last, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer, class Iterator, class Compare>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal_non_merge_member
|
||||||
|
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, container_detail::true_)
|
||||||
{
|
{
|
||||||
typedef typename SequenceContainer::iterator iterator;
|
typedef typename SequenceContainer::iterator iterator;
|
||||||
typedef typename SequenceContainer::value_type value_type;
|
typedef typename SequenceContainer::value_type value_type;
|
||||||
|
|
||||||
iterator it = dest.insert( dest.end(), boost::make_move_iterator(begin), boost::make_move_iterator(end) );
|
iterator const it = dest.insert( dest.end(), first, last );
|
||||||
|
value_type *const braw = boost::movelib::iterator_to_raw_pointer(dest.begin());
|
||||||
if (is_contiguous_container<SequenceContainer>::value){
|
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
|
||||||
value_type *const braw = boost::movelib::iterator_to_raw_pointer(dest.begin());
|
value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end());
|
||||||
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
|
value_type *const sraw = boost::movelib::iterator_to_raw_pointer(dest.begin()+dest.size());
|
||||||
value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end());
|
boost::movelib::adaptive_sort(iraw, eraw, comp, sraw, dest.capacity());
|
||||||
value_type *const sraw = boost::movelib::iterator_to_raw_pointer(dest.begin()+dest.size());
|
boost::movelib::adaptive_merge(braw, iraw, eraw, comp, sraw, dest.capacity()- dest.size());
|
||||||
boost::movelib::adaptive_sort(iraw, eraw, comp, sraw, dest.capacity());
|
|
||||||
boost::movelib::adaptive_merge(braw, iraw, eraw, comp, sraw, dest.capacity()- dest.size());
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
boost::movelib::adaptive_sort(it, dest.end(), comp);
|
|
||||||
boost::movelib::adaptive_merge(dest.begin(), it, dest.end(), comp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SequenceContainer, class Iterator, class Compare>
|
template<class SequenceContainer, class Iterator, class Compare>
|
||||||
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique
|
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal_non_merge_member
|
||||||
(SequenceContainer& dest, Iterator begin, Iterator end, Compare comp, container_detail::false_)
|
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, container_detail::false_)
|
||||||
{
|
{
|
||||||
(flat_tree_merge_equal)(dest, begin, end, comp, container_detail::false_());
|
typedef typename SequenceContainer::iterator iterator;
|
||||||
dest.erase(boost::movelib::unique
|
|
||||||
(dest.begin(), dest.end(), boost::movelib::negate<Compare>(comp)), dest.cend());
|
iterator const it = dest.insert( dest.end(), first, last );
|
||||||
|
boost::movelib::adaptive_sort(it, dest.end(), comp);
|
||||||
|
boost::movelib::adaptive_merge(dest.begin(), it, dest.end(), comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SequenceContainer, class Iterator, class Compare>
|
template<class SequenceContainer, class Iterator, class Compare>
|
||||||
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal
|
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal
|
||||||
(SequenceContainer& dest, Iterator begin, Iterator end, Compare comp, container_detail::true_)
|
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, container_detail::false_)
|
||||||
{
|
{
|
||||||
dest.merge(begin, end, comp);
|
(flat_tree_merge_equal_non_merge_member)( dest, first, last, comp
|
||||||
|
, container_detail::bool_<is_contiguous_container<SequenceContainer>::value>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SequenceContainer, class Iterator, class Compare>
|
template<class SequenceContainer, class Iterator, class Compare>
|
||||||
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique
|
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique
|
||||||
(SequenceContainer& dest, Iterator begin, Iterator end, Compare comp, container_detail::true_)
|
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, container_detail::true_)
|
||||||
{
|
{
|
||||||
dest.merge_unique(begin, end, comp);
|
dest.merge_unique(first, last, comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(stored_allocator_type)
|
template<class SequenceContainer, class Iterator, class Compare>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique
|
||||||
|
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, container_detail::false_)
|
||||||
|
{
|
||||||
|
(flat_tree_merge_equal)(dest, first, last, comp, container_detail::false_());
|
||||||
|
dest.erase(boost::movelib::unique
|
||||||
|
(dest.begin(), dest.end(), boost::movelib::negate<Compare>(comp)), dest.cend());
|
||||||
|
}
|
||||||
|
|
||||||
template<class SequenceContainer, class Iterator>
|
template<class SequenceContainer, class Iterator>
|
||||||
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
|
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
|
||||||
@@ -192,12 +219,83 @@ BOOST_CONTAINER_FORCEINLINE const typename SequenceContainer::stored_allocator_t
|
|||||||
|
|
||||||
template<class SequenceContainer>
|
template<class SequenceContainer>
|
||||||
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::allocator_type
|
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::allocator_type
|
||||||
flat_tree_get_stored_allocator
|
flat_tree_get_stored_allocator
|
||||||
(SequenceContainer& cont, container_detail::false_)
|
(SequenceContainer& cont, container_detail::false_)
|
||||||
{
|
{
|
||||||
return cont.get_allocator();
|
return cont.get_allocator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer, class Compare>
|
||||||
|
void flat_tree_adopt_sequence_equal(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, container_detail::true_)
|
||||||
|
{
|
||||||
|
tseq.clear();
|
||||||
|
boost::movelib::adaptive_sort
|
||||||
|
(boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||||
|
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||||
|
, comp
|
||||||
|
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
||||||
|
, tseq.capacity() - tseq.size());
|
||||||
|
tseq = boost::move(seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer, class Compare>
|
||||||
|
void flat_tree_adopt_sequence_equal(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, container_detail::false_)
|
||||||
|
{
|
||||||
|
boost::movelib::adaptive_sort(seq.begin(), seq.end(), comp);
|
||||||
|
tseq = boost::move(seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer, class Compare>
|
||||||
|
void flat_tree_adopt_sequence_unique(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, container_detail::true_)
|
||||||
|
{
|
||||||
|
boost::movelib::adaptive_sort
|
||||||
|
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||||
|
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||||
|
, comp
|
||||||
|
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
||||||
|
, tseq.capacity() - tseq.size());
|
||||||
|
seq.erase(boost::movelib::unique
|
||||||
|
( seq.begin(), seq.end(), boost::movelib::negate<Compare>(comp))
|
||||||
|
, seq.cend());
|
||||||
|
tseq = boost::move(seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer, class Compare>
|
||||||
|
void flat_tree_adopt_sequence_unique(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, container_detail::false_)
|
||||||
|
{
|
||||||
|
boost::movelib::adaptive_sort(seq.begin(), seq.end(), comp);
|
||||||
|
seq.erase(boost::movelib::unique
|
||||||
|
(seq.begin(), seq.end(), boost::movelib::negate<Compare>(comp)), seq.cend());
|
||||||
|
tseq = boost::move(seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE void
|
||||||
|
flat_tree_reserve(SequenceContainer &tseq, typename SequenceContainer::size_type cap, container_detail::true_)
|
||||||
|
{
|
||||||
|
tseq.reserve(cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE void
|
||||||
|
flat_tree_reserve(SequenceContainer &, typename SequenceContainer::size_type, container_detail::false_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
|
||||||
|
flat_tree_capacity(const SequenceContainer &tseq, container_detail::true_)
|
||||||
|
{
|
||||||
|
return tseq.capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SequenceContainer>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
|
||||||
|
flat_tree_capacity(const SequenceContainer &tseq, container_detail::false_)
|
||||||
|
{
|
||||||
|
return tseq.size();
|
||||||
|
}
|
||||||
|
|
||||||
template<class Compare, class Value, class KeyOfValue>
|
template<class Compare, class Value, class KeyOfValue>
|
||||||
class flat_tree_value_compare
|
class flat_tree_value_compare
|
||||||
: private Compare
|
: private Compare
|
||||||
@@ -268,6 +366,7 @@ class flat_tree
|
|||||||
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
|
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct Data
|
struct Data
|
||||||
//Inherit from value_compare to do EBO
|
//Inherit from value_compare to do EBO
|
||||||
: public value_compare
|
: public value_compare
|
||||||
@@ -1088,10 +1187,18 @@ class flat_tree
|
|||||||
{ return this->priv_lower_bound_range(this->cbegin(), this->cend(), k); }
|
{ return this->priv_lower_bound_range(this->cbegin(), this->cend(), k); }
|
||||||
|
|
||||||
BOOST_CONTAINER_FORCEINLINE size_type capacity() const
|
BOOST_CONTAINER_FORCEINLINE size_type capacity() const
|
||||||
{ return this->m_data.m_seq.capacity(); }
|
{
|
||||||
|
const bool value = boost::container::container_detail::
|
||||||
|
has_member_function_callable_with_capacity<container_type>::value;
|
||||||
|
return (flat_tree_capacity)(this->m_data.m_seq, container_detail::bool_<value>());
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
|
BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
|
||||||
{ this->m_data.m_seq.reserve(cnt); }
|
{
|
||||||
|
const bool value = boost::container::container_detail::
|
||||||
|
has_member_function_callable_with_reserve<container_type, size_type>::value;
|
||||||
|
(flat_tree_reserve)(this->m_data.m_seq, cnt, container_detail::bool_<value>());
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_CONTAINER_FORCEINLINE container_type extract_sequence()
|
BOOST_CONTAINER_FORCEINLINE container_type extract_sequence()
|
||||||
{
|
{
|
||||||
@@ -1103,57 +1210,28 @@ class flat_tree
|
|||||||
return m_data.m_seq;
|
return m_data.m_seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adopt_sequence_equal(BOOST_RV_REF(container_type) seq)
|
BOOST_CONTAINER_FORCEINLINE void adopt_sequence_equal(BOOST_RV_REF(container_type) seq)
|
||||||
{
|
{
|
||||||
container_type &tseq = m_data.m_seq;
|
(flat_tree_adopt_sequence_equal)( m_data.m_seq, boost::move(seq), this->priv_value_comp()
|
||||||
if (is_contiguous_container<container_type>::value){
|
, container_detail::bool_<is_contiguous_container<container_type>::value>());
|
||||||
boost::movelib::adaptive_sort
|
|
||||||
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
|
||||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
|
||||||
, this->priv_value_comp()
|
|
||||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
|
||||||
, tseq.capacity() - tseq.size());
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
boost::movelib::adaptive_sort
|
|
||||||
(seq.begin(), seq.end(), this->priv_value_comp());
|
|
||||||
}
|
|
||||||
tseq = boost::move(seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void adopt_sequence_unique(BOOST_RV_REF(container_type) seq)
|
BOOST_CONTAINER_FORCEINLINE void adopt_sequence_unique(BOOST_RV_REF(container_type) seq)
|
||||||
{
|
{
|
||||||
container_type &tseq = m_data.m_seq;
|
(flat_tree_adopt_sequence_unique)(m_data.m_seq, boost::move(seq), this->priv_value_comp()
|
||||||
if (is_contiguous_container<container_type>::value){
|
, container_detail::bool_<is_contiguous_container<container_type>::value>());
|
||||||
boost::movelib::adaptive_sort
|
|
||||||
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
|
||||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
|
||||||
, this->priv_value_comp()
|
|
||||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
|
||||||
, tseq.capacity() - tseq.size());
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
boost::movelib::adaptive_sort
|
|
||||||
( seq.begin(), seq.end(), this->priv_value_comp());
|
|
||||||
}
|
|
||||||
seq.erase( boost::movelib::unique
|
|
||||||
(seq.begin(), seq.end(), boost::movelib::negate<value_compare>(this->m_data.get_comp()))
|
|
||||||
, seq.cend());
|
|
||||||
tseq = boost::move(seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void adopt_sequence_equal(ordered_range_t, BOOST_RV_REF(container_type) seq)
|
void adopt_sequence_equal(ordered_range_t, BOOST_RV_REF(container_type) seq)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT((is_sorted)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
BOOST_ASSERT((is_sorted)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
||||||
container_type &tseq = m_data.m_seq;
|
m_data.m_seq = boost::move(seq);
|
||||||
tseq = boost::move(seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void adopt_sequence_unique(ordered_unique_range_t, BOOST_RV_REF(container_type) seq)
|
void adopt_sequence_unique(ordered_unique_range_t, BOOST_RV_REF(container_type) seq)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT((is_sorted_and_unique)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
BOOST_ASSERT((is_sorted_and_unique)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
||||||
container_type &tseq = m_data.m_seq;
|
m_data.m_seq = boost::move(seq);
|
||||||
tseq = boost::move(seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_tree& x, const flat_tree& y)
|
BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_tree& x, const flat_tree& y)
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#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>
|
||||||
#include <boost/container/detail/algorithm.hpp> //equal()
|
#include <boost/container/detail/algorithm.hpp> //equal()
|
||||||
|
#include <boost/container/detail/container_or_allocator_rebind.hpp>
|
||||||
// move
|
// move
|
||||||
#include <boost/move/utility_core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
#include <boost/move/traits.hpp>
|
#include <boost/move/traits.hpp>
|
||||||
@@ -125,8 +126,8 @@ class flat_map
|
|||||||
container_detail::pair<Key, T>,
|
container_detail::pair<Key, T>,
|
||||||
container_detail::select1st<Key>,
|
container_detail::select1st<Key>,
|
||||||
Compare,
|
Compare,
|
||||||
typename allocator_traits<AllocatorOrContainer>::template portable_rebind_alloc
|
typename container_detail::container_or_allocator_rebind<AllocatorOrContainer, container_detail::pair<Key, T> >::type
|
||||||
<container_detail::pair<Key, T> >::type> impl_tree_t;
|
> impl_tree_t;
|
||||||
impl_tree_t m_flat_tree; // flat tree representing flat_map
|
impl_tree_t m_flat_tree; // flat tree representing flat_map
|
||||||
|
|
||||||
typedef typename impl_tree_t::value_type impl_value_type;
|
typedef typename impl_tree_t::value_type impl_value_type;
|
||||||
@@ -652,7 +653,8 @@ class flat_map
|
|||||||
BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
|
BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||||
{ return m_flat_tree.capacity(); }
|
{ return m_flat_tree.capacity(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
|
//! <b>Effects</b>: If n is less than or equal to capacity(), or the
|
||||||
|
//! underlying container has no `reserve` member, this call has no
|
||||||
//! effect. Otherwise, it is a request for allocation of additional memory.
|
//! effect. Otherwise, it is a request for allocation of additional memory.
|
||||||
//! If the request is successful, then capacity() is greater than or equal to
|
//! If the request is successful, then capacity() is greater than or equal to
|
||||||
//! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
|
//! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
|
||||||
@@ -1507,8 +1509,8 @@ class flat_multimap
|
|||||||
container_detail::pair<Key, T>,
|
container_detail::pair<Key, T>,
|
||||||
container_detail::select1st<Key>,
|
container_detail::select1st<Key>,
|
||||||
Compare,
|
Compare,
|
||||||
typename allocator_traits<AllocatorOrContainer>::template portable_rebind_alloc
|
typename container_detail::container_or_allocator_rebind<AllocatorOrContainer, container_detail::pair<Key, T> >::type
|
||||||
<container_detail::pair<Key, T> >::type> impl_tree_t;
|
> impl_tree_t;
|
||||||
impl_tree_t m_flat_tree; // flat tree representing flat_map
|
impl_tree_t m_flat_tree; // flat tree representing flat_map
|
||||||
|
|
||||||
typedef typename impl_tree_t::value_type impl_value_type;
|
typedef typename impl_tree_t::value_type impl_value_type;
|
||||||
@@ -1798,7 +1800,7 @@ class flat_multimap
|
|||||||
: m_flat_tree( ordered_range
|
: m_flat_tree( ordered_range
|
||||||
, container_detail::force<impl_initializer_list>(il).begin()
|
, container_detail::force<impl_initializer_list>(il).begin()
|
||||||
, container_detail::force<impl_initializer_list>(il).end()
|
, container_detail::force<impl_initializer_list>(il).end()
|
||||||
, comp, a)
|
, comp, container_detail::force<const impl_allocator_type>(a))
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1826,7 +1828,7 @@ class flat_multimap
|
|||||||
//! <b>Complexity</b>: Linear in x.size().
|
//! <b>Complexity</b>: Linear in x.size().
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
flat_multimap(const flat_multimap& x, const allocator_type &a)
|
flat_multimap(const flat_multimap& x, const allocator_type &a)
|
||||||
: m_flat_tree(x.m_flat_tree, a)
|
: m_flat_tree(x.m_flat_tree, container_detail::force<const impl_allocator_type>(a))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
|
//! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
|
||||||
@@ -1835,7 +1837,7 @@ class flat_multimap
|
|||||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
|
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
|
||||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
: m_flat_tree(boost::move(x.m_flat_tree), container_detail::force<const impl_allocator_type>(a))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//! <b>Effects</b>: Makes *this a copy of x.
|
//! <b>Effects</b>: Makes *this a copy of x.
|
||||||
@@ -2061,7 +2063,8 @@ class flat_multimap
|
|||||||
size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
|
size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||||
{ return m_flat_tree.capacity(); }
|
{ return m_flat_tree.capacity(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
|
//! <b>Effects</b>: If n is less than or equal to capacity(), or the
|
||||||
|
//! underlying container has no `reserve` member, this call has no
|
||||||
//! effect. Otherwise, it is a request for allocation of additional memory.
|
//! effect. Otherwise, it is a request for allocation of additional memory.
|
||||||
//! If the request is successful, then capacity() is greater than or equal to
|
//! If the request is successful, then capacity() is greater than or equal to
|
||||||
//! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
|
//! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
|
||||||
|
@@ -543,12 +543,13 @@ class flat_set
|
|||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW;
|
size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW;
|
||||||
|
|
||||||
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
|
//! <b>Effects</b>: If n is less than or equal to capacity(), or the
|
||||||
|
//! underlying container has no `reserve` member, this call has no
|
||||||
//! effect. Otherwise, it is a request for allocation of additional memory.
|
//! effect. Otherwise, it is a request for allocation of additional memory.
|
||||||
//! If the request is successful, then capacity() is greater than or equal to
|
//! If the request is successful, then capacity() is greater than or equal to
|
||||||
//! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
|
//! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws.
|
//! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
|
//! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
|
||||||
//! to values might be invalidated.
|
//! to values might be invalidated.
|
||||||
|
@@ -13,6 +13,10 @@
|
|||||||
#include <boost/container/allocator.hpp>
|
#include <boost/container/allocator.hpp>
|
||||||
#include <boost/container/detail/flat_tree.hpp>
|
#include <boost/container/detail/flat_tree.hpp>
|
||||||
#include <boost/container/stable_vector.hpp>
|
#include <boost/container/stable_vector.hpp>
|
||||||
|
#include <boost/container/small_vector.hpp>
|
||||||
|
#include <boost/container/deque.hpp>
|
||||||
|
#include <boost/container/static_vector.hpp>
|
||||||
|
#include <boost/container/detail/container_or_allocator_rebind.hpp>
|
||||||
|
|
||||||
#include "print_container.hpp"
|
#include "print_container.hpp"
|
||||||
#include "dummy_test_allocator.hpp"
|
#include "dummy_test_allocator.hpp"
|
||||||
@@ -23,7 +27,6 @@
|
|||||||
#include "emplace_test.hpp"
|
#include "emplace_test.hpp"
|
||||||
#include "../../intrusive/test/iterator_test.hpp"
|
#include "../../intrusive/test/iterator_test.hpp"
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
@@ -35,29 +38,20 @@ namespace container {
|
|||||||
//Explicit instantiation to detect compilation errors
|
//Explicit instantiation to detect compilation errors
|
||||||
|
|
||||||
//flat_map
|
//flat_map
|
||||||
|
typedef std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> test_pair_t;
|
||||||
|
|
||||||
template class flat_map
|
template class flat_map
|
||||||
< test::movable_and_copyable_int
|
< test::movable_and_copyable_int
|
||||||
, test::movable_and_copyable_int
|
, test::movable_and_copyable_int
|
||||||
, std::less<test::movable_and_copyable_int>
|
, std::less<test::movable_and_copyable_int>
|
||||||
, test::simple_allocator
|
, test::simple_allocator< test_pair_t >
|
||||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
template class flat_map
|
template class flat_map
|
||||||
< test::movable_and_copyable_int
|
< test::movable_and_copyable_int
|
||||||
, test::movable_and_copyable_int
|
, test::movable_and_copyable_int
|
||||||
, std::less<test::movable_and_copyable_int>
|
, std::less<test::movable_and_copyable_int>
|
||||||
, std::allocator
|
, small_vector< test_pair_t, 10, std::allocator< test_pair_t > >
|
||||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
|
||||||
>;
|
|
||||||
|
|
||||||
template class flat_map
|
|
||||||
< test::movable_and_copyable_int
|
|
||||||
, test::movable_and_copyable_int
|
|
||||||
, std::less<test::movable_and_copyable_int>
|
|
||||||
, allocator
|
|
||||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
//flat_multimap
|
//flat_multimap
|
||||||
@@ -65,8 +59,21 @@ template class flat_multimap
|
|||||||
< test::movable_and_copyable_int
|
< test::movable_and_copyable_int
|
||||||
, test::movable_and_copyable_int
|
, test::movable_and_copyable_int
|
||||||
, std::less<test::movable_and_copyable_int>
|
, std::less<test::movable_and_copyable_int>
|
||||||
, test::simple_allocator
|
, stable_vector< test_pair_t, allocator< test_pair_t > >
|
||||||
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
|
>;
|
||||||
|
|
||||||
|
template class flat_multimap
|
||||||
|
< test::movable_and_copyable_int
|
||||||
|
, test::movable_and_copyable_int
|
||||||
|
, std::less<test::movable_and_copyable_int>
|
||||||
|
, deque<test_pair_t, test::simple_allocator< test_pair_t > >
|
||||||
|
>;
|
||||||
|
|
||||||
|
template class flat_multimap
|
||||||
|
< test::movable_and_copyable_int
|
||||||
|
, test::movable_and_copyable_int
|
||||||
|
, std::less<test::movable_and_copyable_int>
|
||||||
|
, static_vector<test_pair_t, 10 >
|
||||||
>;
|
>;
|
||||||
|
|
||||||
//As flat container iterators are typedefs for vector::[const_]iterator,
|
//As flat container iterators are typedefs for vector::[const_]iterator,
|
||||||
@@ -74,6 +81,24 @@ template class flat_multimap
|
|||||||
|
|
||||||
}} //boost::container
|
}} //boost::container
|
||||||
|
|
||||||
|
#if (__cplusplus > 201103L)
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace container{
|
||||||
|
|
||||||
|
template class flat_map
|
||||||
|
< test::movable_and_copyable_int
|
||||||
|
, test::movable_and_copyable_int
|
||||||
|
, test::movable_and_copyable_int
|
||||||
|
, std::less<test::movable_and_copyable_int>
|
||||||
|
, std::vector<test_pair_t>
|
||||||
|
>;
|
||||||
|
|
||||||
|
} //container_detail {
|
||||||
|
}} //boost::container
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
class recursive_flat_map
|
class recursive_flat_map
|
||||||
{
|
{
|
||||||
@@ -337,39 +362,23 @@ bool flat_tree_extract_adopt_test()
|
|||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
template<class VoidAllocatorOrContainer, class ValueType, bool = boost::container::container_detail::is_container<VoidAllocatorOrContainer>::value>
|
|
||||||
struct RebindAllocatorOrContainer
|
|
||||||
{
|
|
||||||
typedef typename allocator_traits<VoidAllocatorOrContainer>
|
|
||||||
::template portable_rebind_alloc< std::pair<ValueType, ValueType> >::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class SomeType, class ValueType, template <class> class Allocator>
|
|
||||||
struct RebindAllocatorOrContainer< boost::container::stable_vector<SomeType, Allocator<SomeType> >, ValueType, true>
|
|
||||||
{
|
|
||||||
typedef std::pair<ValueType, ValueType> type_t;
|
|
||||||
typedef typename allocator_traits< Allocator<SomeType> >
|
|
||||||
::template portable_rebind_alloc< type_t >::type allocator_t;
|
|
||||||
typedef typename boost::container::stable_vector<type_t, allocator_t> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<class VoidAllocatorOrContainer>
|
template<class VoidAllocatorOrContainer>
|
||||||
struct GetMapContainer
|
struct GetMapContainer
|
||||||
{
|
{
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
struct apply
|
struct apply
|
||||||
{
|
{
|
||||||
|
typedef std::pair<ValueType, ValueType> type_t;
|
||||||
typedef flat_map< ValueType
|
typedef flat_map< ValueType
|
||||||
, ValueType
|
, ValueType
|
||||||
, std::less<ValueType>
|
, std::less<ValueType>
|
||||||
, typename RebindAllocatorOrContainer<VoidAllocatorOrContainer, ValueType>::type
|
, typename boost::container::container_detail::container_or_allocator_rebind<VoidAllocatorOrContainer, type_t>::type
|
||||||
> map_type;
|
> map_type;
|
||||||
|
|
||||||
typedef flat_multimap< ValueType
|
typedef flat_multimap< ValueType
|
||||||
, ValueType
|
, ValueType
|
||||||
, std::less<ValueType>
|
, std::less<ValueType>
|
||||||
, typename RebindAllocatorOrContainer<VoidAllocatorOrContainer, ValueType>::type
|
, typename boost::container::container_detail::container_or_allocator_rebind<VoidAllocatorOrContainer, type_t>::type
|
||||||
> multimap_type;
|
> multimap_type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -9,9 +9,16 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <boost/container/detail/config_begin.hpp>
|
#include <boost/container/detail/config_begin.hpp>
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include <boost/container/flat_set.hpp>
|
#include <boost/container/flat_set.hpp>
|
||||||
|
#include <boost/container/stable_vector.hpp>
|
||||||
|
#include <boost/container/small_vector.hpp>
|
||||||
|
#include <boost/container/deque.hpp>
|
||||||
|
#include <boost/container/static_vector.hpp>
|
||||||
#include <boost/container/allocator.hpp>
|
#include <boost/container/allocator.hpp>
|
||||||
|
#include <boost/container/detail/container_or_allocator_rebind.hpp>
|
||||||
|
|
||||||
#include "print_container.hpp"
|
#include "print_container.hpp"
|
||||||
#include "dummy_test_allocator.hpp"
|
#include "dummy_test_allocator.hpp"
|
||||||
@@ -20,8 +27,6 @@
|
|||||||
#include "propagate_allocator_test.hpp"
|
#include "propagate_allocator_test.hpp"
|
||||||
#include "emplace_test.hpp"
|
#include "emplace_test.hpp"
|
||||||
#include "container_common_tests.hpp"
|
#include "container_common_tests.hpp"
|
||||||
#include <vector>
|
|
||||||
#include <boost/container/detail/flat_tree.hpp>
|
|
||||||
#include "../../intrusive/test/iterator_test.hpp"
|
#include "../../intrusive/test/iterator_test.hpp"
|
||||||
|
|
||||||
using namespace boost::container;
|
using namespace boost::container;
|
||||||
@@ -41,20 +46,26 @@ template class flat_set
|
|||||||
template class flat_set
|
template class flat_set
|
||||||
< test::movable_and_copyable_int
|
< test::movable_and_copyable_int
|
||||||
, std::less<test::movable_and_copyable_int>
|
, std::less<test::movable_and_copyable_int>
|
||||||
, allocator<test::movable_and_copyable_int>
|
, small_vector<test::movable_and_copyable_int, 10, allocator<test::movable_and_copyable_int> >
|
||||||
>;
|
>;
|
||||||
|
|
||||||
//flat_multiset
|
//flat_multiset
|
||||||
template class flat_multiset
|
template class flat_multiset
|
||||||
< test::movable_and_copyable_int
|
< test::movable_and_copyable_int
|
||||||
, std::less<test::movable_and_copyable_int>
|
, std::less<test::movable_and_copyable_int>
|
||||||
, test::simple_allocator<test::movable_and_copyable_int>
|
, stable_vector<test::movable_and_copyable_int, test::simple_allocator<test::movable_and_copyable_int> >
|
||||||
>;
|
>;
|
||||||
|
|
||||||
template class flat_multiset
|
template class flat_multiset
|
||||||
< test::movable_and_copyable_int
|
< test::movable_and_copyable_int
|
||||||
, std::less<test::movable_and_copyable_int>
|
, std::less<test::movable_and_copyable_int>
|
||||||
, allocator<test::movable_and_copyable_int>
|
, deque<test::movable_and_copyable_int, test::simple_allocator< test::movable_and_copyable_int > >
|
||||||
|
>;
|
||||||
|
|
||||||
|
template class flat_multiset
|
||||||
|
< test::movable_and_copyable_int
|
||||||
|
, std::less<test::movable_and_copyable_int>
|
||||||
|
, static_vector<test::movable_and_copyable_int, 10 >
|
||||||
>;
|
>;
|
||||||
|
|
||||||
//As flat container iterators are typedefs for vector::[const_]iterator,
|
//As flat container iterators are typedefs for vector::[const_]iterator,
|
||||||
@@ -62,6 +73,24 @@ template class flat_multiset
|
|||||||
|
|
||||||
}} //boost::container
|
}} //boost::container
|
||||||
|
|
||||||
|
|
||||||
|
#if (__cplusplus > 201103L)
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace container{
|
||||||
|
|
||||||
|
template class flat_set
|
||||||
|
< test::movable_and_copyable_int
|
||||||
|
, std::less<test::movable_and_copyable_int>
|
||||||
|
, std::vector<test::movable_and_copyable_int>
|
||||||
|
>;
|
||||||
|
|
||||||
|
} //container_detail {
|
||||||
|
}} //boost::container
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//Test recursive structures
|
//Test recursive structures
|
||||||
class recursive_flat_set
|
class recursive_flat_set
|
||||||
{
|
{
|
||||||
@@ -405,23 +434,20 @@ bool flat_tree_extract_adopt_test()
|
|||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
template<class VoidAllocatorOrContainer>
|
||||||
template<class VoidAllocator>
|
struct GetSetContainer
|
||||||
struct GetAllocatorSet
|
|
||||||
{
|
{
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
struct apply
|
struct apply
|
||||||
{
|
{
|
||||||
typedef flat_set < ValueType
|
typedef flat_set < ValueType
|
||||||
, std::less<ValueType>
|
, std::less<ValueType>
|
||||||
, typename allocator_traits<VoidAllocator>
|
, typename boost::container::container_detail::container_or_allocator_rebind<VoidAllocatorOrContainer, ValueType>::type
|
||||||
::template portable_rebind_alloc<ValueType>::type
|
|
||||||
> set_type;
|
> set_type;
|
||||||
|
|
||||||
typedef flat_multiset < ValueType
|
typedef flat_multiset < ValueType
|
||||||
, std::less<ValueType>
|
, std::less<ValueType>
|
||||||
, typename allocator_traits<VoidAllocator>
|
, typename boost::container::container_detail::container_or_allocator_rebind<VoidAllocatorOrContainer, ValueType>::type
|
||||||
::template portable_rebind_alloc<ValueType>::type
|
|
||||||
> multiset_type;
|
> multiset_type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -429,15 +455,15 @@ struct GetAllocatorSet
|
|||||||
template<class VoidAllocator>
|
template<class VoidAllocator>
|
||||||
int test_set_variants()
|
int test_set_variants()
|
||||||
{
|
{
|
||||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<int>::set_type MySet;
|
typedef typename GetSetContainer<VoidAllocator>::template apply<int>::set_type MySet;
|
||||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_int>::set_type MyMoveSet;
|
typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_int>::set_type MyMoveSet;
|
||||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
|
typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
|
||||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::copyable_int>::set_type MyCopySet;
|
typedef typename GetSetContainer<VoidAllocator>::template apply<test::copyable_int>::set_type MyCopySet;
|
||||||
|
|
||||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<int>::multiset_type MyMultiSet;
|
typedef typename GetSetContainer<VoidAllocator>::template apply<int>::multiset_type MyMultiSet;
|
||||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
|
typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
|
||||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
|
typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
|
||||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
|
typedef typename GetSetContainer<VoidAllocator>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
|
||||||
|
|
||||||
typedef std::set<int> MyStdSet;
|
typedef std::set<int> MyStdSet;
|
||||||
typedef std::multiset<int> MyStdMultiSet;
|
typedef std::multiset<int> MyStdMultiSet;
|
||||||
|
@@ -92,7 +92,7 @@ template class flat_tree
|
|||||||
} //container_detail {
|
} //container_detail {
|
||||||
}} //boost::container
|
}} //boost::container
|
||||||
|
|
||||||
#if (__cplusplus >= 201402L)
|
#if (__cplusplus > 201103L)
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace boost{
|
namespace boost{
|
||||||
|
Reference in New Issue
Block a user