mirror of
https://git.suyu.dev/suyu/ext-boost.git
synced 2026-01-04 13:44:28 +01:00
Update to boost v1.63.0
This commit is contained in:
parent
f005c955f8
commit
25db91d480
535 changed files with 20797 additions and 37185 deletions
|
|
@ -77,6 +77,9 @@ namespace container {
|
|||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template<class Allocator>
|
||||
class small_vector_allocator;
|
||||
|
||||
namespace allocator_traits_detail {
|
||||
|
||||
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size)
|
||||
|
|
@ -96,6 +99,10 @@ template<class T>
|
|||
struct is_std_allocator< std::allocator<T> >
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<class T>
|
||||
struct is_std_allocator< small_vector_allocator< std::allocator<T> > >
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<class Allocator>
|
||||
struct is_not_std_allocator
|
||||
{ static const bool value = !is_std_allocator<Allocator>::value; };
|
||||
|
|
@ -445,7 +452,7 @@ struct allocator_traits
|
|||
|
||||
template<class T>
|
||||
static void priv_construct(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&)
|
||||
{ ::new((void*)p) T; }
|
||||
{ ::new((void*)p, boost_container_new_t()) T; }
|
||||
|
||||
static bool priv_storage_is_unpropagable(container_detail::true_type, const Allocator &a, pointer p)
|
||||
{ return a.storage_is_unpropagable(p); }
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
//! - boost::container::vector
|
||||
//! - boost::container::stable_vector
|
||||
//! - boost::container::static_vector
|
||||
//! - boost::container::small_vector
|
||||
//! - boost::container::slist
|
||||
//! - boost::container::list
|
||||
//! - boost::container::set
|
||||
|
|
@ -38,11 +39,19 @@
|
|||
//! - boost::container::string
|
||||
//! - boost::container::wstring
|
||||
//!
|
||||
//! It forward declares the following allocators:
|
||||
//! Forward declares the following allocators:
|
||||
//! - boost::container::allocator
|
||||
//! - boost::container::node_allocator
|
||||
//! - boost::container::adaptive_pool
|
||||
//!
|
||||
//! Forward declares the following polymorphic resource classes:
|
||||
//! - boost::container::pmr::memory_resource
|
||||
//! - boost::container::pmr::polymorphic_allocator
|
||||
//! - boost::container::pmr::monotonic_buffer_resource
|
||||
//! - boost::container::pmr::pool_options
|
||||
//! - boost::container::pmr::unsynchronized_pool_resource
|
||||
//! - boost::container::pmr::synchronized_pool_resource
|
||||
//!
|
||||
//! And finally it defines the following types
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
|
@ -54,11 +63,18 @@
|
|||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
namespace detail{
|
||||
//Create namespace to avoid compilation errors
|
||||
}}
|
||||
}}}
|
||||
|
||||
namespace boost{ namespace container{ namespace container_detail{
|
||||
namespace bi = boost::intrusive;
|
||||
namespace bid = boost::intrusive::detail;
|
||||
}}}
|
||||
|
||||
namespace boost{ namespace container{ namespace pmr{
|
||||
namespace bi = boost::intrusive;
|
||||
namespace bid = boost::intrusive::detail;
|
||||
}}}
|
||||
|
||||
#include <cstddef>
|
||||
|
|
@ -210,6 +226,26 @@ template
|
|||
, std::size_t Version = 2>
|
||||
class node_allocator;
|
||||
|
||||
namespace pmr {
|
||||
|
||||
class memory_resource;
|
||||
|
||||
template<class T>
|
||||
class polymorphic_allocator;
|
||||
|
||||
class monotonic_buffer_resource;
|
||||
|
||||
struct pool_options;
|
||||
|
||||
template <class Allocator>
|
||||
class resource_adaptor_imp;
|
||||
|
||||
class unsynchronized_pool_resource;
|
||||
|
||||
class synchronized_pool_resource;
|
||||
|
||||
} //namespace pmr {
|
||||
|
||||
#else
|
||||
|
||||
//! Default options for tree-based associative containers
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@ namespace container {
|
|||
namespace container_detail {
|
||||
|
||||
template <typename T>
|
||||
inline T* addressof(T& obj)
|
||||
BOOST_CONTAINER_FORCEINLINE T* addressof(T& obj)
|
||||
{
|
||||
return static_cast<T*>(
|
||||
static_cast<void*>(
|
||||
const_cast<char*>(
|
||||
&reinterpret_cast<const char&>(obj)
|
||||
&reinterpret_cast<const volatile char&>(obj)
|
||||
)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ struct insert_nonmovable_emplace_proxy
|
|||
{ this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
template<int ...IdxPack>
|
||||
template<std::size_t ...IdxPack>
|
||||
void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
|
|
@ -266,7 +266,7 @@ struct insert_emplace_proxy
|
|||
|
||||
private:
|
||||
|
||||
template<int ...IdxPack>
|
||||
template<std::size_t ...IdxPack>
|
||||
void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n ==1); (void)n;
|
||||
|
|
|
|||
|
|
@ -53,16 +53,16 @@ struct value_to_node_compare
|
|||
{}
|
||||
|
||||
bool operator()(const Node &a, const Node &b) const
|
||||
{ return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
|
||||
{ return static_cast<const Pred&>(*this)(a.get_data(), b.get_data()); }
|
||||
|
||||
bool operator()(const Node &a) const
|
||||
{ return static_cast<const Pred&>(*this)(a.m_data); }
|
||||
{ return static_cast<const Pred&>(*this)(a.get_data()); }
|
||||
|
||||
bool operator()(const Node &a, const Node &b)
|
||||
{ return static_cast<Pred&>(*this)(a.m_data, b.m_data); }
|
||||
{ return static_cast<Pred&>(*this)(a.get_data(), b.get_data()); }
|
||||
|
||||
bool operator()(const Node &a)
|
||||
{ return static_cast<Pred&>(*this)(a.m_data); }
|
||||
{ return static_cast<Pred&>(*this)(a.get_data()); }
|
||||
|
||||
predicate_type & predicate() { return static_cast<predicate_type&>(*this); }
|
||||
const predicate_type & predicate() const { return static_cast<predicate_type&>(*this); }
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
|
||||
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
|
||||
#pragma warning (disable : 4284) // odd return type for operator->
|
||||
#pragma warning (disable : 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#pragma warning (disable : 4324) // structure was padded due to __declspec(align(
|
||||
#pragma warning (disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
|
||||
#pragma warning (disable : 4355) // "this" : used in base member initializer list
|
||||
|
|
@ -44,7 +45,9 @@
|
|||
#pragma warning (disable : 4702) // unreachable code
|
||||
#pragma warning (disable : 4706) // assignment within conditional expression
|
||||
#pragma warning (disable : 4710) // function not inlined
|
||||
#pragma warning (disable : 4714) // "function": marked as __forceinline not inlined
|
||||
#pragma warning (disable : 4711) // function selected for automatic inline expansion
|
||||
#pragma warning (disable : 4786) // identifier truncated in debug info
|
||||
#pragma warning (disable : 4996) // "function": was declared deprecated
|
||||
|
||||
#endif //BOOST_MSVC
|
||||
|
|
|
|||
|
|
@ -23,16 +23,19 @@
|
|||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//In place construction
|
||||
|
||||
template<class Allocator, class T, class InpIt>
|
||||
inline void construct_in_place(Allocator &a, T* dest, InpIt source)
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source)
|
||||
{ boost::container::allocator_traits<Allocator>::construct(a, dest, *source); }
|
||||
|
||||
template<class Allocator, class T, class U, class D>
|
||||
inline void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest);
|
||||
}
|
||||
|
|
@ -41,7 +44,7 @@ template <class T, class Difference>
|
|||
class default_init_construct_iterator;
|
||||
|
||||
template<class Allocator, class T, class U, class D>
|
||||
inline void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest, default_init);
|
||||
}
|
||||
|
|
@ -50,13 +53,44 @@ template <class T, class EmplaceFunctor, class Difference>
|
|||
class emplace_iterator;
|
||||
|
||||
template<class Allocator, class T, class U, class EF, class D>
|
||||
inline void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
ei.construct_in_place(a, dest);
|
||||
}
|
||||
|
||||
//Assignment
|
||||
|
||||
template<class DstIt, class InpIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source)
|
||||
{ *dest = *source; }
|
||||
|
||||
template<class DstIt, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
container_detail::value_init<U> val;
|
||||
*dest = boost::move(val.get());
|
||||
}
|
||||
|
||||
template <class DstIt, class Difference>
|
||||
class default_init_construct_iterator;
|
||||
|
||||
template<class DstIt, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
U u;
|
||||
*dest = boost::move(u);
|
||||
}
|
||||
|
||||
template <class T, class EmplaceFunctor, class Difference>
|
||||
class emplace_iterator;
|
||||
|
||||
template<class DstIt, class U, class EF, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
ei.assign_in_place(dest);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/construct_in_place.hpp>
|
||||
|
||||
// move
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
|
|
@ -184,8 +186,9 @@ inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
F memmove_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
||||
if(n){
|
||||
|
|
@ -197,8 +200,9 @@ F memmove_n(I f, typename boost::container::iterator_traits<I>::difference_type
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
I memmove_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
if(n){
|
||||
typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
||||
|
|
@ -210,8 +214,9 @@ I memmove_n_source(I f, typename boost::container::iterator_traits<I>::differenc
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
I memmove_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
||||
if(n){
|
||||
|
|
@ -252,15 +257,15 @@ struct disable_if_memzero_initializable
|
|||
|
||||
template <typename I, typename R>
|
||||
struct enable_if_trivially_destructible
|
||||
: enable_if_c < false/*container_detail::is_trivially_destructible
|
||||
<typename boost::container::iterator_traits<I>::value_type>::value*/
|
||||
: enable_if_c < container_detail::is_trivially_destructible
|
||||
<typename boost::container::iterator_traits<I>::value_type>::value
|
||||
, R>
|
||||
{};
|
||||
|
||||
template <typename I, typename R>
|
||||
struct disable_if_trivially_destructible
|
||||
: enable_if_c <true/*!container_detail::is_trivially_destructible
|
||||
<typename boost::container::iterator_traits<I>::value_type>::value*/
|
||||
: enable_if_c <!container_detail::is_trivially_destructible
|
||||
<typename boost::container::iterator_traits<I>::value_type>::value
|
||||
, R>
|
||||
{};
|
||||
|
||||
|
|
@ -330,7 +335,7 @@ template
|
|||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
|
||||
uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
|
|
@ -354,7 +359,7 @@ template
|
|||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
|
||||
uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -375,7 +380,7 @@ template
|
|||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
|
||||
uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
|
|
@ -399,7 +404,7 @@ template
|
|||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
|
||||
uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n_source(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -465,7 +470,7 @@ template
|
|||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
|
||||
uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
|
|
@ -489,7 +494,7 @@ template
|
|||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
|
||||
uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -510,12 +515,12 @@ template
|
|||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
|
||||
uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
|
||||
boost::container::construct_in_place(a, container_detail::iterator_to_raw_pointer(r), f);
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
|
|
@ -534,7 +539,7 @@ template
|
|||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
|
||||
uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n_source(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -554,7 +559,7 @@ template
|
|||
<typename Allocator,
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memzero_initializable<F, F>::type
|
||||
uninitialized_value_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
|
||||
uninitialized_value_init_alloc_n(Allocator &a, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
|
|
@ -577,7 +582,7 @@ template
|
|||
<typename Allocator,
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memzero_initializable<F, F>::type
|
||||
uninitialized_value_init_alloc_n(Allocator &, typename allocator_traits<Allocator>::difference_type n, F r)
|
||||
uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<F>::value_type value_type;
|
||||
std::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
|
||||
|
|
@ -601,7 +606,7 @@ inline typename container_detail::enable_if_memzero_initializable<F, F>::type
|
|||
template
|
||||
<typename Allocator,
|
||||
typename F> // F models ForwardIterator
|
||||
inline F uninitialized_default_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
|
||||
inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
|
|
@ -673,7 +678,7 @@ template
|
|||
<typename Allocator,
|
||||
typename T,
|
||||
typename F> // F models ForwardIterator
|
||||
inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename allocator_traits<Allocator>::difference_type n, F r)
|
||||
inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
|
|
@ -726,9 +731,10 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
|
||||
copy_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
copy_n(I f, U n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = *f;
|
||||
|
|
@ -739,9 +745,10 @@ inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
|
||||
copy_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
copy_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -752,12 +759,13 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
|
||||
copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
copy_n_source(I f, U n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = *f;
|
||||
boost::container::assign_in_place(r, f);
|
||||
++f; ++r;
|
||||
}
|
||||
return f;
|
||||
|
|
@ -765,9 +773,10 @@ inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
|
||||
copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
copy_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n_source(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -778,9 +787,10 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
|
||||
copy_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r)
|
||||
copy_n_source_dest(I f, U n, F &r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = *f;
|
||||
|
|
@ -791,9 +801,10 @@ inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
|
||||
copy_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
copy_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n_source_dest(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -830,9 +841,10 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
|
||||
move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
move_n(I f, U n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = ::boost::move(*f);
|
||||
|
|
@ -843,9 +855,10 @@ inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F
|
|||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename U, // U models unsigned integral constant
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
|
||||
move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
move_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n(f, n, r); }
|
||||
|
||||
|
||||
|
|
@ -889,9 +902,10 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>
|
|||
|
||||
template
|
||||
<typename I // I models InputIterator
|
||||
,typename U // U models unsigned integral constant
|
||||
,typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
|
||||
move_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r)
|
||||
move_n_source_dest(I f, U n, F &r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = ::boost::move(*f);
|
||||
|
|
@ -902,9 +916,10 @@ inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I
|
|||
|
||||
template
|
||||
<typename I // I models InputIterator
|
||||
,typename U // U models unsigned integral constant
|
||||
,typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
|
||||
move_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
move_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n_source_dest(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -915,9 +930,10 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>
|
|||
|
||||
template
|
||||
<typename I // I models InputIterator
|
||||
,typename U // U models unsigned integral constant
|
||||
,typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
|
||||
move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
move_n_source(I f, U n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = ::boost::move(*f);
|
||||
|
|
@ -928,9 +944,10 @@ inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I
|
|||
|
||||
template
|
||||
<typename I // I models InputIterator
|
||||
,typename U // U models unsigned integral constant
|
||||
,typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
|
||||
move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
move_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::memmove_n_source(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1139,4 +1156,4 @@ void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_tr
|
|||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015. 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)
|
||||
//
|
||||
|
|
@ -32,11 +32,13 @@
|
|||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/is_sorted.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#endif
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/move/make_unique.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
|
@ -44,6 +46,7 @@
|
|||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
#include <boost/move/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
|
@ -98,7 +101,7 @@ struct get_flat_tree_iterators
|
|||
typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
template <class Value, class KeyOfValue,
|
||||
class Compare, class Allocator>
|
||||
class flat_tree
|
||||
{
|
||||
|
|
@ -183,7 +186,7 @@ class flat_tree
|
|||
typedef typename vector_t::const_pointer const_pointer;
|
||||
typedef typename vector_t::reference reference;
|
||||
typedef typename vector_t::const_reference const_reference;
|
||||
typedef Key key_type;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
typedef Compare key_compare;
|
||||
typedef typename vector_t::allocator_type allocator_type;
|
||||
typedef typename vector_t::size_type size_type;
|
||||
|
|
@ -200,35 +203,36 @@ class flat_tree
|
|||
typedef allocator_traits<stored_allocator_type> stored_allocator_traits;
|
||||
|
||||
public:
|
||||
flat_tree()
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree()
|
||||
: m_data()
|
||||
{ }
|
||||
|
||||
explicit flat_tree(const Compare& comp)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit flat_tree(const Compare& comp)
|
||||
: m_data(comp)
|
||||
{ }
|
||||
|
||||
flat_tree(const Compare& comp, const allocator_type& a)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(const Compare& comp, const allocator_type& a)
|
||||
: m_data(comp, a)
|
||||
{ }
|
||||
|
||||
explicit flat_tree(const allocator_type& a)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit flat_tree(const allocator_type& a)
|
||||
: m_data(a)
|
||||
{ }
|
||||
|
||||
flat_tree(const flat_tree& x)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(const flat_tree& x)
|
||||
: m_data(x.m_data)
|
||||
{ }
|
||||
|
||||
flat_tree(BOOST_RV_REF(flat_tree) x)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(BOOST_RV_REF(flat_tree) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: m_data(boost::move(x.m_data))
|
||||
{ }
|
||||
|
||||
flat_tree(const flat_tree& x, const allocator_type &a)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(const flat_tree& x, const allocator_type &a)
|
||||
: m_data(x.m_data, a)
|
||||
{ }
|
||||
|
||||
flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
|
||||
: m_data(boost::move(x.m_data), a)
|
||||
{ }
|
||||
|
||||
|
|
@ -237,7 +241,20 @@ class flat_tree
|
|||
, const Compare& comp = Compare()
|
||||
, const allocator_type& a = allocator_type())
|
||||
: m_data(comp, a)
|
||||
{ this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); }
|
||||
{
|
||||
this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last);
|
||||
BOOST_ASSERT((is_sorted)(this->m_data.m_vect.cbegin(), this->m_data.m_vect.cend(), this->priv_value_comp()));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
flat_tree( ordered_unique_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare()
|
||||
, const allocator_type& a = allocator_type())
|
||||
: m_data(comp, a)
|
||||
{
|
||||
this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last);
|
||||
BOOST_ASSERT((is_sorted_and_unique)(this->m_data.m_vect.cbegin(), this->m_data.m_vect.cend(), this->priv_value_comp()));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
flat_tree( bool unique_insertion
|
||||
|
|
@ -262,80 +279,93 @@ class flat_tree
|
|||
}
|
||||
}
|
||||
|
||||
~flat_tree()
|
||||
BOOST_CONTAINER_FORCEINLINE ~flat_tree()
|
||||
{}
|
||||
|
||||
flat_tree& operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree& operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
|
||||
{ m_data = x.m_data; return *this; }
|
||||
|
||||
flat_tree& operator=(BOOST_RV_REF(flat_tree) x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree& operator=(BOOST_RV_REF(flat_tree) x)
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ m_data = boost::move(x.m_data); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const value_compare &priv_value_comp() const
|
||||
{ return static_cast<const value_compare &>(this->m_data); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE value_compare &priv_value_comp()
|
||||
{ return static_cast<value_compare &>(this->m_data); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const key_compare &priv_key_comp() const
|
||||
{ return this->priv_value_comp().get_comp(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE key_compare &priv_key_comp()
|
||||
{ return this->priv_value_comp().get_comp(); }
|
||||
|
||||
public:
|
||||
// accessors:
|
||||
Compare key_comp() const
|
||||
BOOST_CONTAINER_FORCEINLINE Compare key_comp() const
|
||||
{ return this->m_data.get_comp(); }
|
||||
|
||||
value_compare value_comp() const
|
||||
BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
|
||||
{ return this->m_data; }
|
||||
|
||||
allocator_type get_allocator() const
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const
|
||||
{ return this->m_data.m_vect.get_allocator(); }
|
||||
|
||||
const stored_allocator_type &get_stored_allocator() const
|
||||
BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const
|
||||
{ return this->m_data.m_vect.get_stored_allocator(); }
|
||||
|
||||
stored_allocator_type &get_stored_allocator()
|
||||
BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator()
|
||||
{ return this->m_data.m_vect.get_stored_allocator(); }
|
||||
|
||||
iterator begin()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator begin()
|
||||
{ return this->m_data.m_vect.begin(); }
|
||||
|
||||
const_iterator begin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator begin() const
|
||||
{ return this->cbegin(); }
|
||||
|
||||
const_iterator cbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const
|
||||
{ return this->m_data.m_vect.begin(); }
|
||||
|
||||
iterator end()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator end()
|
||||
{ return this->m_data.m_vect.end(); }
|
||||
|
||||
const_iterator end() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator end() const
|
||||
{ return this->cend(); }
|
||||
|
||||
const_iterator cend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cend() const
|
||||
{ return this->m_data.m_vect.end(); }
|
||||
|
||||
reverse_iterator rbegin()
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin()
|
||||
{ return reverse_iterator(this->end()); }
|
||||
|
||||
const_reverse_iterator rbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const
|
||||
{ return this->crbegin(); }
|
||||
|
||||
const_reverse_iterator crbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const
|
||||
{ return const_reverse_iterator(this->cend()); }
|
||||
|
||||
reverse_iterator rend()
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rend()
|
||||
{ return reverse_iterator(this->begin()); }
|
||||
|
||||
const_reverse_iterator rend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const
|
||||
{ return this->crend(); }
|
||||
|
||||
const_reverse_iterator crend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const
|
||||
{ return const_reverse_iterator(this->cbegin()); }
|
||||
|
||||
bool empty() const
|
||||
BOOST_CONTAINER_FORCEINLINE bool empty() const
|
||||
{ return this->m_data.m_vect.empty(); }
|
||||
|
||||
size_type size() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type size() const
|
||||
{ return this->m_data.m_vect.size(); }
|
||||
|
||||
size_type max_size() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type max_size() const
|
||||
{ return this->m_data.m_vect.max_size(); }
|
||||
|
||||
void swap(flat_tree& other)
|
||||
BOOST_CONTAINER_FORCEINLINE void swap(flat_tree& other)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_swappable<Compare>::value )
|
||||
{ this->m_data.swap(other.m_data); }
|
||||
|
|
@ -346,7 +376,7 @@ class flat_tree
|
|||
{
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
ret.second = this->priv_insert_unique_prepare(val, data);
|
||||
ret.second = this->priv_insert_unique_prepare(KeyOfValue()(val), data);
|
||||
ret.first = ret.second ? this->priv_insert_commit(data, val)
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
return ret;
|
||||
|
|
@ -356,7 +386,7 @@ class flat_tree
|
|||
{
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
ret.second = this->priv_insert_unique_prepare(val, data);
|
||||
ret.second = this->priv_insert_unique_prepare(KeyOfValue()(val), data);
|
||||
ret.first = ret.second ? this->priv_insert_commit(data, boost::move(val))
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
return ret;
|
||||
|
|
@ -376,35 +406,37 @@ class flat_tree
|
|||
return i;
|
||||
}
|
||||
|
||||
iterator insert_unique(const_iterator pos, const value_type& val)
|
||||
iterator insert_unique(const_iterator hint, const value_type& val)
|
||||
{
|
||||
std::pair<iterator,bool> ret;
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
insert_commit_data data;
|
||||
return this->priv_insert_unique_prepare(pos, val, data)
|
||||
return this->priv_insert_unique_prepare(hint, KeyOfValue()(val), data)
|
||||
? this->priv_insert_commit(data, val)
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
}
|
||||
|
||||
iterator insert_unique(const_iterator pos, BOOST_RV_REF(value_type) val)
|
||||
iterator insert_unique(const_iterator hint, BOOST_RV_REF(value_type) val)
|
||||
{
|
||||
std::pair<iterator,bool> ret;
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
insert_commit_data data;
|
||||
return this->priv_insert_unique_prepare(pos, val, data)
|
||||
return this->priv_insert_unique_prepare(hint, KeyOfValue()(val), data)
|
||||
? this->priv_insert_commit(data, boost::move(val))
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator pos, const value_type& val)
|
||||
iterator insert_equal(const_iterator hint, const value_type& val)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
insert_commit_data data;
|
||||
this->priv_insert_equal_prepare(pos, val, data);
|
||||
this->priv_insert_equal_prepare(hint, val, data);
|
||||
return this->priv_insert_commit(data, val);
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
|
||||
iterator insert_equal(const_iterator hint, BOOST_RV_REF(value_type) mval)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
insert_commit_data data;
|
||||
this->priv_insert_equal_prepare(pos, mval, data);
|
||||
this->priv_insert_equal_prepare(hint, mval, data);
|
||||
return this->priv_insert_commit(data, boost::move(mval));
|
||||
}
|
||||
|
||||
|
|
@ -477,7 +509,7 @@ class flat_tree
|
|||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->m_data.m_vect.merge(first, last); }
|
||||
{ this->m_data.m_vect.merge(first, last, static_cast<const value_compare &>(this->m_data)); }
|
||||
|
||||
template <class InIt>
|
||||
void insert_unique(ordered_unique_range_t, InIt first, InIt last
|
||||
|
|
@ -506,7 +538,7 @@ class flat_tree
|
|||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->m_data.m_vect.merge_unique(first, last, value_compare()); }
|
||||
{ this->m_data.m_vect.merge_unique(first, last, static_cast<const value_compare &>(this->m_data)); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
|
|
@ -524,6 +556,7 @@ class flat_tree
|
|||
template <class... Args>
|
||||
iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
//hint checked in insert_unique
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||
stored_allocator_type &a = this->get_stored_allocator();
|
||||
|
|
@ -546,6 +579,7 @@ class flat_tree
|
|||
template <class... Args>
|
||||
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
//hint checked in insert_equal
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||
stored_allocator_type &a = this->get_stored_allocator();
|
||||
|
|
@ -554,6 +588,29 @@ class flat_tree
|
|||
return this->insert_equal(hint, ::boost::move(val));
|
||||
}
|
||||
|
||||
template <class KeyType, class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace
|
||||
(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
const key_type & k = key;
|
||||
ret.second = hint == const_iterator()
|
||||
? this->priv_insert_unique_prepare(k, data)
|
||||
: this->priv_insert_unique_prepare(hint, k, data);
|
||||
|
||||
if(!ret.second){
|
||||
ret.first = this->nth(data.position - this->cbegin());
|
||||
}
|
||||
else{
|
||||
typedef typename emplace_functor_type<try_emplace_t, KeyType, Args...>::type func_t;
|
||||
typedef emplace_iterator<value_type, func_t, difference_type> it_t;
|
||||
func_t func(try_emplace_t(), ::boost::forward<KeyType>(key), ::boost::forward<Args>(args)...);
|
||||
ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE(N) \
|
||||
|
|
@ -600,13 +657,57 @@ class flat_tree
|
|||
value_destructor<stored_allocator_type> d(a, val);\
|
||||
return this->insert_equal(hint, ::boost::move(val));\
|
||||
}\
|
||||
template <class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool>\
|
||||
try_emplace(const_iterator hint, BOOST_FWD_REF(KeyType) key BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
std::pair<iterator,bool> ret;\
|
||||
insert_commit_data data;\
|
||||
const key_type & k = key;\
|
||||
ret.second = hint == const_iterator()\
|
||||
? this->priv_insert_unique_prepare(k, data)\
|
||||
: this->priv_insert_unique_prepare(hint, k, data);\
|
||||
\
|
||||
if(!ret.second){\
|
||||
ret.first = this->nth(data.position - this->cbegin());\
|
||||
}\
|
||||
else{\
|
||||
typedef typename emplace_functor_type<try_emplace_t, KeyType BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::type func_t;\
|
||||
typedef emplace_iterator<value_type, func_t, difference_type> it_t;\
|
||||
func_t func(try_emplace_t(), ::boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t());\
|
||||
}\
|
||||
return ret;\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE)
|
||||
BOOST_MOVE_ITERATE_0TO7(BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE)
|
||||
#undef BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
template<class KeyType, class M>
|
||||
std::pair<iterator, bool> insert_or_assign(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
const key_type& k = key;
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
ret.second = hint == const_iterator()
|
||||
? this->priv_insert_unique_prepare(k, data)
|
||||
: this->priv_insert_unique_prepare(hint, k, data);
|
||||
if(!ret.second){
|
||||
ret.first = this->nth(data.position - this->cbegin());
|
||||
ret.first->second = boost::forward<M>(obj);
|
||||
}
|
||||
else{
|
||||
typedef typename emplace_functor_type<KeyType, M>::type func_t;
|
||||
typedef emplace_iterator<value_type, func_t, difference_type> it_t;
|
||||
func_t func(boost::forward<KeyType>(key), boost::forward<M>(obj));
|
||||
ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator position)
|
||||
{ return this->m_data.m_vect.erase(position); }
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
|
|
@ -619,10 +720,10 @@ class flat_tree
|
|||
return ret;
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
|
||||
{ return this->m_data.m_vect.erase(first, last); }
|
||||
|
||||
void clear()
|
||||
BOOST_CONTAINER_FORCEINLINE void clear()
|
||||
{ this->m_data.m_vect.clear(); }
|
||||
|
||||
//! <b>Effects</b>: Tries to deallocate the excess of memory created
|
||||
|
|
@ -631,19 +732,19 @@ class flat_tree
|
|||
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to size().
|
||||
void shrink_to_fit()
|
||||
BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
|
||||
{ this->m_data.m_vect.shrink_to_fit(); }
|
||||
|
||||
iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.nth(n); }
|
||||
|
||||
const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.nth(n); }
|
||||
|
||||
size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.index_of(p); }
|
||||
|
||||
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.index_of(p); }
|
||||
|
||||
// set operations:
|
||||
|
|
@ -676,62 +777,98 @@ class flat_tree
|
|||
return n;
|
||||
}
|
||||
|
||||
iterator lower_bound(const key_type& k)
|
||||
template<class C2>
|
||||
void merge_unique(flat_tree<Value, KeyOfValue, C2, Allocator>& source)
|
||||
{
|
||||
this->insert( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end()));
|
||||
}
|
||||
|
||||
template<class C2>
|
||||
void merge_equal(flat_tree<Value, KeyOfValue, C2, Allocator>& source)
|
||||
{
|
||||
this->insert( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end()));
|
||||
}
|
||||
|
||||
void merge_unique(flat_tree& source)
|
||||
{
|
||||
this->m_data.m_vect.merge_unique
|
||||
( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end())
|
||||
, static_cast<const value_compare &>(this->m_data));
|
||||
}
|
||||
|
||||
void merge_equal(flat_tree& source)
|
||||
{
|
||||
this->m_data.m_vect.merge
|
||||
( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end())
|
||||
, static_cast<const value_compare &>(this->m_data));
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k)
|
||||
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
|
||||
|
||||
const_iterator lower_bound(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& k) const
|
||||
{ return this->priv_lower_bound(this->cbegin(), this->cend(), k); }
|
||||
|
||||
iterator upper_bound(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& k)
|
||||
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
|
||||
|
||||
const_iterator upper_bound(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& k) const
|
||||
{ return this->priv_upper_bound(this->cbegin(), this->cend(), k); }
|
||||
|
||||
std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
{ return this->priv_equal_range(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
{ return this->priv_equal_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
std::pair<iterator, iterator> lower_bound_range(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, iterator> lower_bound_range(const key_type& k)
|
||||
{ return this->priv_lower_bound_range(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
{ return this->priv_lower_bound_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
size_type capacity() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type capacity() const
|
||||
{ return this->m_data.m_vect.capacity(); }
|
||||
|
||||
void reserve(size_type cnt)
|
||||
BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
|
||||
{ this->m_data.m_vect.reserve(cnt); }
|
||||
|
||||
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)
|
||||
{
|
||||
return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
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)
|
||||
{ return !(x == y); }
|
||||
|
||||
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)
|
||||
{ return y < x; }
|
||||
|
||||
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)
|
||||
{ return !(y < x); }
|
||||
|
||||
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)
|
||||
{ return !(x < y); }
|
||||
|
||||
friend void swap(flat_tree& x, flat_tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend void swap(flat_tree& x, flat_tree& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
private:
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos <= this->end());
|
||||
}
|
||||
|
||||
struct insert_commit_data
|
||||
{
|
||||
const_iterator position;
|
||||
|
|
@ -768,34 +905,34 @@ class flat_tree
|
|||
}
|
||||
|
||||
bool priv_insert_unique_prepare
|
||||
(const_iterator b, const_iterator e, const value_type& val, insert_commit_data &commit_data)
|
||||
(const_iterator b, const_iterator e, const key_type& k, insert_commit_data &commit_data)
|
||||
{
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val));
|
||||
return commit_data.position == e || val_cmp(val, *commit_data.position);
|
||||
const key_compare &key_cmp = this->priv_key_comp();
|
||||
commit_data.position = this->priv_lower_bound(b, e, k);
|
||||
return commit_data.position == e || key_cmp(k, KeyOfValue()(*commit_data.position));
|
||||
}
|
||||
|
||||
bool priv_insert_unique_prepare
|
||||
(const value_type& val, insert_commit_data &commit_data)
|
||||
{ return this->priv_insert_unique_prepare(this->cbegin(), this->cend(), val, commit_data); }
|
||||
BOOST_CONTAINER_FORCEINLINE bool priv_insert_unique_prepare
|
||||
(const key_type& k, insert_commit_data &commit_data)
|
||||
{ return this->priv_insert_unique_prepare(this->cbegin(), this->cend(), k, commit_data); }
|
||||
|
||||
bool priv_insert_unique_prepare
|
||||
(const_iterator pos, const value_type& val, insert_commit_data &commit_data)
|
||||
(const_iterator pos, const key_type& k, insert_commit_data &commit_data)
|
||||
{
|
||||
//N1780. Props to Howard Hinnant!
|
||||
//To insert val at pos:
|
||||
//if pos == end || val <= *pos
|
||||
// if pos == begin || val >= *(pos-1)
|
||||
// insert val before pos
|
||||
//To insert k at pos:
|
||||
//if pos == end || k <= *pos
|
||||
// if pos == begin || k >= *(pos-1)
|
||||
// insert k before pos
|
||||
// else
|
||||
// insert val before upper_bound(val)
|
||||
//else if pos+1 == end || val <= *(pos+1)
|
||||
// insert val after pos
|
||||
// insert k before upper_bound(k)
|
||||
//else if pos+1 == end || k <= *(pos+1)
|
||||
// insert k after pos
|
||||
//else
|
||||
// insert val before lower_bound(val)
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
// insert k before lower_bound(k)
|
||||
const key_compare &key_cmp = this->priv_key_comp();
|
||||
const const_iterator cend_it = this->cend();
|
||||
if(pos == cend_it || val_cmp(val, *pos)){ //Check if val should go before end
|
||||
if(pos == cend_it || key_cmp(k, KeyOfValue()(*pos))){ //Check if k should go before end
|
||||
const const_iterator cbeg = this->cbegin();
|
||||
commit_data.position = pos;
|
||||
if(pos == cbeg){ //If container is empty then insert it in the beginning
|
||||
|
|
@ -803,27 +940,27 @@ class flat_tree
|
|||
}
|
||||
const_iterator prev(pos);
|
||||
--prev;
|
||||
if(val_cmp(*prev, val)){ //If previous element was less, then it should go between prev and pos
|
||||
if(key_cmp(KeyOfValue()(*prev), k)){ //If previous element was less, then it should go between prev and pos
|
||||
return true;
|
||||
}
|
||||
else if(!val_cmp(val, *prev)){ //If previous was equal then insertion should fail
|
||||
else if(!key_cmp(k, KeyOfValue()(*prev))){ //If previous was equal then insertion should fail
|
||||
commit_data.position = prev;
|
||||
return false;
|
||||
}
|
||||
else{ //Previous was bigger so insertion hint was pointless, dispatch to hintless insertion
|
||||
//but reduce the search between beg and prev as prev is bigger than val
|
||||
return this->priv_insert_unique_prepare(cbeg, prev, val, commit_data);
|
||||
//but reduce the search between beg and prev as prev is bigger than k
|
||||
return this->priv_insert_unique_prepare(cbeg, prev, k, commit_data);
|
||||
}
|
||||
}
|
||||
else{
|
||||
//The hint is before the insertion position, so insert it
|
||||
//in the remaining range [pos, end)
|
||||
return this->priv_insert_unique_prepare(pos, cend_it, val, commit_data);
|
||||
return this->priv_insert_unique_prepare(pos, cend_it, k, commit_data);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Convertible>
|
||||
iterator priv_insert_commit
|
||||
BOOST_CONTAINER_FORCEINLINE iterator priv_insert_commit
|
||||
(insert_commit_data &commit_data, BOOST_FWD_REF(Convertible) convertible)
|
||||
{
|
||||
return this->m_data.m_vect.insert
|
||||
|
|
@ -954,9 +1091,9 @@ class flat_tree
|
|||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class T, class KeyOfValue,
|
||||
template <class T, class KeyOfValue,
|
||||
class Compare, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<Key, T, KeyOfValue, Compare, Allocator> >
|
||||
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<T, KeyOfValue, Compare, Allocator> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
|
|
|
|||
57
boost/container/detail/is_sorted.hpp
Normal file
57
boost/container/detail/is_sorted.hpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2016-2016. 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_IS_SORTED_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template <class ForwardIterator, class Pred>
|
||||
bool is_sorted (ForwardIterator first, ForwardIterator last, Pred pred)
|
||||
{
|
||||
if(first != last){
|
||||
ForwardIterator next = first;
|
||||
while (++next != last){
|
||||
if(pred(*next, *first))
|
||||
return false;
|
||||
++first;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class ForwardIterator, class Pred>
|
||||
bool is_sorted_and_unique (ForwardIterator first, ForwardIterator last, Pred pred)
|
||||
{
|
||||
if(first != last){
|
||||
ForwardIterator next = first;
|
||||
while (++next != last){
|
||||
if(!pred(*first, *next))
|
||||
return false;
|
||||
++first;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/intrusive/detail/reverse_iterator.hpp>
|
||||
|
|
@ -377,7 +378,7 @@ class default_init_construct_iterator
|
|||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class repeat_iterator
|
||||
: public ::boost::container::iterator
|
||||
<std::random_access_iterator_tag, T, Difference>
|
||||
<std::random_access_iterator_tag, T, Difference, T*, T&>
|
||||
{
|
||||
typedef repeat_iterator<T, Difference> this_type;
|
||||
public:
|
||||
|
|
@ -493,13 +494,13 @@ class emplace_iterator
|
|||
|
||||
public:
|
||||
typedef Difference difference_type;
|
||||
explicit emplace_iterator(EmplaceFunctor&e)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e)
|
||||
: m_num(1), m_pe(&e){}
|
||||
|
||||
emplace_iterator()
|
||||
BOOST_CONTAINER_FORCEINLINE emplace_iterator()
|
||||
: m_num(0), m_pe(0){}
|
||||
|
||||
this_type& operator++()
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
this_type operator++(int)
|
||||
|
|
@ -509,7 +510,7 @@ class emplace_iterator
|
|||
return result;
|
||||
}
|
||||
|
||||
this_type& operator--()
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
this_type operator--(int)
|
||||
|
|
@ -519,29 +520,29 @@ class emplace_iterator
|
|||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const this_type& i, const this_type& i2)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const this_type& i, const this_type& i2)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const this_type& i, const this_type& i2)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const this_type& i, const this_type& i2)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const this_type& i, const this_type& i2)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const this_type& i, const this_type& i2)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend difference_type operator- (const this_type& i, const this_type& i2)
|
||||
BOOST_CONTAINER_FORCEINLINE friend difference_type operator- (const this_type& i, const this_type& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
this_type& operator+=(difference_type off)
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
this_type operator+(difference_type off) const
|
||||
|
|
@ -551,52 +552,58 @@ class emplace_iterator
|
|||
return other;
|
||||
}
|
||||
|
||||
friend this_type operator+(difference_type off, const this_type& right)
|
||||
BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right)
|
||||
{ return right + off; }
|
||||
|
||||
this_type& operator-=(difference_type off)
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
this_type operator-(difference_type off) const
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
private:
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
||||
//So comment them to catch bad uses
|
||||
//const T& operator*() const;
|
||||
//const T& operator[](difference_type) const;
|
||||
//const T* operator->() const;
|
||||
const T& operator*() const;
|
||||
const T& operator[](difference_type) const;
|
||||
const T* operator->() const;
|
||||
|
||||
public:
|
||||
template<class Allocator>
|
||||
void construct_in_place(Allocator &a, T* ptr)
|
||||
{ (*m_pe)(a, ptr); }
|
||||
|
||||
template<class DestIt>
|
||||
void assign_in_place(DestIt dest)
|
||||
{ (*m_pe)(dest); }
|
||||
|
||||
private:
|
||||
difference_type m_num;
|
||||
EmplaceFunctor * m_pe;
|
||||
|
||||
void increment()
|
||||
BOOST_CONTAINER_FORCEINLINE void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
BOOST_CONTAINER_FORCEINLINE const T & dereference() const
|
||||
{
|
||||
static T dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
void advance(difference_type n)
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(difference_type n)
|
||||
{ m_num -= n; }
|
||||
|
||||
difference_type distance_to(const this_type &other)const
|
||||
BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const
|
||||
{ return difference_type(m_num - other.m_num); }
|
||||
};
|
||||
|
||||
|
|
@ -612,21 +619,44 @@ struct emplace_functor
|
|||
{}
|
||||
|
||||
template<class Allocator, class T>
|
||||
void operator()(Allocator &a, T *ptr)
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)
|
||||
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
|
||||
|
||||
template<class Allocator, class T, int ...IdxPack>
|
||||
void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
|
||||
template<class DestIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)
|
||||
{ emplace_functor::inplace_impl(dest, index_tuple_t()); }
|
||||
|
||||
private:
|
||||
template<class Allocator, class T, std::size_t ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
|
||||
{
|
||||
allocator_traits<Allocator>::construct
|
||||
(a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
|
||||
}
|
||||
|
||||
template<class DestIt, std::size_t ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const container_detail::index_tuple<IdxPack...>&)
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;
|
||||
value_type && tmp= value_type(::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
|
||||
*dest = ::boost::move(tmp);
|
||||
}
|
||||
|
||||
container_detail::tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
template<class ...Args>
|
||||
struct emplace_functor_type
|
||||
{
|
||||
typedef emplace_functor<Args...> type;
|
||||
};
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//Partial specializations cannot match argument list for primary template, so add an extra argument
|
||||
template <BOOST_MOVE_CLASSDFLT9, class Dummy = void>
|
||||
struct emplace_functor_type;
|
||||
|
||||
#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
struct emplace_functor##N\
|
||||
|
|
@ -638,10 +668,26 @@ struct emplace_functor##N\
|
|||
void operator()(Allocator &a, T *ptr)\
|
||||
{ allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
|
||||
\
|
||||
template<class DestIt>\
|
||||
void operator()(DestIt dest)\
|
||||
{\
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\
|
||||
BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), container_detail::value_init<value_type> tmp) ;\
|
||||
*dest = ::boost::move(const_cast<value_type &>(BOOST_MOVE_IF(N, tmp, tmp.get())));\
|
||||
}\
|
||||
\
|
||||
BOOST_MOVE_MREF##N\
|
||||
};\
|
||||
\
|
||||
template <BOOST_MOVE_CLASS##N>\
|
||||
struct emplace_functor_type<BOOST_MOVE_TARG##N>\
|
||||
{\
|
||||
typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\
|
||||
};\
|
||||
//
|
||||
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
|
||||
|
||||
#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
|
||||
|
||||
#endif
|
||||
|
|
@ -762,54 +808,55 @@ class iterator_from_iiterator
|
|||
typedef typename types_t::iterator_category iterator_category;
|
||||
typedef typename types_t::value_type value_type;
|
||||
|
||||
iterator_from_iiterator()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator()
|
||||
: m_iit()
|
||||
{}
|
||||
|
||||
explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_iit(iit)
|
||||
{}
|
||||
|
||||
iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_iit(other.get())
|
||||
{}
|
||||
|
||||
iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ ++this->m_iit; return *this; }
|
||||
|
||||
iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
iterator_from_iiterator result (*this);
|
||||
++this->m_iit;
|
||||
return result;
|
||||
}
|
||||
|
||||
iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
//If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist
|
||||
BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value));
|
||||
--this->m_iit; return *this;
|
||||
}
|
||||
|
||||
iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
iterator_from_iiterator result (*this);
|
||||
--this->m_iit;
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return l.m_iit == r.m_iit; }
|
||||
|
||||
friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return !(l == r); }
|
||||
|
||||
reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_iit->get_data(); }
|
||||
|
||||
pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
|
||||
|
||||
const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_iit; }
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -62,19 +62,18 @@ using boost::move_detail::disable_if_and;
|
|||
using boost::move_detail::enable_if_or;
|
||||
using boost::move_detail::disable_if_or;
|
||||
|
||||
|
||||
template <class Pair>
|
||||
template <class FirstType>
|
||||
struct select1st
|
||||
{
|
||||
typedef Pair argument_type;
|
||||
typedef typename Pair::first_type result_type;
|
||||
typedef FirstType type;
|
||||
|
||||
template<class OtherPair>
|
||||
const typename Pair::first_type& operator()(const OtherPair& x) const
|
||||
template<class T>
|
||||
const type& operator()(const T& x) const
|
||||
{ return x.first; }
|
||||
|
||||
const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
|
||||
{ return x; }
|
||||
template<class T>
|
||||
type& operator()(T& x)
|
||||
{ return const_cast<type&>(x.first); }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
|
|
|||
|
|
@ -60,14 +60,17 @@ struct node_alloc_holder
|
|||
{
|
||||
//If the intrusive container is an associative container, obtain the predicate, which will
|
||||
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
|
||||
value_compare, container_detail::nat) intrusive_value_compare;
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
( boost::container::container_detail::
|
||||
, ICont, value_compare, container_detail::nat) intrusive_value_compare;
|
||||
//In that case obtain the value predicate from the node predicate via predicate_type
|
||||
//if intrusive_value_compare is node_compare<>, nat otherwise
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare,
|
||||
predicate_type, container_detail::nat) value_compare;
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
( boost::container::container_detail::
|
||||
, intrusive_value_compare
|
||||
, predicate_type, container_detail::nat) value_compare;
|
||||
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef ICont intrusive_container;
|
||||
typedef typename ICont::value_type Node;
|
||||
|
|
@ -75,19 +78,19 @@ struct node_alloc_holder
|
|||
portable_rebind_alloc<Node>::type NodeAlloc;
|
||||
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
|
||||
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
|
||||
typedef Allocator ValAlloc;
|
||||
typedef Allocator ValAlloc;
|
||||
typedef typename node_allocator_traits_type::pointer NodePtr;
|
||||
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
|
||||
typedef typename node_allocator_traits_type::size_type size_type;
|
||||
typedef typename node_allocator_traits_type::difference_type difference_type;
|
||||
typedef container_detail::integral_constant<unsigned,
|
||||
boost::container::container_detail::
|
||||
version<NodeAlloc>::value> alloc_version;
|
||||
typedef typename ICont::iterator icont_iterator;
|
||||
typedef typename ICont::const_iterator icont_citerator;
|
||||
typedef allocator_destroyer<NodeAlloc> Destroyer;
|
||||
typedef allocator_traits<NodeAlloc> NodeAllocTraits;
|
||||
typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
|
||||
version<NodeAlloc>::value> alloc_version;
|
||||
typedef typename ICont::iterator icont_iterator;
|
||||
typedef typename ICont::const_iterator icont_citerator;
|
||||
typedef allocator_destroyer<NodeAlloc> Destroyer;
|
||||
typedef allocator_traits<NodeAlloc> NodeAllocTraits;
|
||||
typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
|
||||
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
|
||||
|
|
@ -208,6 +211,29 @@ struct node_alloc_holder
|
|||
return (p);
|
||||
}
|
||||
|
||||
template<class KeyConvertible>
|
||||
NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
NodeAlloc &na = this->node_alloc();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
node_allocator_traits_type::construct
|
||||
(na, container_detail::addressof(p->m_data.first), boost::forward<KeyConvertible>(key));
|
||||
BOOST_TRY{
|
||||
node_allocator_traits_type::construct(na, container_detail::addressof(p->m_data.second));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
node_allocator_traits_type::destroy(na, container_detail::addressof(p->m_data.first));
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
void destroy_node(const NodePtr &nodep)
|
||||
{
|
||||
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
|
||||
|
|
@ -368,12 +394,6 @@ struct node_alloc_holder
|
|||
ICont &non_const_icont() const
|
||||
{ return const_cast<ICont&>(this->members_.m_icont); }
|
||||
|
||||
ICont &icont()
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
const ICont &icont() const
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
NodeAlloc &node_alloc()
|
||||
{ return static_cast<NodeAlloc &>(this->members_); }
|
||||
|
||||
|
|
@ -381,6 +401,13 @@ struct node_alloc_holder
|
|||
{ return static_cast<const NodeAlloc &>(this->members_); }
|
||||
|
||||
members_holder members_;
|
||||
|
||||
public:
|
||||
ICont &icont()
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
const ICont &icont() const
|
||||
{ return this->members_.m_icont; }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
|
|
|||
|
|
@ -27,56 +27,75 @@
|
|||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
# include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#endif
|
||||
#include <boost/move/adl_move_swap.hpp> //swap
|
||||
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include<boost/move/detail/fwd_macros.hpp>
|
||||
|
||||
/*
|
||||
namespace boost{
|
||||
namespace boost {
|
||||
namespace tuples {
|
||||
|
||||
template<class T1, class T2>
|
||||
inline rv< std::pair<T1, T2> > &move(std::pair<T1, T2> &r)
|
||||
{
|
||||
return reinterpret_cast< rv< std::pair<T1, T2> > &>(r);
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
inline rv< std::pair<T1, T2> > &move(rv< std::pair<T1, T2> > &r)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_and
|
||||
< T &
|
||||
, boost::container::container_detail::is_std_pair<T>
|
||||
, ::boost::move_detail::is_rv<T>
|
||||
>::type
|
||||
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
||||
{
|
||||
return const_cast<T&>(x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_and
|
||||
< const T &
|
||||
, boost::container::container_detail::is_std_pair<T>
|
||||
, ::boost::move_detail::is_not_rv<T>
|
||||
>::type
|
||||
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
struct null_type;
|
||||
|
||||
} //namespace tuples {
|
||||
} //namespace boost {
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
//MSVC 2010 tuple marker
|
||||
namespace std { namespace tr1 { struct _Nil; }}
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
||||
//MSVC 2012 tuple marker
|
||||
namespace std { struct _Nil; }
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <int Dummy = 0>
|
||||
struct std_piecewise_construct_holder
|
||||
{
|
||||
static ::std::piecewise_construct_t *dummy;
|
||||
};
|
||||
|
||||
template <int Dummy>
|
||||
::std::piecewise_construct_t *std_piecewise_construct_holder<Dummy>::dummy =
|
||||
reinterpret_cast< ::std::piecewise_construct_t *>(0x01234); //Avoid sanitizer errors on references to null pointers
|
||||
|
||||
typedef const std::piecewise_construct_t & piecewise_construct_t;
|
||||
|
||||
struct try_emplace_t{};
|
||||
|
||||
#else
|
||||
|
||||
//! The piecewise_construct_t struct is an empty structure type used as a unique type to
|
||||
//! disambiguate used to disambiguate between different functions that take two tuple arguments.
|
||||
typedef unspecified piecewise_construct_t;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A instance of type
|
||||
//! piecewise_construct_t
|
||||
static piecewise_construct_t piecewise_construct = BOOST_CONTAINER_DOC1ST(unspecified, *std_piecewise_construct_holder<>::dummy);
|
||||
|
||||
///@cond
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
struct piecewise_construct_use
|
||||
{
|
||||
//Avoid warnings of unused "piecewise_construct"
|
||||
piecewise_construct_use()
|
||||
{ (void)&::boost::container::piecewise_construct; }
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair;
|
||||
|
||||
|
|
@ -118,35 +137,10 @@ struct is_std_pair< std::pair<T1, T2> >
|
|||
|
||||
struct pair_nat;
|
||||
|
||||
struct piecewise_construct_t { };
|
||||
static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||
|
||||
/*
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
{
|
||||
template <class U, class V> pair(pair<U, V>&& p);
|
||||
template <class... Args1, class... Args2>
|
||||
pair(piecewise_construct_t, tuple<Args1...> first_args,
|
||||
tuple<Args2...> second_args);
|
||||
|
||||
template <class U, class V> pair& operator=(const pair<U, V>& p);
|
||||
pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
|
||||
is_nothrow_move_assignable<T2>::value);
|
||||
template <class U, class V> pair& operator=(pair<U, V>&& p);
|
||||
|
||||
void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&
|
||||
noexcept(swap(second, p.second)));
|
||||
};
|
||||
|
||||
template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
*/
|
||||
template<typename T, typename U, typename V>
|
||||
void get(T); //to enable ADL
|
||||
|
||||
///@endcond
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
|
|
@ -217,11 +211,105 @@ struct pair
|
|||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
//piecewise_construct missing
|
||||
//template <class U, class V> pair(pair<U, V>&& p);
|
||||
//template <class... Args1, class... Args2>
|
||||
// pair(piecewise_construct_t, tuple<Args1...> first_args,
|
||||
// tuple<Args2...> second_args);
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template< class KeyType, class ...Args>
|
||||
pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args)
|
||||
: first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\
|
||||
{}
|
||||
#else
|
||||
|
||||
//piecewise construction from boost::tuple
|
||||
#define BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE(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 )\
|
||||
: first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\
|
||||
{}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE)
|
||||
#undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE
|
||||
|
||||
#endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
|
||||
//piecewise construction from boost::tuple
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
|
||||
template< template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
|
||||
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<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
|
||||
, BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
|
||||
: first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\
|
||||
{ (void)p; (void)q; }\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
|
||||
|
||||
//piecewise construction from variadic tuple (with delegating constructors)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
# if !defined(BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS)
|
||||
private:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
|
||||
pair(Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
|
||||
: first (::boost::forward<Args1>(get<Indexes1>(t1))...)
|
||||
, second(::boost::forward<Args2>(get<Indexes2>(t2))...)
|
||||
{ (void) t1; (void)t2; }
|
||||
|
||||
public:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2>
|
||||
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())
|
||||
{}
|
||||
# else
|
||||
//piecewise construction from variadic tuple (suboptimal, without delegating constructors)
|
||||
private:
|
||||
template<typename T, template<class ...> class Tuple, typename... Args>
|
||||
static T build_from_args(Tuple<Args...>&& t)
|
||||
{ return do_build_from_args<T>(::boost::move(t), typename build_number_seq<sizeof...(Args)>::type()); }
|
||||
|
||||
template<typename T, template<class ...> class Tuple, typename... Args, std::size_t... Indexes>
|
||||
static T do_build_from_args(Tuple<Args...> && t, const index_tuple<Indexes...>&)
|
||||
{ (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...); }
|
||||
|
||||
public:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2>
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
: first (build_from_args<first_type> (::boost::move(t1)))
|
||||
, second (build_from_args<second_type>(::boost::move(t2)))
|
||||
{}
|
||||
# endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
//MSVC 2010 tuple implementation
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
|
||||
template< template<class, class, class, class, class, class, class, class, class, class> class StdTuple \
|
||||
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\
|
||||
, 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)\
|
||||
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
|
||||
{ (void)p; (void)q; }\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
||||
#if _VARIADIC_MAX >= 9
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
|
||||
#else
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
|
||||
#endif
|
||||
|
||||
//MSVC 2012 tuple implementation
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
|
||||
template< template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
|
||||
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\
|
||||
, 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)\
|
||||
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
|
||||
{ (void)p; (void)q; }\
|
||||
//
|
||||
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_MSVC2012_TUPLE_MAX_IT
|
||||
#endif
|
||||
|
||||
//pair copy assignment
|
||||
pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
|
||||
|
|
@ -340,30 +428,6 @@ inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
|
|||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
|
||||
|
||||
//Without this specialization recursive flat_(multi)map instantiation fails
|
||||
//because is_enum needs to instantiate the recursive pair, leading to a compilation error).
|
||||
//This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation.
|
||||
template<class T>
|
||||
struct is_enum;
|
||||
|
||||
template<class T, class U>
|
||||
struct is_enum< ::boost::container::container_detail::pair<T, U> >
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_class;
|
||||
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
template <class T1, class T2>
|
||||
struct is_class< ::boost::container::container_detail::pair<T1, T2> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
template<class T1, class T2>
|
||||
|
|
@ -387,6 +451,51 @@ struct is_class_or_union< ::boost::container::container_detail::pair<T1, T2> >
|
|||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class_or_union< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_union;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_union< ::boost::container::container_detail::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_union< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_class;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class< ::boost::container::container_detail::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace move_detail{
|
||||
|
||||
|
|
|
|||
|
|
@ -23,26 +23,8 @@
|
|||
// Standard predeclarations
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(_LIBCPP_VERSION)
|
||||
#define BOOST_CONTAINER_CLANG_INLINE_STD_NS
|
||||
#pragma GCC diagnostic push
|
||||
#if defined(__clang__)
|
||||
#pragma GCC diagnostic ignored "-Wc++11-extensions"
|
||||
#endif
|
||||
#define BOOST_CONTAINER_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
#define BOOST_CONTAINER_STD_NS_END _LIBCPP_END_NAMESPACE_STD
|
||||
#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION) //GCC >= 4.6
|
||||
#define BOOST_CONTAINER_STD_NS_BEG namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#define BOOST_CONTAINER_STD_NS_END _GLIBCXX_END_NAMESPACE_VERSION } // namespace
|
||||
#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE) //GCC >= 4.2
|
||||
#define BOOST_CONTAINER_STD_NS_BEG _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
#define BOOST_CONTAINER_STD_NS_END _GLIBCXX_END_NAMESPACE
|
||||
#else
|
||||
#define BOOST_CONTAINER_STD_NS_BEG namespace std{
|
||||
#define BOOST_CONTAINER_STD_NS_END }
|
||||
#endif
|
||||
|
||||
BOOST_CONTAINER_STD_NS_BEG
|
||||
#include <boost/move/detail/std_ns_begin.hpp>
|
||||
BOOST_MOVE_STD_NS_BEG
|
||||
|
||||
template<class T>
|
||||
class allocator;
|
||||
|
|
@ -66,11 +48,9 @@ class insert_iterator;
|
|||
|
||||
struct allocator_arg_t;
|
||||
|
||||
BOOST_CONTAINER_STD_NS_END
|
||||
struct piecewise_construct_t;
|
||||
|
||||
#ifdef BOOST_CONTAINER_CLANG_INLINE_STD_NS
|
||||
#pragma GCC diagnostic pop
|
||||
#undef BOOST_CONTAINER_CLANG_INLINE_STD_NS
|
||||
#endif //BOOST_CONTAINER_CLANG_INLINE_STD_NS
|
||||
BOOST_MOVE_STD_NS_END
|
||||
#include <boost/move/detail/std_ns_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015. 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)
|
||||
//
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/options.hpp>
|
||||
#include <boost/container/node_handle.hpp>
|
||||
|
||||
// container/detail
|
||||
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
|
||||
|
|
@ -50,6 +51,7 @@
|
|||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
#include <boost/move/detail/move_helpers.hpp>
|
||||
// other
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
|
||||
|
|
@ -134,15 +136,15 @@ struct tree_node
|
|||
typedef typename tree_internal_data_type<T>::type internal_type;
|
||||
|
||||
typedef tree_node< T, VoidPointer
|
||||
, tree_type_value, OptimizeSize> node_type;
|
||||
, tree_type_value, OptimizeSize> node_t;
|
||||
|
||||
T &get_data()
|
||||
BOOST_CONTAINER_FORCEINLINE T &get_data()
|
||||
{
|
||||
T* ptr = reinterpret_cast<T*>(&this->m_data);
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
const T &get_data() const
|
||||
BOOST_CONTAINER_FORCEINLINE const T &get_data() const
|
||||
{
|
||||
const T* ptr = reinterpret_cast<const T*>(&this->m_data);
|
||||
return *ptr;
|
||||
|
|
@ -151,39 +153,39 @@ struct tree_node
|
|||
internal_type m_data;
|
||||
|
||||
template<class T1, class T2>
|
||||
void do_assign(const std::pair<const T1, T2> &p)
|
||||
BOOST_CONTAINER_FORCEINLINE void do_assign(const std::pair<const T1, T2> &p)
|
||||
{
|
||||
const_cast<T1&>(m_data.first) = p.first;
|
||||
m_data.second = p.second;
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
void do_assign(const pair<const T1, T2> &p)
|
||||
BOOST_CONTAINER_FORCEINLINE void do_assign(const pair<const T1, T2> &p)
|
||||
{
|
||||
const_cast<T1&>(m_data.first) = p.first;
|
||||
m_data.second = p.second;
|
||||
}
|
||||
|
||||
template<class V>
|
||||
void do_assign(const V &v)
|
||||
BOOST_CONTAINER_FORCEINLINE void do_assign(const V &v)
|
||||
{ m_data = v; }
|
||||
|
||||
template<class T1, class T2>
|
||||
void do_move_assign(std::pair<const T1, T2> &p)
|
||||
BOOST_CONTAINER_FORCEINLINE void do_move_assign(std::pair<const T1, T2> &p)
|
||||
{
|
||||
const_cast<T1&>(m_data.first) = ::boost::move(p.first);
|
||||
m_data.second = ::boost::move(p.second);
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
void do_move_assign(pair<const T1, T2> &p)
|
||||
BOOST_CONTAINER_FORCEINLINE void do_move_assign(pair<const T1, T2> &p)
|
||||
{
|
||||
const_cast<T1&>(m_data.first) = ::boost::move(p.first);
|
||||
m_data.second = ::boost::move(p.second);
|
||||
}
|
||||
|
||||
template<class V>
|
||||
void do_move_assign(V &v)
|
||||
BOOST_CONTAINER_FORCEINLINE void do_move_assign(V &v)
|
||||
{ m_data = ::boost::move(v); }
|
||||
};
|
||||
|
||||
|
|
@ -198,11 +200,11 @@ class insert_equal_end_hint_functor
|
|||
Icont &icont_;
|
||||
|
||||
public:
|
||||
insert_equal_end_hint_functor(Icont &icont)
|
||||
BOOST_CONTAINER_FORCEINLINE insert_equal_end_hint_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Node &n)
|
||||
{ this->icont_.insert_equal(this->icont_.cend(), n); }
|
||||
};
|
||||
|
||||
|
|
@ -212,11 +214,11 @@ class push_back_functor
|
|||
Icont &icont_;
|
||||
|
||||
public:
|
||||
push_back_functor(Icont &icont)
|
||||
BOOST_CONTAINER_FORCEINLINE push_back_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Node &n)
|
||||
{ this->icont_.push_back(n); }
|
||||
};
|
||||
|
||||
|
|
@ -293,18 +295,18 @@ struct intrusive_tree_type
|
|||
allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename container_detail::tree_node
|
||||
< value_type, void_pointer
|
||||
, tree_type_value, OptimizeSize> node_type;
|
||||
, tree_type_value, OptimizeSize> node_t;
|
||||
typedef value_to_node_compare
|
||||
<node_type, ValueCompare> node_compare_type;
|
||||
//Deducing the hook type from node_type (e.g. node_type::hook_type) would
|
||||
//provoke an early instantiation of node_type that could ruin recursive
|
||||
<node_t, ValueCompare> node_compare_type;
|
||||
//Deducing the hook type from node_t (e.g. node_t::hook_type) would
|
||||
//provoke an early instantiation of node_t that could ruin recursive
|
||||
//tree definitions, so retype the complete type to avoid any problem.
|
||||
typedef typename intrusive_tree_hook
|
||||
<void_pointer, tree_type_value
|
||||
, OptimizeSize>::type hook_type;
|
||||
public:
|
||||
typedef typename intrusive_tree_dispatch
|
||||
< node_type, node_compare_type
|
||||
< node_t, node_compare_type
|
||||
, size_type, hook_type
|
||||
, tree_type_value>::type type;
|
||||
};
|
||||
|
|
@ -327,14 +329,14 @@ template< boost::container::tree_type_enum tree_type_value
|
|||
struct intrusive_tree_proxy
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &) {}
|
||||
BOOST_CONTAINER_FORCEINLINE static void rebalance(Icont &) {}
|
||||
};
|
||||
|
||||
template<boost::container::tree_type_enum tree_type_value>
|
||||
struct intrusive_tree_proxy<tree_type_value, true>
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &c)
|
||||
BOOST_CONTAINER_FORCEINLINE static void rebalance(Icont &c)
|
||||
{ c.rebalance(); }
|
||||
};
|
||||
|
||||
|
|
@ -350,7 +352,7 @@ template<class AllocHolder, bool DoMove>
|
|||
class RecyclingCloner
|
||||
{
|
||||
typedef typename AllocHolder::intrusive_container intrusive_container;
|
||||
typedef typename AllocHolder::Node node_type;
|
||||
typedef typename AllocHolder::Node node_t;
|
||||
typedef typename AllocHolder::NodePtr node_ptr_type;
|
||||
|
||||
public:
|
||||
|
|
@ -358,13 +360,13 @@ class RecyclingCloner
|
|||
: m_holder(holder), m_icont(itree)
|
||||
{}
|
||||
|
||||
static void do_assign(node_ptr_type &p, const node_type &other, bool_<true>)
|
||||
{ p->do_move_assign(const_cast<node_type &>(other).m_data); }
|
||||
BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type &p, const node_t &other, bool_<true>)
|
||||
{ p->do_move_assign(const_cast<node_t &>(other).m_data); }
|
||||
|
||||
static void do_assign(node_ptr_type &p, const node_type &other, bool_<false>)
|
||||
BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type &p, const node_t &other, bool_<false>)
|
||||
{ p->do_assign(other.m_data); }
|
||||
|
||||
node_ptr_type operator()(const node_type &other) const
|
||||
node_ptr_type operator()(const node_t &other) const
|
||||
{
|
||||
if(node_ptr_type p = m_icont.unlink_leftmost_without_rebalance()){
|
||||
//First recycle a node (this can't throw)
|
||||
|
|
@ -392,56 +394,63 @@ class RecyclingCloner
|
|||
intrusive_container &m_icont;
|
||||
};
|
||||
|
||||
template<class KeyValueCompare, class Node>
|
||||
//where KeyValueCompare is tree_value_compare<Key, T, Compare, KeyOfValue>
|
||||
template<class KeyCompare, class KeyOfValue>
|
||||
struct key_node_compare
|
||||
: private KeyValueCompare
|
||||
: public boost::intrusive::detail::ebo_functor_holder<KeyCompare>
|
||||
{
|
||||
explicit key_node_compare(const KeyValueCompare &comp)
|
||||
: KeyValueCompare(comp)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit key_node_compare(const KeyCompare &comp)
|
||||
: base_t(comp)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
struct is_node
|
||||
{
|
||||
static const bool value = is_same<T, Node>::value;
|
||||
};
|
||||
typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t;
|
||||
typedef KeyCompare key_compare;
|
||||
typedef KeyOfValue key_of_value;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<is_node<T>::value, const typename KeyValueCompare::value_type &>::type
|
||||
key_forward(const T &node) const
|
||||
{ return node.get_data(); }
|
||||
BOOST_CONTAINER_FORCEINLINE const key_compare &key_comp() const
|
||||
{ return static_cast<const key_compare &>(*this); }
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<!is_node<T>::value, const T &>::type
|
||||
key_forward(const T &key) const
|
||||
{ return key; }
|
||||
BOOST_CONTAINER_FORCEINLINE key_compare &key_comp()
|
||||
{ return static_cast<key_compare &>(*this); }
|
||||
|
||||
template<class KeyType, class KeyType2>
|
||||
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||
{ return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const
|
||||
{ return this->key_comp()(key1, key2); }
|
||||
|
||||
template<class U>
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const U &nonkey2) const
|
||||
{ return this->key_comp()(key1, key_of_value()(nonkey2.get_data())); }
|
||||
|
||||
template<class U>
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2) const
|
||||
{ return this->key_comp()(key_of_value()(nonkey1.get_data()), key2); }
|
||||
|
||||
template<class U, class V>
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const V &nonkey2) const
|
||||
{ return this->key_comp()(key_of_value()(nonkey1.get_data()), key_of_value()(nonkey2.get_data())); }
|
||||
};
|
||||
|
||||
template <class Key, class T, class KeyOfValue,
|
||||
template <class T, class KeyOfValue,
|
||||
class Compare, class Allocator,
|
||||
class Options = tree_assoc_defaults>
|
||||
class tree
|
||||
: protected container_detail::node_alloc_holder
|
||||
: public container_detail::node_alloc_holder
|
||||
< Allocator
|
||||
, typename container_detail::intrusive_tree_type
|
||||
< Allocator, tree_value_compare<Key, T, Compare, KeyOfValue> //ValComp
|
||||
< Allocator, tree_value_compare
|
||||
<typename allocator_traits<Allocator>::pointer, Compare, KeyOfValue>
|
||||
, Options::tree_type, Options::optimize_size>::type
|
||||
>
|
||||
{
|
||||
typedef tree_value_compare
|
||||
<Key, T, Compare, KeyOfValue> ValComp;
|
||||
< typename allocator_traits<Allocator>::pointer
|
||||
, Compare, KeyOfValue> ValComp;
|
||||
typedef typename container_detail::intrusive_tree_type
|
||||
< Allocator, ValComp, Options::tree_type
|
||||
, Options::optimize_size>::type Icont;
|
||||
typedef container_detail::node_alloc_holder
|
||||
<Allocator, Icont> AllocHolder;
|
||||
typedef typename AllocHolder::NodePtr NodePtr;
|
||||
typedef tree < Key, T, KeyOfValue
|
||||
typedef tree < T, KeyOfValue
|
||||
, Compare, Allocator, Options> ThisType;
|
||||
typedef typename AllocHolder::NodeAlloc NodeAlloc;
|
||||
typedef boost::container::
|
||||
|
|
@ -458,7 +467,7 @@ class tree
|
|||
|
||||
public:
|
||||
|
||||
typedef Key key_type;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
typedef T value_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef Compare key_compare;
|
||||
|
|
@ -475,32 +484,36 @@ class tree
|
|||
allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename boost::container::
|
||||
allocator_traits<Allocator>::difference_type difference_type;
|
||||
typedef difference_type tree_difference_type;
|
||||
typedef pointer tree_pointer;
|
||||
typedef const_pointer tree_const_pointer;
|
||||
typedef reference tree_reference;
|
||||
typedef const_reference tree_const_reference;
|
||||
typedef container_detail::iterator_from_iiterator
|
||||
<iiterator, false> iterator;
|
||||
typedef container_detail::iterator_from_iiterator
|
||||
<iiterator, true > const_iterator;
|
||||
typedef boost::container::reverse_iterator
|
||||
<iterator> reverse_iterator;
|
||||
typedef boost::container::reverse_iterator
|
||||
<const_iterator> const_reverse_iterator;
|
||||
typedef node_handle
|
||||
< Node, value_type, allocator_type, void> node_type;
|
||||
typedef insert_return_type_base
|
||||
<iterator, node_type> insert_return_type;
|
||||
|
||||
typedef NodeAlloc stored_allocator_type;
|
||||
|
||||
private:
|
||||
|
||||
typedef key_node_compare<value_compare, Node> KeyNodeCompare;
|
||||
typedef key_node_compare<key_compare, KeyOfValue> KeyNodeCompare;
|
||||
|
||||
public:
|
||||
typedef container_detail::iterator_from_iiterator<iiterator, false> iterator;
|
||||
typedef container_detail::iterator_from_iiterator<iiterator, true > const_iterator;
|
||||
typedef boost::container::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
tree()
|
||||
BOOST_CONTAINER_FORCEINLINE tree()
|
||||
: AllocHolder()
|
||||
{}
|
||||
|
||||
explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
|
||||
BOOST_CONTAINER_FORCEINLINE explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
|
||||
: AllocHolder(ValComp(comp), a)
|
||||
{}
|
||||
|
||||
explicit tree(const allocator_type& a)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit tree(const allocator_type& a)
|
||||
: AllocHolder(a)
|
||||
{}
|
||||
|
||||
|
|
@ -523,12 +536,12 @@ class tree
|
|||
const const_iterator end_it(this->cend());
|
||||
if(unique_insertion){
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_unique(end_it, *first);
|
||||
this->insert_unique_convertible(end_it, *first);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_equal(end_it, *first);
|
||||
this->insert_equal_convertible(end_it, *first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -552,7 +565,7 @@ class tree
|
|||
//for the constructor
|
||||
const const_iterator end_it(this->cend());
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_unique(end_it, *first);
|
||||
this->insert_unique_convertible(end_it, *first);
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
|
@ -600,18 +613,19 @@ class tree
|
|||
, container_detail::push_back_functor<Node, Icont>(this->icont()));
|
||||
}
|
||||
|
||||
tree(const tree& x)
|
||||
BOOST_CONTAINER_FORCEINLINE tree(const tree& x)
|
||||
: AllocHolder(x.value_comp(), x)
|
||||
{
|
||||
this->icont().clone_from
|
||||
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
tree(BOOST_RV_REF(tree) x)
|
||||
BOOST_CONTAINER_FORCEINLINE tree(BOOST_RV_REF(tree) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: AllocHolder(BOOST_MOVE_BASE(AllocHolder, x), x.value_comp())
|
||||
{}
|
||||
|
||||
tree(const tree& x, const allocator_type &a)
|
||||
BOOST_CONTAINER_FORCEINLINE tree(const tree& x, const allocator_type &a)
|
||||
: AllocHolder(x.value_comp(), a)
|
||||
{
|
||||
this->icont().clone_from
|
||||
|
|
@ -630,7 +644,7 @@ class tree
|
|||
}
|
||||
}
|
||||
|
||||
~tree()
|
||||
BOOST_CONTAINER_FORCEINLINE ~tree()
|
||||
{} //AllocHolder clears the tree
|
||||
|
||||
tree& operator=(BOOST_COPY_ASSIGN_REF(tree) x)
|
||||
|
|
@ -665,8 +679,9 @@ class tree
|
|||
}
|
||||
|
||||
tree& operator=(BOOST_RV_REF(tree) x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{
|
||||
BOOST_ASSERT(this != &x);
|
||||
NodeAlloc &this_alloc = this->node_alloc();
|
||||
|
|
@ -708,43 +723,43 @@ class tree
|
|||
|
||||
public:
|
||||
// accessors:
|
||||
value_compare value_comp() const
|
||||
BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
|
||||
{ return this->icont().value_comp().predicate(); }
|
||||
|
||||
key_compare key_comp() const
|
||||
BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
|
||||
{ return this->icont().value_comp().predicate().key_comp(); }
|
||||
|
||||
allocator_type get_allocator() const
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const
|
||||
{ return allocator_type(this->node_alloc()); }
|
||||
|
||||
const stored_allocator_type &get_stored_allocator() const
|
||||
BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const
|
||||
{ return this->node_alloc(); }
|
||||
|
||||
stored_allocator_type &get_stored_allocator()
|
||||
BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator()
|
||||
{ return this->node_alloc(); }
|
||||
|
||||
iterator begin()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator begin()
|
||||
{ return iterator(this->icont().begin()); }
|
||||
|
||||
const_iterator begin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator begin() const
|
||||
{ return this->cbegin(); }
|
||||
|
||||
iterator end()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator end()
|
||||
{ return iterator(this->icont().end()); }
|
||||
|
||||
const_iterator end() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator end() const
|
||||
{ return this->cend(); }
|
||||
|
||||
reverse_iterator rbegin()
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin()
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator rbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const
|
||||
{ return this->crbegin(); }
|
||||
|
||||
reverse_iterator rend()
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rend()
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator rend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const
|
||||
{ return this->crend(); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
||||
|
|
@ -752,7 +767,7 @@ class tree
|
|||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator cbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const
|
||||
{ return const_iterator(this->non_const_icont().begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
||||
|
|
@ -760,7 +775,7 @@ class tree
|
|||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator cend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cend() const
|
||||
{ return const_iterator(this->non_const_icont().end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
||||
|
|
@ -769,7 +784,7 @@ class tree
|
|||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reverse_iterator crbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const
|
||||
{ return const_reverse_iterator(cend()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
||||
|
|
@ -778,19 +793,19 @@ class tree
|
|||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reverse_iterator crend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const
|
||||
{ return const_reverse_iterator(cbegin()); }
|
||||
|
||||
bool empty() const
|
||||
BOOST_CONTAINER_FORCEINLINE bool empty() const
|
||||
{ return !this->size(); }
|
||||
|
||||
size_type size() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type size() const
|
||||
{ return this->icont().size(); }
|
||||
|
||||
size_type max_size() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type max_size() const
|
||||
{ return AllocHolder::max_size(); }
|
||||
|
||||
void swap(ThisType& x)
|
||||
BOOST_CONTAINER_FORCEINLINE void swap(ThisType& x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_swappable<Compare>::value )
|
||||
{ AllocHolder::swap(x); }
|
||||
|
|
@ -804,27 +819,19 @@ class tree
|
|||
(const key_type& key, insert_commit_data &data)
|
||||
{
|
||||
std::pair<iiterator, bool> ret =
|
||||
this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data);
|
||||
this->icont().insert_unique_check(key, KeyNodeCompare(key_comp()), data);
|
||||
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
|
||||
}
|
||||
|
||||
std::pair<iterator,bool> insert_unique_check
|
||||
(const_iterator hint, const key_type& key, insert_commit_data &data)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
std::pair<iiterator, bool> ret =
|
||||
this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
|
||||
this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(key_comp()), data);
|
||||
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
|
||||
}
|
||||
|
||||
iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node(v);
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_unique_commit(*tmp, data));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
iterator insert_unique_commit
|
||||
(BOOST_FWD_REF(MovableConvertible) v, insert_commit_data &data)
|
||||
|
|
@ -836,17 +843,6 @@ class tree
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::pair<iterator,bool> insert_unique(const value_type& v)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(KeyOfValue()(v), data);
|
||||
if(ret.second){
|
||||
ret.first = this->insert_unique_commit(v, data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
std::pair<iterator,bool> insert_unique(BOOST_FWD_REF(MovableConvertible) v)
|
||||
{
|
||||
|
|
@ -861,6 +857,26 @@ class tree
|
|||
|
||||
private:
|
||||
|
||||
template<class KeyConvertible, class M>
|
||||
iiterator priv_insert_or_assign_commit
|
||||
(BOOST_FWD_REF(KeyConvertible) key, BOOST_FWD_REF(M) obj, insert_commit_data &data)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node(boost::forward<KeyConvertible>(key), boost::forward<M>(obj));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iiterator ret(this->icont().insert_unique_commit(*tmp, data));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool priv_is_linked(const_iterator const position) const
|
||||
{
|
||||
iiterator const cur(position.get());
|
||||
return cur == this->icont().end() ||
|
||||
cur == this->icont().root() ||
|
||||
iiterator(cur).go_parent().go_left() == cur ||
|
||||
iiterator(cur).go_parent().go_right() == cur;
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
void push_back_impl(BOOST_FWD_REF(MovableConvertible) v)
|
||||
{
|
||||
|
|
@ -882,12 +898,13 @@ class tree
|
|||
//No throw insertion part, release rollback
|
||||
destroy_deallocator.release();
|
||||
return std::pair<iterator,bool>
|
||||
( iterator(iiterator(this->icont().insert_unique_commit(*p, data)))
|
||||
( iterator(this->icont().insert_unique_commit(*p, data))
|
||||
, true );
|
||||
}
|
||||
|
||||
iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
value_type &v = p->get_data();
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
|
|
@ -896,7 +913,7 @@ class tree
|
|||
Destroyer(this->node_alloc())(p);
|
||||
return ret.first;
|
||||
}
|
||||
return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
|
||||
return iterator(this->icont().insert_unique_commit(*p, data));
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -904,11 +921,11 @@ class tree
|
|||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <class... Args>
|
||||
std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
|
||||
{ return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); }
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{ return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...)); }
|
||||
|
||||
template <class... Args>
|
||||
|
|
@ -924,6 +941,7 @@ class tree
|
|||
template <class... Args>
|
||||
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
|
|
@ -931,6 +949,22 @@ class tree
|
|||
return ret;
|
||||
}
|
||||
|
||||
template <class KeyType, class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace
|
||||
(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
insert_commit_data data;
|
||||
const key_type & k = key; //Support emulated rvalue references
|
||||
std::pair<iiterator, bool> ret =
|
||||
hint == const_iterator() ? this->icont().insert_unique_check( k, KeyNodeCompare(key_comp()), data)
|
||||
: this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);
|
||||
if(ret.second){
|
||||
ret.first = this->icont().insert_unique_commit
|
||||
(*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key), boost::forward<Args>(args)...), data);
|
||||
}
|
||||
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_TREE_EMPLACE_CODE(N) \
|
||||
|
|
@ -955,31 +989,39 @@ class tree
|
|||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
BOOST_ASSERT((priv_is_linked)(hint));\
|
||||
NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));\
|
||||
destroy_deallocator.release();\
|
||||
return ret;\
|
||||
}\
|
||||
\
|
||||
template <class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool>\
|
||||
try_emplace(const_iterator hint, BOOST_FWD_REF(KeyType) key BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
insert_commit_data data;\
|
||||
const key_type & k = key;\
|
||||
std::pair<iiterator, bool> ret =\
|
||||
hint == const_iterator() ? this->icont().insert_unique_check( k, KeyNodeCompare(key_comp()), data)\
|
||||
: this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);\
|
||||
if(ret.second){\
|
||||
ret.first = this->icont().insert_unique_commit\
|
||||
(*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N), data);\
|
||||
}\
|
||||
return std::pair<iterator, bool>(iterator(ret.first), ret.second);\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_TREE_EMPLACE_CODE)
|
||||
#undef BOOST_CONTAINER_TREE_EMPLACE_CODE
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
iterator insert_unique(const_iterator hint, const value_type& v)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(hint, KeyOfValue()(v), data);
|
||||
if(!ret.second)
|
||||
return ret.first;
|
||||
return this->insert_unique_commit(v, data);
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
|
||||
iterator insert_unique_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(hint, KeyOfValue()(v), data);
|
||||
|
|
@ -988,6 +1030,8 @@ class tree
|
|||
return this->insert_unique_commit(boost::forward<MovableConvertible>(v), data);
|
||||
}
|
||||
|
||||
BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_unique, value_type, iterator, this->insert_unique_convertible, const_iterator, const_iterator)
|
||||
|
||||
template <class InputIterator>
|
||||
void insert_unique(InputIterator first, InputIterator last)
|
||||
{
|
||||
|
|
@ -1014,18 +1058,10 @@ class tree
|
|||
return ret;
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator hint, const value_type& v)
|
||||
{
|
||||
NodePtr tmp(AllocHolder::create_node(v));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
|
||||
iterator insert_equal_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
|
|
@ -1033,6 +1069,8 @@ class tree
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_equal, value_type, iterator, this->insert_equal_convertible, const_iterator, const_iterator)
|
||||
|
||||
template <class InputIterator>
|
||||
void insert_equal(InputIterator first, InputIterator last)
|
||||
{
|
||||
|
|
@ -1040,52 +1078,150 @@ class tree
|
|||
this->insert_equal(*first);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{ return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
|
||||
template<class KeyType, class M>
|
||||
std::pair<iterator, bool> insert_or_assign(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
insert_commit_data data;
|
||||
const key_type & k = key; //Support emulated rvalue references
|
||||
std::pair<iiterator, bool> ret =
|
||||
hint == const_iterator() ? this->icont().insert_unique_check(k, KeyNodeCompare(key_comp()), data)
|
||||
: this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);
|
||||
if(ret.second){
|
||||
ret.first = this->priv_insert_or_assign_commit(boost::forward<KeyType>(key), boost::forward<M>(obj), data);
|
||||
}
|
||||
else{
|
||||
ret.first->get_data().second = boost::forward<M>(obj);
|
||||
}
|
||||
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{ return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
|
||||
return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc())));
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& k)
|
||||
{ return AllocHolder::erase_key(k, KeyNodeCompare(key_comp()), alloc_version()); }
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{ return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
|
||||
{
|
||||
BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
|
||||
BOOST_ASSERT(first == last || (priv_is_linked)(last));
|
||||
return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
|
||||
}
|
||||
|
||||
void clear()
|
||||
node_type extract(const key_type& k)
|
||||
{
|
||||
iterator const it = this->find(k);
|
||||
if(this->end() != it){
|
||||
return this->extract(it);
|
||||
}
|
||||
return node_type();
|
||||
}
|
||||
|
||||
node_type extract(const_iterator position)
|
||||
{
|
||||
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
|
||||
iiterator const iit(position.get());
|
||||
this->icont().erase(iit);
|
||||
return node_type(iit.operator->(), this->node_alloc());
|
||||
}
|
||||
|
||||
insert_return_type insert_unique_node(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{
|
||||
return this->insert_unique_node(this->end(), boost::move(nh));
|
||||
}
|
||||
|
||||
insert_return_type insert_unique_node(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{
|
||||
insert_return_type irt; //inserted == false, node.empty()
|
||||
if(!nh.empty()){
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(hint, KeyOfValue()(nh.value()), data);
|
||||
if(ret.second){
|
||||
irt.inserted = true;
|
||||
irt.position = iterator(this->icont().insert_unique_commit(*nh.get_node_pointer(), data));
|
||||
nh.release();
|
||||
}
|
||||
else{
|
||||
irt.position = ret.first;
|
||||
irt.node = boost::move(nh);
|
||||
}
|
||||
}
|
||||
else{
|
||||
irt.position = this->end();
|
||||
}
|
||||
return BOOST_MOVE_RET(insert_return_type, irt);
|
||||
}
|
||||
|
||||
iterator insert_equal_node(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{
|
||||
if(nh.empty()){
|
||||
return this->end();
|
||||
}
|
||||
else{
|
||||
NodePtr const p(nh.release());
|
||||
return iterator(this->icont().insert_equal(*p));
|
||||
}
|
||||
}
|
||||
|
||||
iterator insert_equal_node(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{
|
||||
if(nh.empty()){
|
||||
return this->end();
|
||||
}
|
||||
else{
|
||||
NodePtr const p(nh.release());
|
||||
return iterator(this->icont().insert_equal(hint.get(), *p));
|
||||
}
|
||||
}
|
||||
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge_unique(tree<T, KeyOfValue, C2, Allocator, Options>& source)
|
||||
{ return this->icont().merge_unique(source.icont()); }
|
||||
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge_equal(tree<T, KeyOfValue, C2, Allocator, Options>& source)
|
||||
{ return this->icont().merge_equal(source.icont()); }
|
||||
BOOST_CONTAINER_FORCEINLINE void clear()
|
||||
{ AllocHolder::clear(alloc_version()); }
|
||||
|
||||
// search operations. Const and non-const overloads even if no iterator is returned
|
||||
// so splay implementations can to their rebalancing when searching in non-const versions
|
||||
iterator find(const key_type& k)
|
||||
{ return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
|
||||
BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& k)
|
||||
{ return iterator(this->icont().find(k, KeyNodeCompare(key_comp()))); }
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); }
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(key_comp()))); }
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{ return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
|
||||
BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& k) const
|
||||
{ return size_type(this->icont().count(k, KeyNodeCompare(key_comp()))); }
|
||||
|
||||
iterator lower_bound(const key_type& k)
|
||||
{ return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k)
|
||||
{ return iterator(this->icont().lower_bound(k, KeyNodeCompare(key_comp()))); }
|
||||
|
||||
const_iterator lower_bound(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(key_comp()))); }
|
||||
|
||||
iterator upper_bound(const key_type& k)
|
||||
{ return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& k)
|
||||
{ return iterator(this->icont().upper_bound(k, KeyNodeCompare(key_comp()))); }
|
||||
|
||||
const_iterator upper_bound(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(key_comp()))); }
|
||||
|
||||
std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->icont().equal_range(k, KeyNodeCompare(value_comp()));
|
||||
this->icont().equal_range(k, KeyNodeCompare(key_comp()));
|
||||
return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
|
||||
this->non_const_icont().equal_range(k, KeyNodeCompare(key_comp()));
|
||||
return std::pair<const_iterator,const_iterator>
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
|
@ -1093,40 +1229,40 @@ class tree
|
|||
std::pair<iterator,iterator> lower_bound_range(const key_type& k)
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->icont().lower_bound_range(k, KeyNodeCompare(value_comp()));
|
||||
this->icont().lower_bound_range(k, KeyNodeCompare(key_comp()));
|
||||
return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->non_const_icont().lower_bound_range(k, KeyNodeCompare(value_comp()));
|
||||
this->non_const_icont().lower_bound_range(k, KeyNodeCompare(key_comp()));
|
||||
return std::pair<const_iterator,const_iterator>
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
||||
void rebalance()
|
||||
BOOST_CONTAINER_FORCEINLINE void rebalance()
|
||||
{ intrusive_tree_proxy_t::rebalance(this->icont()); }
|
||||
|
||||
friend bool operator==(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator==(const tree& x, const tree& y)
|
||||
{ return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
friend bool operator<(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<(const tree& x, const tree& y)
|
||||
{ return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
friend bool operator!=(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const tree& x, const tree& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
friend bool operator>(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>(const tree& x, const tree& y)
|
||||
{ return y < x; }
|
||||
|
||||
friend bool operator<=(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const tree& x, const tree& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
friend bool operator>=(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const tree& x, const tree& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
friend void swap(tree& x, tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend void swap(tree& x, tree& y)
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
||||
|
|
@ -1138,11 +1274,11 @@ struct has_trivial_destructor_after_move;
|
|||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class T, class KeyOfValue, class Compare, class Allocator, class Options>
|
||||
template <class T, class KeyOfValue, class Compare, class Allocator, class Options>
|
||||
struct has_trivial_destructor_after_move
|
||||
<
|
||||
::boost::container::container_detail::tree
|
||||
<Key, T, KeyOfValue, Compare, Allocator, Options>
|
||||
<T, KeyOfValue, Compare, Allocator, Options>
|
||||
>
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ namespace boost {
|
|||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
using ::boost::move_detail::enable_if;
|
||||
using ::boost::move_detail::enable_if_and;
|
||||
using ::boost::move_detail::is_same;
|
||||
using ::boost::move_detail::is_different;
|
||||
using ::boost::move_detail::is_pointer;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ struct value_init
|
|||
|
||||
operator T &() { return m_t; }
|
||||
|
||||
T &get() { return m_t; }
|
||||
|
||||
T m_t;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <cstddef> //std::size_t
|
||||
|
|
@ -42,19 +43,19 @@ class tuple<Head, Tail...>
|
|||
typedef tuple<Tail...> inherited;
|
||||
|
||||
public:
|
||||
tuple() { }
|
||||
tuple()
|
||||
: inherited(), m_head()
|
||||
{}
|
||||
|
||||
// implicit copy-constructor is okay
|
||||
// Construct tuple from separate arguments.
|
||||
tuple(typename add_const_reference<Head>::type v,
|
||||
typename add_const_reference<Tail>::type... vtail)
|
||||
: inherited(vtail...), m_head(v)
|
||||
template<class U, class ...Args>
|
||||
tuple(U &&u, Args && ...args)
|
||||
: inherited(::boost::forward<Args>(args)...), m_head(::boost::forward<U>(u))
|
||||
{}
|
||||
|
||||
// Construct tuple from another tuple.
|
||||
template<typename... VValues>
|
||||
tuple(const tuple<VValues...>& other)
|
||||
: m_head(other.head()), inherited(other.tail())
|
||||
: inherited(other.tail()), m_head(other.head())
|
||||
{}
|
||||
|
||||
template<typename... VValues>
|
||||
|
|
@ -77,8 +78,8 @@ class tuple<Head, Tail...>
|
|||
|
||||
|
||||
template<typename... Values>
|
||||
tuple<Values&&...> tie_forward(Values&&... values)
|
||||
{ return tuple<Values&&...>(values...); }
|
||||
tuple<Values&&...> forward_as_tuple(Values&&... values)
|
||||
{ return tuple<Values&&...>(::boost::forward<Values>(values)...); }
|
||||
|
||||
template<int I, typename Tuple>
|
||||
struct tuple_element;
|
||||
|
|
@ -135,21 +136,25 @@ typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>&
|
|||
// in a function call.
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
template<int... Indexes>
|
||||
struct index_tuple{};
|
||||
template<std::size_t...> struct index_tuple{ typedef index_tuple type; };
|
||||
|
||||
template<std::size_t Num, typename Tuple = index_tuple<> >
|
||||
struct build_number_seq;
|
||||
template<class S1, class S2> struct concat_index_tuple;
|
||||
|
||||
template<std::size_t Num, int... Indexes>
|
||||
struct build_number_seq<Num, index_tuple<Indexes...> >
|
||||
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
|
||||
template<std::size_t... I1, std::size_t... I2>
|
||||
struct concat_index_tuple<index_tuple<I1...>, index_tuple<I2...>>
|
||||
: index_tuple<I1..., (sizeof...(I1)+I2)...>{};
|
||||
|
||||
template<std::size_t N> struct build_number_seq;
|
||||
|
||||
template<std::size_t N>
|
||||
struct build_number_seq
|
||||
: concat_index_tuple<typename build_number_seq<N/2>::type
|
||||
,typename build_number_seq<N - N/2 >::type
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<int... Indexes>
|
||||
struct build_number_seq<0, index_tuple<Indexes...> >
|
||||
{ typedef index_tuple<Indexes...> type; };
|
||||
|
||||
template<> struct build_number_seq<0> : index_tuple<>{};
|
||||
template<> struct build_number_seq<1> : index_tuple<0>{};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)\
|
||||
&& !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
|
||||
#define BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
|
@ -31,12 +29,30 @@
|
|||
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC_VERSION)
|
||||
# if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11)
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#elif defined(BOOST_MSVC)
|
||||
# if _MSC_FULL_VER < 180020827
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#elif defined(BOOST_CLANG)
|
||||
# if !__has_feature(cxx_delegating_constructors)
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_FALLTHOUGH)
|
||||
#define BOOST_CONTAINER_FALLTHOUGH
|
||||
#else
|
||||
#define BOOST_CONTAINER_FALLTHOUGH BOOST_FALLTHOUGH;
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600))
|
||||
#define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE
|
||||
#endif
|
||||
|
||||
//Macros for documentation purposes. For code, expands to the argument
|
||||
#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
|
||||
#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE
|
||||
|
|
@ -59,6 +75,39 @@
|
|||
#define BOOST_CONTAINER_DOCIGN(T) T
|
||||
#define BOOST_CONTAINER_DOCONLY(T)
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
/*
|
||||
we need to import/export our code only if the user has specifically
|
||||
asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
|
||||
libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK
|
||||
if they want just this one to be dynamically liked:
|
||||
*/
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
||||
|
||||
/* export if this is our own source, otherwise import: */
|
||||
#ifdef BOOST_CONTAINER_SOURCE
|
||||
# define BOOST_CONTAINER_DECL BOOST_SYMBOL_EXPORT
|
||||
#else
|
||||
# define BOOST_CONTAINER_DECL BOOST_SYMBOL_IMPORT
|
||||
|
||||
#endif /* BOOST_CONTAINER_SOURCE */
|
||||
#else
|
||||
#define BOOST_CONTAINER_DECL
|
||||
#endif /* DYN_LINK */
|
||||
|
||||
//#define BOOST_CONTAINER_DISABLE_FORCEINLINE
|
||||
|
||||
#if defined(BOOST_CONTAINER_DISABLE_FORCEINLINE)
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#elif defined(BOOST_CONTAINER_FORCEINLINE_IS_BOOST_FORCELINE)
|
||||
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
|
||||
#elif defined(BOOST_MSVC) && defined(_DEBUG)
|
||||
//"__forceinline" and MSVC seems to have some bugs in debug mode
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5)))
|
||||
//Older GCCs have problems with forceinline
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#else
|
||||
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
|
|
|||
|
|
@ -53,14 +53,17 @@ namespace container {
|
|||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_multimap;
|
||||
|
||||
namespace container_detail{
|
||||
|
||||
template<class D, class S>
|
||||
static D &force(const S &s)
|
||||
BOOST_CONTAINER_FORCEINLINE static D &force(const S &s)
|
||||
{ return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
|
||||
|
||||
template<class D, class S>
|
||||
static D force_copy(S s)
|
||||
BOOST_CONTAINER_FORCEINLINE static D force_copy(S s)
|
||||
{
|
||||
D *vp = reinterpret_cast<D *>(&s);
|
||||
return D(*vp);
|
||||
|
|
@ -110,16 +113,16 @@ class flat_map
|
|||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_map)
|
||||
//This is the tree that we should store if pair was movable
|
||||
typedef container_detail::flat_tree<Key,
|
||||
typedef container_detail::flat_tree<
|
||||
std::pair<Key, T>,
|
||||
container_detail::select1st< std::pair<Key, T> >,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
Allocator> tree_t;
|
||||
|
||||
//This is the real tree stored here. It's based on a movable pair
|
||||
typedef container_detail::flat_tree<Key,
|
||||
typedef container_detail::flat_tree<
|
||||
container_detail::pair<Key, T>,
|
||||
container_detail::select1st<container_detail::pair<Key, T> >,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
typename allocator_traits<Allocator>::template portable_rebind_alloc
|
||||
<container_detail::pair<Key, T> >::type> impl_tree_t;
|
||||
|
|
@ -131,7 +134,7 @@ class flat_map
|
|||
typedef typename impl_tree_t::allocator_type impl_allocator_type;
|
||||
typedef container_detail::flat_tree_value_compare
|
||||
< Compare
|
||||
, container_detail::select1st< std::pair<Key, T> >
|
||||
, container_detail::select1st<Key>
|
||||
, std::pair<Key, T> > value_compare_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::iterator iterator_impl;
|
||||
|
|
@ -143,6 +146,13 @@ class flat_map
|
|||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
public:
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
|
||||
impl_tree_t &tree()
|
||||
{ return m_flat_tree; }
|
||||
|
||||
const impl_tree_t &tree() const
|
||||
{ return m_flat_tree; }
|
||||
|
||||
private:
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
|
|
@ -183,10 +193,11 @@ class flat_map
|
|||
//! <b>Effects</b>: Default constructs an empty flat_map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
flat_map()
|
||||
flat_map() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: m_flat_tree()
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -197,7 +208,7 @@ class flat_map
|
|||
explicit flat_map(const Compare& comp, const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +218,7 @@ class flat_map
|
|||
explicit flat_map(const allocator_type& a)
|
||||
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +232,7 @@ class flat_map
|
|||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -234,7 +245,7 @@ class flat_map
|
|||
flat_map(InputIterator first, InputIterator last, const allocator_type& a)
|
||||
: m_flat_tree(true, first, last, Compare(), container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -251,9 +262,9 @@ class flat_map
|
|||
template <class InputIterator>
|
||||
flat_map( ordered_unique_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
: m_flat_tree(ordered_unique_range, first, last, comp, a)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -267,7 +278,7 @@ class flat_map
|
|||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -279,7 +290,7 @@ class flat_map
|
|||
flat_map(std::initializer_list<value_type> il, const allocator_type& a)
|
||||
: m_flat_tree(true, il.begin(), il.end(), Compare(), container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -295,9 +306,9 @@ class flat_map
|
|||
//! <b>Note</b>: Non-standard extension.
|
||||
flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
|
||||
: m_flat_tree(ordered_unique_range, il.begin(), il.end(), comp, a)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
#endif
|
||||
|
|
@ -308,7 +319,7 @@ class flat_map
|
|||
flat_map(const flat_map& x)
|
||||
: m_flat_tree(x.m_flat_tree)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -319,9 +330,10 @@ class flat_map
|
|||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_map(BOOST_RV_REF(flat_map) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -331,7 +343,7 @@ class flat_map
|
|||
flat_map(const flat_map& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -342,7 +354,7 @@ class flat_map
|
|||
flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -362,8 +374,9 @@ class flat_map
|
|||
//! propagate_on_container_move_assignment is true or
|
||||
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||
flat_map& operator=(BOOST_RV_REF(flat_map) x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ m_flat_tree = boost::move(x.m_flat_tree); return *this; }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
|
@ -593,11 +606,104 @@ class flat_map
|
|||
//!
|
||||
//! Complexity: Logarithmic.
|
||||
mapped_type &operator[](key_type &&k) ;
|
||||
|
||||
#elif defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
|
||||
//in compilers like GCC 3.4, we can't catch temporaries
|
||||
mapped_type& operator[](const key_type &k) { return this->priv_subscript(k); }
|
||||
mapped_type& operator[](BOOST_RV_REF(key_type) k) { return this->priv_subscript(::boost::move(k)); }
|
||||
#else
|
||||
BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
|
||||
BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
|
||||
#endif
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, forward<M>(obj)).
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(this->m_flat_tree.insert_or_assign
|
||||
( impl_const_iterator(), k, ::boost::forward<M>(obj))
|
||||
);
|
||||
}
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, move(obj)).
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(this->m_flat_tree.insert_or_assign
|
||||
( impl_const_iterator(), ::boost::move(k), ::boost::forward<M>(obj))
|
||||
);
|
||||
}
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, forward<M>(obj)) and the new element
|
||||
//! to the container as close as possible to the position just before hint.
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container in general, but amortized constant if
|
||||
//! the new element is inserted just before hint.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(this->m_flat_tree.insert_or_assign
|
||||
( container_detail::force_copy<impl_const_iterator>(hint)
|
||||
, k, ::boost::forward<M>(obj))
|
||||
);
|
||||
}
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, move(obj)) and the new element
|
||||
//! to the container as close as possible to the position just before hint.
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container in general, but amortized constant if
|
||||
//! the new element is inserted just before hint.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(this->m_flat_tree.insert_or_assign
|
||||
( container_detail::force_copy<impl_const_iterator>(hint)
|
||||
, ::boost::move(k), ::boost::forward<M>(obj))
|
||||
);
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::nth(size_type)
|
||||
iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
|
||||
|
|
@ -686,6 +792,79 @@ class flat_map
|
|||
, boost::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
|
||||
//! forward_as_tuple(k), forward_as_tuple(forward<Args>(args)...).
|
||||
//!
|
||||
//! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
|
||||
//! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),
|
||||
//! forward_as_tuple(forward<Args>(args)...).
|
||||
//!
|
||||
//! <b>Returns</b>: The bool component of the returned pair is true if and only if the
|
||||
//! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
template <class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >(
|
||||
m_flat_tree.try_emplace(impl_const_iterator(), k, boost::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
|
||||
//! forward_as_tuple(k), forward_as_tuple(forward<Args>(args)...).
|
||||
//!
|
||||
//! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
|
||||
//! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),
|
||||
//! forward_as_tuple(forward<Args>(args)...).
|
||||
//!
|
||||
//! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
|
||||
//! is inserted right before p.
|
||||
template <class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return container_detail::force_copy<iterator>(m_flat_tree.try_emplace
|
||||
(container_detail::force_copy<impl_const_iterator>(hint), k, boost::forward<Args>(args)...).first);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
|
||||
//! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
|
||||
//!
|
||||
//! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
|
||||
//! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
|
||||
//! forward_as_tuple(forward<Args>(args)...).
|
||||
//!
|
||||
//! <b>Returns</b>: The bool component of the returned pair is true if and only if the
|
||||
//! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
template <class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k), boost::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
|
||||
//! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
|
||||
//!
|
||||
//! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
|
||||
//! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
|
||||
//! forward_as_tuple(forward<Args>(args)...).
|
||||
//!
|
||||
//! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
|
||||
//! is inserted right before p.
|
||||
template <class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return container_detail::force_copy<iterator>
|
||||
(m_flat_tree.try_emplace(container_detail::force_copy
|
||||
<impl_const_iterator>(hint), boost::move(k), boost::forward<Args>(args)...).first);
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
|
||||
|
|
@ -702,6 +881,29 @@ class flat_map
|
|||
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique\
|
||||
(container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
|
||||
}\
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >\
|
||||
(m_flat_tree.try_emplace(impl_const_iterator(), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
|
||||
}\
|
||||
\
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{ return container_detail::force_copy<iterator>(m_flat_tree.try_emplace\
|
||||
(container_detail::force_copy<impl_const_iterator>(hint), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
|
||||
\
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >\
|
||||
(m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
|
||||
}\
|
||||
\
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{ return container_detail::force_copy<iterator>(m_flat_tree.try_emplace\
|
||||
(container_detail::force_copy<impl_const_iterator>(hint), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
|
||||
#undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
|
||||
|
|
@ -864,6 +1066,39 @@ class flat_map
|
|||
{ m_flat_tree.insert_unique(ordered_unique_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: this->get_allocator() == source.get_allocator().
|
||||
//!
|
||||
//! <b>Effects</b>: Attempts to extract each element in source and insert it into a using
|
||||
//! the comparison object of *this. If there is an element in a with key equivalent to the
|
||||
//! key of an element from source, then that element is not extracted from source.
|
||||
//!
|
||||
//! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
|
||||
//! to those same elements but as members of *this. Iterators referring to the transferred
|
||||
//! elements will continue to refer to their elements, but they now behave as iterators into *this,
|
||||
//! not into source.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless the comparison object throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, Allocator>& source)
|
||||
{ m_flat_tree.merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_map<Key, T, C2, Allocator>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, Allocator>& source)
|
||||
{ m_flat_tree.merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multimap<Key, T, C2, Allocator>&>(source)); }
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns an iterator pointing to the element immediately
|
||||
|
|
@ -958,7 +1193,7 @@ class flat_map
|
|||
//! <b>Returns</b>: A const_iterator pointing to an element with the key
|
||||
//! equivalent to x, or end() if such an element is not found.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.s
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
const_iterator find(const key_type& x) const
|
||||
{ return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
|
||||
|
||||
|
|
@ -971,40 +1206,40 @@ class flat_map
|
|||
//! <b>Returns</b>: An iterator pointing to the first element with key not less
|
||||
//! than k, or a.end() if such an element is not found.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
iterator lower_bound(const key_type& x)
|
||||
{ return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
|
||||
|
||||
//! <b>Returns</b>: A const iterator pointing to the first element with key not
|
||||
//! less than k, or a.end() if such an element is not found.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
const_iterator lower_bound(const key_type& x) const
|
||||
{ return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
|
||||
|
||||
//! <b>Returns</b>: An iterator pointing to the first element with key not less
|
||||
//! than x, or end() if such an element is not found.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
iterator upper_bound(const key_type& x)
|
||||
{ return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
|
||||
|
||||
//! <b>Returns</b>: A const iterator pointing to the first element with key not
|
||||
//! less than x, or end() if such an element is not found.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
const_iterator upper_bound(const key_type& x) const
|
||||
{ return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
|
||||
|
||||
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
std::pair<iterator,iterator> equal_range(const key_type& x)
|
||||
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
|
||||
|
||||
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
|
||||
|
||||
|
|
@ -1134,15 +1369,15 @@ class flat_multimap
|
|||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
|
||||
typedef container_detail::flat_tree<Key,
|
||||
typedef container_detail::flat_tree<
|
||||
std::pair<Key, T>,
|
||||
container_detail::select1st< std::pair<Key, T> >,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
Allocator> tree_t;
|
||||
//This is the real tree stored here. It's based on a movable pair
|
||||
typedef container_detail::flat_tree<Key,
|
||||
typedef container_detail::flat_tree<
|
||||
container_detail::pair<Key, T>,
|
||||
container_detail::select1st<container_detail::pair<Key, T> >,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
typename allocator_traits<Allocator>::template portable_rebind_alloc
|
||||
<container_detail::pair<Key, T> >::type> impl_tree_t;
|
||||
|
|
@ -1154,7 +1389,7 @@ class flat_multimap
|
|||
typedef typename impl_tree_t::allocator_type impl_allocator_type;
|
||||
typedef container_detail::flat_tree_value_compare
|
||||
< Compare
|
||||
, container_detail::select1st< std::pair<Key, T> >
|
||||
, container_detail::select1st<Key>
|
||||
, std::pair<Key, T> > value_compare_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::iterator iterator_impl;
|
||||
|
|
@ -1166,6 +1401,13 @@ class flat_multimap
|
|||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
public:
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
|
||||
impl_tree_t &tree()
|
||||
{ return m_flat_tree; }
|
||||
|
||||
const impl_tree_t &tree() const
|
||||
{ return m_flat_tree; }
|
||||
|
||||
private:
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
|
|
@ -1205,10 +1447,11 @@ class flat_multimap
|
|||
//! <b>Effects</b>: Default constructs an empty flat_map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
flat_multimap()
|
||||
flat_multimap() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: m_flat_tree()
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1220,7 +1463,7 @@ class flat_multimap
|
|||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1230,7 +1473,7 @@ class flat_multimap
|
|||
explicit flat_multimap(const allocator_type& a)
|
||||
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1245,7 +1488,7 @@ class flat_multimap
|
|||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1258,7 +1501,7 @@ class flat_multimap
|
|||
flat_multimap(InputIterator first, InputIterator last, const allocator_type& a)
|
||||
: m_flat_tree(false, first, last, Compare(), container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1277,7 +1520,7 @@ class flat_multimap
|
|||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1290,7 +1533,7 @@ class flat_multimap
|
|||
flat_multimap(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1302,7 +1545,7 @@ class flat_multimap
|
|||
flat_multimap(std::initializer_list<value_type> il, const allocator_type& a)
|
||||
: m_flat_tree(false, il.begin(), il.end(), Compare(), container_detail::force<impl_allocator_type>(a))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1319,7 +1562,7 @@ class flat_multimap
|
|||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1330,7 +1573,7 @@ class flat_multimap
|
|||
flat_multimap(const flat_multimap& x)
|
||||
: m_flat_tree(x.m_flat_tree)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1340,9 +1583,10 @@ class flat_multimap
|
|||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_multimap(BOOST_RV_REF(flat_multimap) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1352,7 +1596,7 @@ class flat_multimap
|
|||
flat_multimap(const flat_multimap& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1363,7 +1607,7 @@ class flat_multimap
|
|||
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
{
|
||||
//A type must be std::pair<Key, T>
|
||||
//value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
}
|
||||
|
||||
|
|
@ -1377,8 +1621,9 @@ class flat_multimap
|
|||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ m_flat_tree = boost::move(x.m_flat_tree); return *this; }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
|
@ -1798,6 +2043,38 @@ class flat_multimap
|
|||
{ m_flat_tree.insert_equal(ordered_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: this->get_allocator() == source.get_allocator().
|
||||
//!
|
||||
//! <b>Effects</b>: Extracts each element in source and insert it into a using
|
||||
//! the comparison object of *this.
|
||||
//!
|
||||
//! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
|
||||
//! to those same elements but as members of *this. Iterators referring to the transferred
|
||||
//! elements will continue to refer to their elements, but they now behave as iterators into *this,
|
||||
//! not into source.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless the comparison object throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
|
||||
template<class C2>
|
||||
void merge(flat_multimap<Key, T, C2, Allocator>& source)
|
||||
{ m_flat_tree.merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multimap<Key, T, C2, Allocator>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
void merge(flat_map<Key, T, C2, Allocator>& source)
|
||||
{ m_flat_tree.merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_map<Key, T, C2, Allocator>&>(source)); }
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns an iterator pointing to the element immediately
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@
|
|||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_multimap;
|
||||
#endif
|
||||
|
||||
//! flat_set is a Sorted Associative Container that stores objects of type Key.
|
||||
//! It is also a Unique Associative Container, meaning that no two elements are the same.
|
||||
//!
|
||||
|
|
@ -69,13 +74,21 @@ template <class Key, class Compare, class Allocator>
|
|||
#endif
|
||||
class flat_set
|
||||
///@cond
|
||||
: public container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
: public container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_set)
|
||||
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
typedef container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
|
||||
public:
|
||||
base_t &tree()
|
||||
{ return *this; }
|
||||
|
||||
const base_t &tree() const
|
||||
{ return *this; }
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
|
@ -112,7 +125,8 @@ class flat_set
|
|||
//! <b>Effects</b>: Default constructs an empty container.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_set()
|
||||
explicit flat_set() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: base_t()
|
||||
{}
|
||||
|
||||
|
|
@ -168,7 +182,7 @@ class flat_set
|
|||
flat_set(ordered_unique_range_t, InputIterator first, InputIterator last,
|
||||
const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: base_t(ordered_range, first, last, comp, a)
|
||||
: base_t(ordered_unique_range, first, last, comp, a)
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
|
@ -203,7 +217,7 @@ class flat_set
|
|||
//! <b>Note</b>: Non-standard extension.
|
||||
flat_set(ordered_unique_range_t, std::initializer_list<value_type> il,
|
||||
const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
||||
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
||||
: base_t(ordered_unique_range, il.begin(), il.end(), comp, a)
|
||||
{}
|
||||
#endif
|
||||
|
||||
|
|
@ -220,6 +234,7 @@ class flat_set
|
|||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_set(BOOST_RV_REF(flat_set) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x))
|
||||
{}
|
||||
|
||||
|
|
@ -251,8 +266,9 @@ class flat_set
|
|||
//! propagate_on_container_move_assignment is true or
|
||||
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||
flat_set& operator=(BOOST_RV_REF(flat_set) x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ return static_cast<flat_set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
|
@ -602,6 +618,26 @@ class flat_set
|
|||
{ this->base_t::insert_unique(ordered_unique_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_set<Key, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_set<Key, C2, Allocator>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_multiset<Key, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multiset<Key, C2, Allocator>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
|
|
@ -700,11 +736,10 @@ class flat_set
|
|||
//! <b>Note</b>: Non-standard extension
|
||||
const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
//! <b>Requires</b>: size() >= n.
|
||||
//! <b>Requires</b>: begin() <= p <= end().
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an iterator to the nth element
|
||||
//! from the beginning of the container. Returns end()
|
||||
//! if n == size().
|
||||
//! <b>Effects</b>: Returns the index of the element pointed by p
|
||||
//! and size() if p == end().
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
|
|
@ -865,13 +900,20 @@ template <class Key, class Compare, class Allocator>
|
|||
#endif
|
||||
class flat_multiset
|
||||
///@cond
|
||||
: public container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
: public container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
|
||||
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
typedef container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
|
||||
public:
|
||||
base_t &tree()
|
||||
{ return *this; }
|
||||
|
||||
const base_t &tree() const
|
||||
{ return *this; }
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
|
@ -899,7 +941,8 @@ class flat_multiset
|
|||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set()
|
||||
explicit flat_multiset()
|
||||
explicit flat_multiset() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: base_t()
|
||||
{}
|
||||
|
||||
|
|
@ -956,8 +999,16 @@ class flat_multiset
|
|||
: base_t(false, il.begin(), il.end(), Compare(), a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare& comp, const allocator_type&)
|
||||
flat_multiset(ordered_unique_range_t, std::initializer_list<value_type> il,
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
//! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
|
||||
//! is more efficient than the normal range creation for ordered ranges.
|
||||
//!
|
||||
//! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in N.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
flat_multiset(ordered_range_t, std::initializer_list<value_type> il,
|
||||
const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
||||
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
||||
{}
|
||||
|
|
@ -968,17 +1019,18 @@ class flat_multiset
|
|||
: base_t(static_cast<const base_t&>(x))
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set(flat_set &&)
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(flat_set &&)
|
||||
flat_multiset(BOOST_RV_REF(flat_multiset) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: base_t(boost::move(static_cast<base_t&>(x)))
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set(const flat_set &, const allocator_type &)
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(const flat_set &, const allocator_type &)
|
||||
flat_multiset(const flat_multiset& x, const allocator_type &a)
|
||||
: base_t(static_cast<const base_t&>(x), a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set(flat_set &&, const allocator_type &)
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(flat_set &&, const allocator_type &)
|
||||
flat_multiset(BOOST_RV_REF(flat_multiset) x, const allocator_type &a)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x), a)
|
||||
{}
|
||||
|
|
@ -989,8 +1041,9 @@ class flat_multiset
|
|||
|
||||
//! @copydoc ::boost::container::flat_set::operator=(flat_set &&)
|
||||
flat_multiset& operator=(BOOST_RV_REF(flat_multiset) x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ return static_cast<flat_multiset&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
|
@ -1220,6 +1273,26 @@ class flat_multiset
|
|||
{ this->base_t::insert_equal(ordered_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multiset::merge(flat_multiset<Key, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multiset<Key, C2, Allocator>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multiset::merge(flat_set<Key, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_set<Key, C2, Allocator>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::erase(const_iterator)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -29,6 +29,8 @@
|
|||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
|
||||
template<bool Value>
|
||||
struct new_allocator_bool
|
||||
{ static const bool value = Value; };
|
||||
|
|
@ -36,6 +38,8 @@ struct new_allocator_bool
|
|||
template<class T>
|
||||
class new_allocator;
|
||||
|
||||
/// @endcond
|
||||
|
||||
//! Specialization of new_allocator for void types
|
||||
template<>
|
||||
class new_allocator<void>
|
||||
|
|
@ -172,4 +176,4 @@ class new_allocator
|
|||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_ALLOCATOR_HPP
|
||||
#endif //BOOST_CONTAINER_NEW_ALLOCATOR_HPP
|
||||
|
|
|
|||
396
boost/container/node_handle.hpp
Normal file
396
boost/container/node_handle.hpp
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2016-2016. 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_NODE_HANDLE_HPP
|
||||
#define BOOST_CONTAINER_NODE_HANDLE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
|
||||
|
||||
//!\file
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
///@cond
|
||||
|
||||
template<class Value, class KeyMapped, bool keymapped_is_void = container_detail::is_same<KeyMapped, void>::value>
|
||||
struct node_handle_keymapped_traits
|
||||
{
|
||||
typedef Value key_type;
|
||||
typedef Value mapped_type;
|
||||
};
|
||||
|
||||
template<class Value, class KeyMapped>
|
||||
struct node_handle_keymapped_traits<Value, KeyMapped, false>
|
||||
{
|
||||
typedef typename KeyMapped::key_type key_type;
|
||||
typedef typename KeyMapped::mapped_type mapped_type;
|
||||
};
|
||||
|
||||
///@endcond
|
||||
|
||||
//! A node_handle is an object that accepts ownership of a single element from an associative container.
|
||||
//! It may be used to transfer that ownership to another container with compatible nodes. Containers
|
||||
//! with compatible nodes have the same node handle type. Elements may be transferred in either direction
|
||||
//! between container types in the same row:.
|
||||
//!
|
||||
//! Container types with compatible nodes
|
||||
//!
|
||||
//! map<K, T, C1, A> <-> map<K, T, C2, A>
|
||||
//!
|
||||
//! map<K, T, C1, A> <-> multimap<K, T, C2, A>
|
||||
//!
|
||||
//! set<K, C1, A> <-> set<K, C2, A>
|
||||
//!
|
||||
//! set<K, C1, A> <-> multiset<K, C2, A>
|
||||
//!
|
||||
//! If a node handle is not empty, then it contains an allocator that is equal to the allocator of the container
|
||||
//! when the element was extracted. If a node handle is empty, it contains no allocator.
|
||||
template <class NodeType, class Value, class Allocator, class KeyMapped = void>
|
||||
class node_handle
|
||||
{
|
||||
typedef node_handle_keymapped_traits<Value, KeyMapped> keymapped_t;
|
||||
|
||||
public:
|
||||
typedef Value value_type;
|
||||
typedef typename keymapped_t::key_type key_type;
|
||||
typedef typename keymapped_t::mapped_type mapped_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef NodeType container_node_type;
|
||||
|
||||
///@cond
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle)
|
||||
|
||||
typedef allocator_traits<allocator_type> ator_traits;
|
||||
typedef typename ator_traits::template portable_rebind_alloc
|
||||
<container_node_type>::type nallocator_type;
|
||||
typedef allocator_traits<nallocator_type> node_ator_traits;
|
||||
typedef typename node_ator_traits::pointer node_pointer;
|
||||
typedef ::boost::aligned_storage
|
||||
<sizeof(allocator_type), boost::alignment_of<nallocator_type>::value> nalloc_storage_t;
|
||||
|
||||
node_pointer m_ptr;
|
||||
nalloc_storage_t m_nalloc_storage;
|
||||
|
||||
void move_construct_alloc(nallocator_type &al)
|
||||
{ ::new(m_nalloc_storage.address(), boost_container_new_t()) allocator_type(::boost::move(al)); }
|
||||
|
||||
void destroy_node()
|
||||
{
|
||||
node_ator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(m_ptr));
|
||||
node_ator_traits::deallocate(this->node_alloc(), m_ptr, 1u);
|
||||
}
|
||||
|
||||
template<class OtherNodeHandle>
|
||||
void move_construct_end(OtherNodeHandle &nh)
|
||||
{
|
||||
if(m_ptr){
|
||||
::new (m_nalloc_storage.address(), boost_container_new_t()) allocator_type(::boost::move(nh.node_alloc()));
|
||||
nh.destroy_alloc();
|
||||
nh.get_node_pointer() = node_pointer();
|
||||
}
|
||||
BOOST_ASSERT(nh.empty());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void destroy_alloc()
|
||||
{ static_cast<allocator_type*>(m_nalloc_storage.address())->~allocator_type(); }
|
||||
|
||||
node_pointer &get_node_pointer()
|
||||
{ return m_ptr; }
|
||||
|
||||
nallocator_type &node_alloc()
|
||||
{ return *static_cast<nallocator_type*>(m_nalloc_storage.address()); }
|
||||
|
||||
node_pointer release()
|
||||
{
|
||||
node_pointer p(m_ptr);
|
||||
m_ptr = node_pointer();
|
||||
if(p)
|
||||
this->destroy_alloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
///@endcond
|
||||
|
||||
public:
|
||||
//! <b>Effects</b>: Initializes m_ptr to nullptr.
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->empty()
|
||||
BOOST_CXX14_CONSTEXPR node_handle() BOOST_NOEXCEPT
|
||||
: m_ptr(), m_nalloc_storage()
|
||||
{ BOOST_ASSERT(this->empty()); }
|
||||
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with p.
|
||||
//! If p != nullptr copy constructs internal allocator al.
|
||||
node_handle(node_pointer p, const nallocator_type &al) BOOST_NOEXCEPT
|
||||
: m_ptr(p), m_nalloc_storage()
|
||||
{
|
||||
if(m_ptr){
|
||||
::new (m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(al);
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with a related nh's internal pointer
|
||||
//! and assigns nullptr to the later. If nh's internal pointer was not nullptr, move constructs internal
|
||||
//! allocator with nh's internal allocator and destroy nh's internal allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: nh.empty()
|
||||
//!
|
||||
//! <b>Note</b>: Two node_handle's are related if only one of KeyMapped template parameter
|
||||
//! of a node handle is void.
|
||||
template<class KeyMapped2>
|
||||
node_handle( BOOST_RV_REF_BEG node_handle<NodeType, Value, Allocator, KeyMapped2> BOOST_RV_REF_END nh
|
||||
, typename container_detail::enable_if_c
|
||||
< ((unsigned)container_detail::is_same<KeyMapped, void>::value +
|
||||
(unsigned)container_detail::is_same<KeyMapped2, void>::value) == 1u
|
||||
>::type* = 0)
|
||||
: m_ptr(nh.get_node_pointer()), m_nalloc_storage()
|
||||
{ this->move_construct_end(nh); }
|
||||
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with nh's internal pointer
|
||||
//! and assigns nullptr to the later. If nh's internal pointer was not nullptr, move constructs internal
|
||||
//! allocator with nh's internal allocator and destroy nh's internal allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: nh.empty()
|
||||
node_handle (BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT
|
||||
: m_ptr(nh.m_ptr), m_nalloc_storage()
|
||||
{ this->move_construct_end(nh); }
|
||||
|
||||
//! <b>Effects</b>: If !this->empty(), destroys the value_type subobject in the container_node_type object
|
||||
//! pointed to by c by calling allocator_traits<impl_defined>::destroy, then deallocates m_ptr by calling
|
||||
//! ator_traits::rebind_traits<container_node_type>::deallocate.
|
||||
~node_handle () BOOST_NOEXCEPT
|
||||
{
|
||||
if(!this->empty()){
|
||||
this->destroy_node();
|
||||
this->destroy_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: Either this->empty(), or ator_traits::propagate_on_container_move_assignment is true, or
|
||||
//! node_alloc() == nh.node_alloc().
|
||||
//!
|
||||
//! <b>Effects</b>: If m_ptr != nullptr, destroys the value_type subobject in the container_node_type object
|
||||
//! pointed to by m_ptr by calling ator_traits::destroy, then deallocates m_ptr by calling ator_-
|
||||
//! traits::rebind_traits<container_node_type>::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty()
|
||||
//! or ator_traits::propagate_on_container_move_assignment is true, move assigns nh.node_alloc() to
|
||||
//! node_alloc(). Assigns nullptr to nh.m_ptr and assigns nullopt to nh.node_alloc().
|
||||
//! <b>Returns</b>: *this.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
node_handle & operator=(BOOST_RV_REF(node_handle) nh)
|
||||
{
|
||||
BOOST_ASSERT(this->empty() || nh.empty() || ator_traits::propagate_on_container_move_assignment::value
|
||||
|| ator_traits::equal(node_alloc(), nh.node_alloc()));
|
||||
|
||||
bool const was_this_non_null = !this->empty();
|
||||
bool const was_nh_non_null = !nh.empty();
|
||||
|
||||
if(was_nh_non_null){
|
||||
if(was_this_non_null){
|
||||
this->destroy_node();
|
||||
if(ator_traits::propagate_on_container_move_assignment::value){
|
||||
this->node_alloc() = ::boost::move(nh.node_alloc());
|
||||
}
|
||||
}
|
||||
else{
|
||||
this->move_construct_alloc(nh.node_alloc());
|
||||
}
|
||||
m_ptr = nh.m_ptr;
|
||||
nh.m_ptr = node_pointer();
|
||||
nh.destroy_alloc();
|
||||
}
|
||||
else if(was_this_non_null){
|
||||
this->destroy_node();
|
||||
this->destroy_alloc();
|
||||
m_ptr = node_pointer();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: empty() == false.
|
||||
//!
|
||||
//! <b>Returns</b>: A reference to the value_type subobject in the container_node_type object pointed to by m_ptr
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
value_type& value() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<KeyMapped, void>::value));
|
||||
BOOST_ASSERT(!empty());
|
||||
return m_ptr->get_data();
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: empty() == false.
|
||||
//!
|
||||
//! <b>Returns</b>: A non-const reference to the key_type member of the value_type subobject in the
|
||||
//! container_node_type object pointed to by m_ptr.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Requires</b>: Modifying the key through the returned reference is permitted.
|
||||
key_type& key() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!container_detail::is_same<KeyMapped, void>::value));
|
||||
BOOST_ASSERT(!empty());
|
||||
return const_cast<key_type &>(KeyMapped().key_of_value(m_ptr->get_data()));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: empty() == false.
|
||||
//!
|
||||
//! <b>Returns</b>: A reference to the mapped_type member of the value_type subobject
|
||||
//! in the container_node_type object pointed to by m_ptr
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
mapped_type& mapped() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!container_detail::is_same<KeyMapped, void>::value));
|
||||
BOOST_ASSERT(!empty());
|
||||
return KeyMapped().mapped_of_value(m_ptr->get_data());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: empty() == false.
|
||||
//!
|
||||
//! <b>Returns</b>: A copy of the internally hold allocator.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
return this->node_alloc();
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: m_ptr != nullptr.
|
||||
//!
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
BOOST_CONTAINER_FORCEINLINE explicit operator bool
|
||||
#else
|
||||
private: struct bool_conversion {int for_bool; int for_arg(); }; typedef int bool_conversion::* explicit_bool_arg;
|
||||
public: BOOST_CONTAINER_FORCEINLINE operator explicit_bool_arg
|
||||
#endif
|
||||
()const BOOST_NOEXCEPT
|
||||
{ return m_ptr ? &bool_conversion::for_bool : explicit_bool_arg(0); }
|
||||
|
||||
//! <b>Returns</b>: m_ptr == nullptr.
|
||||
//!
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
{
|
||||
return !this->m_ptr;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: this->empty(), or nh.empty(), or ator_traits::propagate_on_container_swap is true, or
|
||||
//! node_alloc() == nh.node_alloc().
|
||||
//!
|
||||
//! <b>Effects</b>: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or ator_traits::propagate_on_-
|
||||
//! container_swap is true calls swap(node_alloc(), nh.node_alloc()).
|
||||
void swap(node_handle &nh)
|
||||
BOOST_NOEXCEPT_IF(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value)
|
||||
{
|
||||
BOOST_ASSERT(this->empty() || nh.empty() || ator_traits::propagate_on_container_swap::value
|
||||
|| ator_traits::equal(node_alloc(), nh.node_alloc()));
|
||||
|
||||
bool const was_this_non_null = !this->empty();
|
||||
bool const was_nh_non_null = !nh.empty();
|
||||
|
||||
if(was_nh_non_null){
|
||||
if(was_this_non_null){
|
||||
if(ator_traits::propagate_on_container_swap){
|
||||
::boost::adl_move_swap(this->node_alloc(), nh.node_alloc());
|
||||
}
|
||||
}
|
||||
else{
|
||||
this->move_construct_alloc(nh.node_alloc());
|
||||
nh.destroy_alloc();
|
||||
}
|
||||
}
|
||||
else if(was_this_non_null){
|
||||
nh.move_construct_alloc(this->node_alloc());
|
||||
nh.destroy_alloc();
|
||||
}
|
||||
::boost::adl_move_swap(m_ptr, nh.m_ptr);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: x.swap(y).
|
||||
//!
|
||||
friend void swap(node_handle & x, node_handle & y) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
||||
//! A class template used to describe the results of inserting a
|
||||
//! Container::node_type in a Container with unique keys.
|
||||
//! Includes at least the following non-static public data members:
|
||||
//!
|
||||
//! <ul><li>bool inserted</li>;
|
||||
//! <li>Iterator position</li>;
|
||||
//! <li>NodeType node</li></ul>
|
||||
//!
|
||||
//! This type is MoveConstructible, MoveAssignable, DefaultConstructible,
|
||||
//! Destructible, and lvalues of that type are swappable
|
||||
template<class Iterator, class NodeType>
|
||||
struct insert_return_type_base
|
||||
{
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type_base)
|
||||
|
||||
public:
|
||||
insert_return_type_base()
|
||||
: inserted(false), position(), node()
|
||||
{}
|
||||
|
||||
insert_return_type_base(BOOST_RV_REF(insert_return_type_base) other)
|
||||
: inserted(other.inserted), position(other.position), node(boost::move(other.node))
|
||||
{}
|
||||
|
||||
template<class RelatedIt, class RelatedNode>
|
||||
insert_return_type_base(bool insert, RelatedIt it, BOOST_RV_REF(RelatedNode) node)
|
||||
: inserted(insert), position(it), node(boost::move(node))
|
||||
{}
|
||||
|
||||
insert_return_type_base & operator=(BOOST_RV_REF(insert_return_type_base) other)
|
||||
{
|
||||
inserted = other.inserted;
|
||||
position = other.position;
|
||||
node = boost::move(other.node);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool inserted;
|
||||
Iterator position;
|
||||
NodeType node;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_NODE_HANDLE_HPP
|
||||
|
|
@ -59,22 +59,22 @@ namespace container {
|
|||
//! \tparam Key is the type to be inserted in the set, which is also the key_type
|
||||
//! \tparam Compare is the comparison functor used to order keys
|
||||
//! \tparam Allocator is the allocator to be used to allocate memory for this container
|
||||
//! \tparam SetOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class SetOptions = tree_assoc_defaults >
|
||||
//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = tree_assoc_defaults >
|
||||
#else
|
||||
template <class Key, class Compare, class Allocator, class SetOptions>
|
||||
template <class Key, class Compare, class Allocator, class Options>
|
||||
#endif
|
||||
class set
|
||||
///@cond
|
||||
: public container_detail::tree
|
||||
< Key, Key, container_detail::identity<Key>, Compare, Allocator, SetOptions>
|
||||
< Key, container_detail::identity<Key>, Compare, Allocator, Options>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(set)
|
||||
typedef container_detail::tree
|
||||
< Key, Key, container_detail::identity<Key>, Compare, Allocator, SetOptions> base_t;
|
||||
< Key, container_detail::identity<Key>, Compare, Allocator, Options> base_t;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
|
@ -100,6 +100,8 @@ class set
|
|||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type) node_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::insert_return_type) insert_return_type;
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -110,7 +112,8 @@ class set
|
|||
//! <b>Effects</b>: Default constructs an empty set.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
set()
|
||||
set() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: base_t()
|
||||
{}
|
||||
|
||||
|
|
@ -215,6 +218,7 @@ class set
|
|||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
set(BOOST_RV_REF(set) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x))
|
||||
{}
|
||||
|
||||
|
|
@ -248,11 +252,15 @@ class set
|
|||
//! propagate_on_container_move_assignment is true or
|
||||
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||
set& operator=(BOOST_RV_REF(set) x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ return static_cast<set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! <b>Effects</b>: Copy all elements from il to *this.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in il.size().
|
||||
set& operator=(std::initializer_list<value_type> il)
|
||||
{
|
||||
this->clear();
|
||||
|
|
@ -517,6 +525,42 @@ class set
|
|||
{ this->base_t::insert_unique(il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::map::insert(node_type&&)
|
||||
insert_return_type insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{ return this->base_t::insert_unique_node(boost::move(nh)); }
|
||||
|
||||
//! @copydoc ::boost::container::map::insert(const_iterator, node_type&&)
|
||||
insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{ return this->base_t::insert_unique_node(hint, boost::move(nh)); }
|
||||
|
||||
//! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<Key, container_detail::identity<Key>, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_unique(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::set::merge(set<Key, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::map::merge(multimap<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<Key, container_detail::identity<Key>, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_unique(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::set::merge(multiset<Key, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
|
|
@ -708,8 +752,8 @@ class set
|
|||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class Compare, class SetOptions, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, SetOptions> >
|
||||
template <class Key, class Compare, class Options, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, Options> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
|
|
@ -734,22 +778,22 @@ namespace container {
|
|||
//! \tparam Key is the type to be inserted in the set, which is also the key_type
|
||||
//! \tparam Compare is the comparison functor used to order keys
|
||||
//! \tparam Allocator is the allocator to be used to allocate memory for this container
|
||||
//! \tparam MultiSetOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class MultiSetOptions = tree_assoc_defaults >
|
||||
//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = tree_assoc_defaults >
|
||||
#else
|
||||
template <class Key, class Compare, class Allocator, class MultiSetOptions>
|
||||
template <class Key, class Compare, class Allocator, class Options>
|
||||
#endif
|
||||
class multiset
|
||||
/// @cond
|
||||
: public container_detail::tree
|
||||
<Key, Key,container_detail::identity<Key>, Compare, Allocator, MultiSetOptions>
|
||||
<Key,container_detail::identity<Key>, Compare, Allocator, Options>
|
||||
/// @endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(multiset)
|
||||
typedef container_detail::tree
|
||||
<Key, Key,container_detail::identity<Key>, Compare, Allocator, MultiSetOptions> base_t;
|
||||
<Key,container_detail::identity<Key>, Compare, Allocator, Options> base_t;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
|
@ -776,6 +820,7 @@ class multiset
|
|||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type) node_type;
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -784,7 +829,8 @@ class multiset
|
|||
//////////////////////////////////////////////
|
||||
|
||||
//! @copydoc ::boost::container::set::set()
|
||||
multiset()
|
||||
multiset() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: base_t()
|
||||
{}
|
||||
|
||||
|
|
@ -851,17 +897,18 @@ class multiset
|
|||
: base_t(static_cast<const base_t&>(x))
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::set(set &&)
|
||||
//! @copydoc ::boost::container::set::set(set &&)
|
||||
multiset(BOOST_RV_REF(multiset) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x))
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::set(const set &, const allocator_type &)
|
||||
//! @copydoc ::boost::container::set::set(const set &, const allocator_type &)
|
||||
multiset(const multiset& x, const allocator_type &a)
|
||||
: base_t(static_cast<const base_t&>(x), a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::set(set &&, const allocator_type &)
|
||||
//! @copydoc ::boost::container::set::set(set &&, const allocator_type &)
|
||||
multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x), a)
|
||||
{}
|
||||
|
|
@ -872,8 +919,9 @@ class multiset
|
|||
|
||||
//! @copydoc ::boost::container::set::operator=(set &&)
|
||||
multiset& operator=(BOOST_RV_REF(multiset) x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ return static_cast<multiset&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
|
@ -1040,6 +1088,42 @@ class multiset
|
|||
{ this->base_t::insert_equal(il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::multimap::insert(node_type&&)
|
||||
iterator insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{ return this->base_t::insert_equal_node(boost::move(nh)); }
|
||||
|
||||
//! @copydoc ::boost::container::multimap::insert(const_iterator, node_type&&)
|
||||
iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{ return this->base_t::insert_equal_node(hint, boost::move(nh)); }
|
||||
|
||||
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<Key, container_detail::identity<Key>, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_equal(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::multiset::merge(multiset<Key, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::multimap::merge(map<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<Key, container_detail::identity<Key>, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_equal(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::multiset::merge(set<Key, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! @copydoc ::boost::container::set::erase(const_iterator)
|
||||
|
|
@ -1151,8 +1235,8 @@ class multiset
|
|||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class Compare, class Allocator, class MultiSetOptions>
|
||||
struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, MultiSetOptions> >
|
||||
template <class Key, class Compare, class Allocator, class Options>
|
||||
struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, Options> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
|
|
|
|||
|
|
@ -41,29 +41,32 @@ class static_storage_allocator
|
|||
public:
|
||||
typedef T value_type;
|
||||
|
||||
static_storage_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE static_storage_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
static_storage_allocator(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE static_storage_allocator(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
static_storage_allocator & operator=(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
BOOST_CONTAINER_FORCEINLINE static_storage_allocator & operator=(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this; }
|
||||
|
||||
T* internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE T* internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return const_cast<T*>(static_cast<const T*>(static_cast<const void*>(&storage))); }
|
||||
|
||||
T* internal_storage() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE T* internal_storage() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<T*>(static_cast<void*>(&storage)); }
|
||||
|
||||
static const std::size_t internal_capacity = N;
|
||||
|
||||
std::size_t max_size() const
|
||||
{ return N; }
|
||||
|
||||
typedef boost::container::container_detail::version_type<static_storage_allocator, 0> version;
|
||||
|
||||
friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return false; }
|
||||
|
||||
friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return true; }
|
||||
|
||||
private:
|
||||
|
|
@ -136,6 +139,9 @@ public:
|
|||
//! @brief The const reverse iterator.
|
||||
typedef typename base_t::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//! @brief The capacity/max size of the container
|
||||
static const size_type static_capacity = Capacity;
|
||||
|
||||
//! @brief Constructs an empty static_vector.
|
||||
//!
|
||||
//! @par Throws
|
||||
|
|
@ -143,7 +149,7 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Constant O(1).
|
||||
static_vector() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: base_t()
|
||||
{}
|
||||
|
||||
|
|
@ -158,7 +164,7 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
explicit static_vector(size_type count)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit static_vector(size_type count)
|
||||
: base_t(count)
|
||||
{}
|
||||
|
||||
|
|
@ -176,7 +182,7 @@ public:
|
|||
//!
|
||||
//! @par Note
|
||||
//! Non-standard extension
|
||||
static_vector(size_type count, default_init_t)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(size_type count, default_init_t)
|
||||
: base_t(count, default_init_t())
|
||||
{}
|
||||
|
||||
|
|
@ -192,7 +198,7 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
static_vector(size_type count, value_type const& value)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(size_type count, value_type const& value)
|
||||
: base_t(count, value)
|
||||
{}
|
||||
|
||||
|
|
@ -211,7 +217,7 @@ public:
|
|||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
template <typename Iterator>
|
||||
static_vector(Iterator first, Iterator last)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(Iterator first, Iterator last)
|
||||
: base_t(first, last)
|
||||
{}
|
||||
|
||||
|
|
@ -228,7 +234,7 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
static_vector(std::initializer_list<value_type> il)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(std::initializer_list<value_type> il)
|
||||
: base_t(il)
|
||||
{}
|
||||
#endif
|
||||
|
|
@ -242,7 +248,7 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
static_vector(static_vector const& other)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other)
|
||||
: base_t(other)
|
||||
{}
|
||||
|
||||
|
|
@ -258,7 +264,7 @@ public:
|
|||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
template <std::size_t C>
|
||||
static_vector(static_vector<value_type, C> const& other)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(static_vector<value_type, C> const& other)
|
||||
: base_t(other)
|
||||
{}
|
||||
|
||||
|
|
@ -272,7 +278,8 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
static_vector(BOOST_RV_REF(static_vector) other)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF(static_vector) other)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<value_type>::value)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, other))
|
||||
{}
|
||||
|
||||
|
|
@ -289,7 +296,7 @@ public:
|
|||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
template <std::size_t C>
|
||||
static_vector(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
|
||||
: base_t(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other))
|
||||
{}
|
||||
|
||||
|
|
@ -302,7 +309,7 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
static_vector & operator=(BOOST_COPY_ASSIGN_REF(static_vector) other)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_COPY_ASSIGN_REF(static_vector) other)
|
||||
{
|
||||
return static_cast<static_vector&>(base_t::operator=(static_cast<base_t const&>(other)));
|
||||
}
|
||||
|
|
@ -317,7 +324,7 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
static_vector & operator=(std::initializer_list<value_type> il)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector & operator=(std::initializer_list<value_type> il)
|
||||
{ return static_cast<static_vector&>(base_t::operator=(il)); }
|
||||
#endif
|
||||
|
||||
|
|
@ -333,7 +340,7 @@ public:
|
|||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
template <std::size_t C>
|
||||
static_vector & operator=(static_vector<value_type, C> const& other)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector & operator=(static_vector<value_type, C> const& other)
|
||||
{
|
||||
return static_cast<static_vector&>(base_t::operator=
|
||||
(static_cast<typename static_vector<value_type, C>::base_t const&>(other)));
|
||||
|
|
@ -349,7 +356,7 @@ public:
|
|||
//!
|
||||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
static_vector & operator=(BOOST_RV_REF(static_vector) other)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF(static_vector) other)
|
||||
{
|
||||
return static_cast<static_vector&>(base_t::operator=(BOOST_MOVE_BASE(base_t, other)));
|
||||
}
|
||||
|
|
@ -367,7 +374,7 @@ public:
|
|||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
template <std::size_t C>
|
||||
static_vector & operator=(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
|
||||
{
|
||||
return static_cast<static_vector&>(base_t::operator=
|
||||
(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other)));
|
||||
|
|
@ -578,7 +585,6 @@ public:
|
|||
template <typename Iterator>
|
||||
iterator insert(const_iterator p, Iterator first, Iterator last);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! @pre
|
||||
//! @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
|
||||
//! @li <tt>distance(il.begin(), il.end()) <= capacity()</tt>
|
||||
|
|
@ -594,7 +600,6 @@ public:
|
|||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
iterator insert(const_iterator p, std::initializer_list<value_type> il);
|
||||
#endif
|
||||
|
||||
//! @pre \c p must be a valid iterator of \c *this in range <tt>[begin(), end())</tt>
|
||||
//!
|
||||
|
|
@ -640,12 +645,11 @@ public:
|
|||
template <typename Iterator>
|
||||
void assign(Iterator first, Iterator last);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! @pre <tt>distance(il.begin(), il.end()) <= capacity()</tt>
|
||||
//!
|
||||
//! @brief Assigns a range <tt>[il.begin(), il.end())</tt> of Values to this container.
|
||||
//!
|
||||
//! @param first std::initializer_list with values used to construct new content of this container.
|
||||
//! @param il std::initializer_list with values used to construct new content of this container.
|
||||
//!
|
||||
//! @par Throws
|
||||
//! If Value's copy constructor or copy assignment throws,
|
||||
|
|
@ -653,7 +657,6 @@ public:
|
|||
//! @par Complexity
|
||||
//! Linear O(N).
|
||||
void assign(std::initializer_list<value_type> il);
|
||||
#endif
|
||||
|
||||
//! @pre <tt>count <= capacity()</tt>
|
||||
//!
|
||||
|
|
@ -674,6 +677,8 @@ public:
|
|||
//! @brief Inserts a Value constructed with
|
||||
//! \c std::forward<Args>(args)... in the end of the container.
|
||||
//!
|
||||
//! @return A reference to the created object.
|
||||
//!
|
||||
//! @param args The arguments of the constructor of the new element which will be created at the end of the container.
|
||||
//!
|
||||
//! @par Throws
|
||||
|
|
@ -682,7 +687,7 @@ public:
|
|||
//! @par Complexity
|
||||
//! Constant O(1).
|
||||
template<class ...Args>
|
||||
void emplace_back(Args &&...args);
|
||||
reference emplace_back(Args &&...args);
|
||||
|
||||
//! @pre
|
||||
//! @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>
|
||||
|
|
@ -809,7 +814,7 @@ public:
|
|||
//!
|
||||
//! @brief Returns the index of the element pointed by p.
|
||||
//!
|
||||
//! @param i The element's index.
|
||||
//! @param p An iterator to the element.
|
||||
//!
|
||||
//! @return The index of the element pointed by p.
|
||||
//!
|
||||
|
|
@ -824,7 +829,7 @@ public:
|
|||
//!
|
||||
//! @brief Returns the index of the element pointed by p.
|
||||
//!
|
||||
//! @param i The index of the element pointed by p.
|
||||
//! @param p A const_iterator to the element.
|
||||
//!
|
||||
//! @return a const_iterator to the i-th element.
|
||||
//!
|
||||
|
|
@ -1095,7 +1100,7 @@ public:
|
|||
bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
#else
|
||||
|
||||
friend void swap(static_vector &x, static_vector &y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend void swap(static_vector &x, static_vector &y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <stdexcept> //for std exception types
|
||||
#include <string> //for implicit std::string conversion
|
||||
#include <new> //for std::bad_alloc
|
||||
#else
|
||||
#include <boost/assert.hpp>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue