diff --git a/inst/i/b/container/adaptive_pool.hpp b/inst/i/b/container/adaptive_pool.hpp deleted file mode 100644 index f688961e1..000000000 --- a/inst/i/b/container/adaptive_pool.hpp +++ /dev/null @@ -1,623 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2005-2013. 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_ADAPTIVE_POOL_HPP -#define BOOST_CONTAINER_ADAPTIVE_POOL_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - - -namespace boost { -namespace container { - -//!An STL node allocator that uses a modified DLMalloc as memory -//!source. -//! -//!This node allocator shares a segregated storage between all instances -//!of adaptive_pool with equal sizeof(T). -//! -//!NodesPerBlock is the number of nodes allocated at once when the allocator -//!needs runs out of nodes. MaxFreeBlocks is the maximum number of totally free blocks -//!that the adaptive node pool will hold. The rest of the totally free blocks will be -//!deallocated to the memory manager. -//! -//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator: -//!(memory usable for nodes / total memory allocated from the memory allocator) -template < class T - , std::size_t NodesPerBlock BOOST_CONTAINER_DOCONLY(= ADP_nodes_per_block) - , std::size_t MaxFreeBlocks BOOST_CONTAINER_DOCONLY(= ADP_max_free_blocks) - , std::size_t OverheadPercent BOOST_CONTAINER_DOCONLY(= ADP_overhead_percent) - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I unsigned Version) - > -class adaptive_pool -{ - //!If Version is 1, the allocator is a STL conforming allocator. If Version is 2, - //!the allocator offers advanced expand in place and burst allocation capabilities. - public: - typedef unsigned int allocation_type; - typedef adaptive_pool - self_t; - - static const std::size_t nodes_per_block = NodesPerBlock; - static const std::size_t max_free_blocks = MaxFreeBlocks; - static const std::size_t overhead_percent = OverheadPercent; - static const std::size_t real_nodes_per_block = NodesPerBlock; - - BOOST_CONTAINER_DOCIGN(BOOST_STATIC_ASSERT((Version <=2))); - - public: - //------- - typedef T value_type; - typedef T * pointer; - typedef const T * const_pointer; - typedef typename ::boost::container:: - dtl::unvoid_ref::type reference; - typedef typename ::boost::container:: - dtl::unvoid_ref::type const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - typedef boost::container::dtl:: - version_type version; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef boost::container::dtl:: - basic_multiallocation_chain multiallocation_chain_void; - typedef boost::container::dtl:: - transform_multiallocation_chain - multiallocation_chain; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - //!Obtains adaptive_pool from - //!adaptive_pool - template - struct rebind - { - typedef adaptive_pool - < T2 - , NodesPerBlock - , MaxFreeBlocks - , OverheadPercent - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version) - > other; - }; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - //!Not assignable from related adaptive_pool - template - adaptive_pool& operator= - (const adaptive_pool&); - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - //!Default constructor - adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Copy constructor from other adaptive_pool. - adaptive_pool(const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Copy assignment from other adaptive_pool. - adaptive_pool & operator=(const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - { return *this; } - - //!Copy constructor from related adaptive_pool. - template - adaptive_pool - (const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Destructor - ~adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Returns the number of elements that could be allocated. - //!Never throws - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return size_type(-1)/(2u*sizeof(T)); } - - //!Allocate memory for an array of count elements. - //!Throws bad_alloc if there is no enough memory - pointer allocate(size_type count, const void * = 0) - { - if(BOOST_UNLIKELY(count > size_type(-1)/(2u*sizeof(T)))) - boost::container::throw_bad_alloc(); - - if(Version == 1 && count == 1){ - typedef typename dtl::shared_adaptive_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - return pointer(static_cast(singleton_t::instance().allocate_node())); - } - else{ - return static_cast(dlmalloc_malloc(count*sizeof(T))); - } - } - - //!Deallocate allocated memory. - //!Never throws - void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW - { - (void)count; - if(Version == 1 && count == 1){ - typedef dtl::shared_adaptive_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - singleton_t::instance().deallocate_node(ptr); - } - else{ - dlmalloc_free(ptr); - } - } - - pointer allocation_command(allocation_type command, - size_type limit_size, - size_type &prefer_in_recvd_out_size, - pointer &reuse) - { - pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); - if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))) - boost::container::throw_bad_alloc(); - return ret; - } - - //!Returns maximum the number of objects the previously allocated memory - //!pointed by p can hold. - size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW - { return dlmalloc_size(p); } - - //!Allocates just one object. Memory allocated with this function - //!must be deallocated only with deallocate_one(). - //!Throws bad_alloc if there is no enough memory - pointer allocate_one() - { - typedef dtl::shared_adaptive_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - return (pointer)singleton_t::instance().allocate_node(); - } - - //!Allocates many elements of size == 1. - //!Elements must be individually deallocated with deallocate_one() - void allocate_individual(std::size_t num_elements, multiallocation_chain &chain) - { - typedef dtl::shared_adaptive_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - singleton_t::instance().allocate_nodes(num_elements, static_cast(chain)); - //typename shared_pool_t::multiallocation_chain ch; - //singleton_t::instance().allocate_nodes(num_elements, ch); - //chain.incorporate_after - //(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size()); - } - - //!Deallocates memory previously allocated with allocate_one(). - //!You should never use deallocate_one to deallocate memory allocated - //!with other functions different from allocate_one(). Never throws - void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW - { - typedef dtl::shared_adaptive_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - singleton_t::instance().deallocate_node(p); - } - - void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW - { - typedef dtl::shared_adaptive_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - //typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size()); - //singleton_t::instance().deallocate_nodes(ch); - singleton_t::instance().deallocate_nodes(chain); - } - - //!Allocates many elements of size elem_size. - //!Elements must be individually deallocated with deallocate() - void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain) - { - BOOST_STATIC_ASSERT(( Version > 1 ));/* - dlmalloc_memchain ch; - BOOST_CONTAINER_MEMCHAIN_INIT(&ch); - if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){ - boost::container::throw_bad_alloc(); - } - chain.incorporate_after(chain.before_begin() - ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch) - ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) - ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/ - if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes - ( n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS - , move_detail::force_ptr(&chain)))){ - boost::container::throw_bad_alloc(); - } - } - - //!Allocates n_elements elements, each one of size elem_sizes[i] - //!Elements must be individually deallocated with deallocate() - void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain) - { - BOOST_STATIC_ASSERT(( Version > 1 ));/* - dlmalloc_memchain ch; - BOOST_CONTAINER_MEMCHAIN_INIT(&ch); - if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){ - boost::container::throw_bad_alloc(); - } - chain.incorporate_after(chain.before_begin() - ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch) - ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) - ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/ - if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays - ( n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS - , move_detail::force_ptr(&chain)))){ - boost::container::throw_bad_alloc(); - } - } - - void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW - {/* - dlmalloc_memchain ch; - void *beg(&*chain.begin()), *last(&*chain.last()); - size_t size(chain.size()); - BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size); - dlmalloc_multidealloc(&ch);*/ - dlmalloc_multidealloc(move_detail::force_ptr(&chain)); - } - - //!Deallocates all free blocks of the pool - static void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW - { - typedef dtl::shared_adaptive_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - singleton_t::instance().deallocate_free_blocks(); - } - - //!Swaps allocators. Does not throw. If each allocator is placed in a - //!different memory segment, the result is undefined. - friend void swap(adaptive_pool &, adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!An allocator always compares to true, as memory allocated with one - //!instance can be deallocated by another instance - friend bool operator==(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - { return true; } - - //!An allocator always compares to false, as memory allocated with one - //!instance can be deallocated by another instance - friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - { return false; } - - private: - pointer priv_allocation_command - (allocation_type command, std::size_t limit_size - ,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr) - { - std::size_t const preferred_size = prefer_in_recvd_out_size; - dlmalloc_command_ret_t ret = {0 , 0}; - if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){ - return pointer(); - } - std::size_t l_size = limit_size*sizeof(T); - std::size_t p_size = preferred_size*sizeof(T); - std::size_t r_size; - { - void* reuse_ptr_void = reuse_ptr; - ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void); - reuse_ptr = ret.second ? static_cast(reuse_ptr_void) : 0; - } - prefer_in_recvd_out_size = r_size/sizeof(T); - return (pointer)ret.first; - } -}; - - - - - - - - - - - - - - - - - - - - -template < class T - , std::size_t NodesPerBlock = ADP_nodes_per_block - , std::size_t MaxFreeBlocks = ADP_max_free_blocks - , std::size_t OverheadPercent = ADP_overhead_percent - , unsigned Version = 2 - > -class private_adaptive_pool -{ - //!If Version is 1, the allocator is a STL conforming allocator. If Version is 2, - //!the allocator offers advanced expand in place and burst allocation capabilities. - public: - typedef unsigned int allocation_type; - typedef private_adaptive_pool - self_t; - - static const std::size_t nodes_per_block = NodesPerBlock; - static const std::size_t max_free_blocks = MaxFreeBlocks; - static const std::size_t overhead_percent = OverheadPercent; - static const std::size_t real_nodes_per_block = NodesPerBlock; - - BOOST_CONTAINER_DOCIGN(BOOST_STATIC_ASSERT((Version <=2))); - - typedef dtl::private_adaptive_node_pool - pool_t; - pool_t m_pool; - - public: - //------- - typedef T value_type; - typedef T * pointer; - typedef const T * const_pointer; - typedef typename ::boost::container:: - dtl::unvoid_ref::type reference; - typedef typename ::boost::container:: - dtl::unvoid_ref::type const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - typedef boost::container::dtl:: - version_type version; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef boost::container::dtl:: - basic_multiallocation_chain multiallocation_chain_void; - typedef boost::container::dtl:: - transform_multiallocation_chain - multiallocation_chain; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - //!Obtains private_adaptive_pool from - //!private_adaptive_pool - template - struct rebind - { - typedef private_adaptive_pool - < T2 - , NodesPerBlock - , MaxFreeBlocks - , OverheadPercent - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version) - > other; - }; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - //!Not assignable from related private_adaptive_pool - template - private_adaptive_pool& operator= - (const private_adaptive_pool&); - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - //!Default constructor - private_adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Copy constructor from other private_adaptive_pool. - private_adaptive_pool(const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Copy assignment from other adaptive_pool. - private_adaptive_pool & operator=(const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - { return *this; } - - //!Copy constructor from related private_adaptive_pool. - template - private_adaptive_pool - (const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Destructor - ~private_adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Returns the number of elements that could be allocated. - //!Never throws - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return size_type(-1)/(2u*sizeof(T)); } - - //!Allocate memory for an array of count elements. - //!Throws bad_alloc if there is no enough memory - pointer allocate(size_type count, const void * = 0) - { - if(BOOST_UNLIKELY(count > size_type(-1)/(2u*sizeof(T)))) - boost::container::throw_bad_alloc(); - - if(Version == 1 && count == 1){ - return pointer(static_cast(m_pool.allocate_node())); - } - else{ - return static_cast(dlmalloc_malloc(count*sizeof(T))); - } - } - - //!Deallocate allocated memory. - //!Never throws - void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW - { - (void)count; - if(Version == 1 && count == 1){ - m_pool.deallocate_node(ptr); - } - else{ - dlmalloc_free(ptr); - } - } - - pointer allocation_command(allocation_type command, - size_type limit_size, - size_type &prefer_in_recvd_out_size, - pointer &reuse) - { - pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); - if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))) - boost::container::throw_bad_alloc(); - return ret; - } - - //!Returns maximum the number of objects the previously allocated memory - //!pointed by p can hold. - size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW - { return dlmalloc_size(p); } - - //!Allocates just one object. Memory allocated with this function - //!must be deallocated only with deallocate_one(). - //!Throws bad_alloc if there is no enough memory - pointer allocate_one() - { - return (pointer)m_pool.allocate_node(); - } - - //!Allocates many elements of size == 1. - //!Elements must be individually deallocated with deallocate_one() - void allocate_individual(std::size_t num_elements, multiallocation_chain &chain) - { - m_pool.allocate_nodes(num_elements, static_cast(chain)); - } - - //!Deallocates memory previously allocated with allocate_one(). - //!You should never use deallocate_one to deallocate memory allocated - //!with other functions different from allocate_one(). Never throws - void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW - { - m_pool.deallocate_node(p); - } - - void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW - { - m_pool.deallocate_nodes(chain); - } - - //!Allocates many elements of size elem_size. - //!Elements must be individually deallocated with deallocate() - void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain) - { - BOOST_STATIC_ASSERT(( Version > 1 )); - if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes - ( n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS - , move_detail::force_ptr(&chain)))){ - boost::container::throw_bad_alloc(); - } - } - - //!Allocates n_elements elements, each one of size elem_sizes[i] - //!Elements must be individually deallocated with deallocate() - void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain) - { - BOOST_STATIC_ASSERT(( Version > 1 )); - if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays - (n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS - , move_detail::force_ptr(&chain)))){ - boost::container::throw_bad_alloc(); - } - } - - void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW - { - dlmalloc_multidealloc(move_detail::force_ptr(&chain)); - } - - //!Deallocates all free blocks of the pool - void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW - { - m_pool.deallocate_free_blocks(); - } - - //!Swaps allocators. Does not throw. If each allocator is placed in a - //!different memory segment, the result is undefined. - friend void swap(private_adaptive_pool &, private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!An allocator always compares to true, as memory allocated with one - //!instance can be deallocated by another instance - friend bool operator==(const private_adaptive_pool &, const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - { return true; } - - //!An allocator always compares to false, as memory allocated with one - //!instance can be deallocated by another instance - friend bool operator!=(const private_adaptive_pool &, const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW - { return false; } - - private: - pointer priv_allocation_command - (allocation_type command, std::size_t limit_size - ,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr) - { - std::size_t const preferred_size = prefer_in_recvd_out_size; - dlmalloc_command_ret_t ret = {0 , 0}; - if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){ - return pointer(); - } - std::size_t l_size = limit_size*sizeof(T); - std::size_t p_size = preferred_size*sizeof(T); - std::size_t r_size; - { - void* reuse_ptr_void = reuse_ptr; - ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void); - reuse_ptr = ret.second ? static_cast(reuse_ptr_void) : 0; - } - prefer_in_recvd_out_size = r_size/sizeof(T); - return (pointer)ret.first; - } -}; - -} //namespace container { -} //namespace boost { - -#include - -#endif //#ifndef BOOST_CONTAINER_ADAPTIVE_POOL_HPP diff --git a/inst/i/b/container/deque.hpp b/inst/i/b/container/deque.hpp deleted file mode 100644 index 28b6d4106..000000000 --- a/inst/i/b/container/deque.hpp +++ /dev/null @@ -1,2374 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (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) -// -// See http://www.boost.org/libs/container for documentation. -// -////////////////////////////////////////////////////////////////////////////// -#ifndef BOOST_CONTAINER_DEQUE_HPP -#define BOOST_CONTAINER_DEQUE_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -// container -#include -#include -#include //new_allocator -#include -#include -// container/detail -#include -#include //algo_equal(), algo_lexicographical_compare -#include -#include -#include -#include -#include -#include -#include -#include -#include -// move -#include -#include -#include -#include -// move/detail -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -#include -// other -#include -// std -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -namespace boost { -namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -template -class deque; - -template -struct deque_value_traits -{ - typedef T value_type; - static const bool trivial_dctr = dtl::is_trivially_destructible::value; - static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move::value; -}; - -template -struct deque_block_size -{ - BOOST_STATIC_ASSERT_MSG(!(BlockBytes && BlockSize), "BlockBytes and BlockSize can't be specified at the same time"); - static const std::size_t block_bytes = BlockBytes ? BlockBytes : 512u; - static const std::size_t value = BlockSize ? BlockSize : (sizeof(T) < block_bytes ? (block_bytes/sizeof(T)) : std::size_t(1)); -}; - -namespace dtl { - -// Class invariants: -// For any nonsingular iterator i: -// i.node is the address of an element in the map array. The -// contents of i.node is a pointer to the beginning of a node. -// i.first == //(i.node) -// i.last == i.first + node_size -// i.cur is a pointer in the range [i.first, i.last). NOTE: -// the implication of this is that i.cur is always a dereferenceable -// pointer, even if i is a past-the-end iterator. -// Start and Finish are always nonsingular iterators. NOTE: this means -// that an empty deque must have one node, and that a deque -// with N elements, where N is the buffer size, must have two nodes. -// For every node other than start.node and finish.node, every element -// in the node is an initialized object. If start.node == finish.node, -// then [start.cur, finish.cur) are initialized objects, and -// the elements outside that range are uninitialized storage. Otherwise, -// [start.cur, start.last) and [finish.first, finish.cur) are initialized -// objects, and [start.first, start.cur) and [finish.cur, finish.last) -// are uninitialized storage. -// [map, map + map_size) is a valid, non-empty range. -// [start.node, finish.node] is a valid range contained within -// [map, map + map_size). -// A pointer in the range [map, map + map_size) points to an allocated node -// if and only if the pointer is in the range [start.node, finish.node]. -template -class deque_iterator -{ - public: - typedef std::random_access_iterator_tag iterator_category; - typedef typename boost::intrusive::pointer_traits::element_type value_type; - typedef typename boost::intrusive::pointer_traits::difference_type difference_type; - typedef typename boost::intrusive::pointer_traits::size_type size_type; - typedef typename if_c - < IsConst - , typename boost::intrusive::pointer_traits::template - rebind_pointer::type - , Pointer - >::type pointer; - typedef typename if_c - < IsConst - , const value_type& - , value_type& - >::type reference; - - class nat; - typedef typename dtl::if_c< IsConst - , deque_iterator - , nat>::type nonconst_iterator; - - typedef Pointer val_alloc_ptr; - typedef typename boost::intrusive::pointer_traits:: - template rebind_pointer::type index_pointer; - - Pointer m_cur; - Pointer m_first; - Pointer m_last; - index_pointer m_node; - - public: - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_cur() const { return m_cur; } - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_first() const { return m_first; } - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_last() const { return m_last; } - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE index_pointer get_node() const { return m_node; } - - BOOST_CONTAINER_FORCEINLINE deque_iterator(val_alloc_ptr x, index_pointer y, difference_type block_size) BOOST_NOEXCEPT_OR_NOTHROW - : m_cur(x), m_first(*y), m_last(*y + block_size), m_node(y) - {} - - BOOST_CONTAINER_FORCEINLINE deque_iterator(val_alloc_ptr x, index_pointer y, size_type block_size) BOOST_NOEXCEPT_OR_NOTHROW - : m_cur(x), m_first(*y), m_last(*y + difference_type(block_size)), m_node(y) - {} - - BOOST_CONTAINER_FORCEINLINE deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW - : m_cur(), m_first(), m_last(), m_node() //Value initialization to achieve "null iterators" (N3644) - {} - - BOOST_CONTAINER_FORCEINLINE deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW - : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node()) - {} - - BOOST_CONTAINER_FORCEINLINE deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW - : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node()) - {} - - BOOST_CONTAINER_FORCEINLINE deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW - : m_cur(cur), m_first(first), m_last(last), m_node(node) - {} - - BOOST_CONTAINER_FORCEINLINE deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW - { m_cur = x.get_cur(); m_first = x.get_first(); m_last = x.get_last(); m_node = x.get_node(); return *this; } - - BOOST_CONTAINER_FORCEINLINE deque_iterator unconst() const BOOST_NOEXCEPT_OR_NOTHROW - { - return deque_iterator(this->get_cur(), this->get_first(), this->get_last(), this->get_node()); - } - - BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW - { return *this->m_cur; } - - BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->m_cur; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW - { - if(!this->m_cur && !x.m_cur){ - return 0; - } - const difference_type block_size = m_last - m_first; - BOOST_ASSERT(block_size); - return block_size * (this->m_node - x.m_node - 1) + - (this->m_cur - this->m_first) + (x.m_last - x.m_cur); - } - - deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!!m_cur); - ++this->m_cur; - if (this->m_cur == this->m_last) { - const difference_type block_size = m_last - m_first; - BOOST_ASSERT(block_size); - this->priv_set_node(this->m_node + 1, block_size); - this->m_cur = this->m_first; - } - return *this; - } - - BOOST_CONTAINER_FORCEINLINE deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW - { - deque_iterator tmp(*this); - ++*this; - return tmp; - } - - deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!!m_cur); - if (this->m_cur == this->m_first) { - const difference_type block_size = m_last - m_first; - BOOST_ASSERT(block_size); - this->priv_set_node(this->m_node - 1, block_size); - this->m_cur = this->m_last; - } - --this->m_cur; - return *this; - } - - BOOST_CONTAINER_FORCEINLINE deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW - { - deque_iterator tmp(*this); - --*this; - return tmp; - } - - deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW - { - if (!n) - return *this; - BOOST_ASSERT(!!m_cur); - difference_type offset = n + (this->m_cur - this->m_first); - const difference_type block_size = m_last - m_first; - BOOST_ASSERT(block_size); - if (offset >= 0 && offset < block_size) - this->m_cur += difference_type(n); - else { - difference_type node_offset = - offset > 0 ? (offset / block_size) - : (-difference_type((-offset - 1) / block_size) - 1); - this->priv_set_node(this->m_node + node_offset, size_type(block_size)); - this->m_cur = this->m_first + - (offset - node_offset * block_size); - } - return *this; - } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { deque_iterator tmp(*this); return tmp += n; } - - BOOST_CONTAINER_FORCEINLINE - deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW - { return *this += -n; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { deque_iterator tmp(*this); return tmp -= n; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { return *(*this + n); } - - //Comparisons - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return l.m_cur == r.m_cur; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return l.m_cur != r.m_cur; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return r < l; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return !(r < l); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return !(l < r); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW - { return x += n; } - - BOOST_CONTAINER_FORCEINLINE void priv_set_node(index_pointer new_node, size_type block_size) BOOST_NOEXCEPT_OR_NOTHROW - { return this->priv_set_node(new_node, difference_type(block_size)); } - - BOOST_CONTAINER_FORCEINLINE void priv_set_node(index_pointer new_node, difference_type block_size) BOOST_NOEXCEPT_OR_NOTHROW - { - this->m_node = new_node; - this->m_first = *new_node; - this->m_last = this->m_first + block_size; - } -}; - -} //namespace dtl { - -template -struct get_deque_opt -{ - typedef Options type; -}; - -template<> -struct get_deque_opt -{ - typedef deque_null_opt type; -}; - -// Deque base class. It has two purposes. First, its constructor -// and destructor allocate (but don't initialize) storage. This makes -// exception safety easier. -template -class deque_base -{ - BOOST_COPYABLE_AND_MOVABLE(deque_base) - public: - typedef allocator_traits val_alloc_traits_type; - typedef typename val_alloc_traits_type::value_type val_alloc_val; - typedef typename val_alloc_traits_type::pointer val_alloc_ptr; - typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr; - typedef typename val_alloc_traits_type::reference val_alloc_ref; - typedef typename val_alloc_traits_type::const_reference val_alloc_cref; - typedef typename val_alloc_traits_type::difference_type val_alloc_diff; - typedef typename val_alloc_traits_type::size_type val_alloc_size; - typedef typename val_alloc_traits_type::template - portable_rebind_alloc::type ptr_alloc_t; - typedef allocator_traits ptr_alloc_traits_type; - typedef typename ptr_alloc_traits_type::value_type ptr_alloc_val; - typedef typename ptr_alloc_traits_type::pointer ptr_alloc_ptr; - typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr; - typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref; - typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref; - typedef Allocator allocator_type; - typedef allocator_type stored_allocator_type; - typedef val_alloc_size size_type; - typedef val_alloc_diff difference_type; - - private: - typedef typename get_deque_opt::type options_type; - - protected: - typedef dtl::deque_iterator iterator; - typedef dtl::deque_iterator const_iterator; - - BOOST_CONSTEXPR BOOST_CONTAINER_FORCEINLINE static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW - { return deque_block_size::value; } - - BOOST_CONSTEXPR BOOST_CONTAINER_FORCEINLINE static val_alloc_diff get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW - { return val_alloc_diff((get_block_size)()); } - - typedef deque_value_traits traits_t; - typedef ptr_alloc_t map_allocator_type; - - BOOST_CONTAINER_FORCEINLINE val_alloc_ptr priv_allocate_node() - { return this->alloc().allocate(get_block_size()); } - - BOOST_CONTAINER_FORCEINLINE void priv_deallocate_node(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW - { this->alloc().deallocate(p, get_block_size()); } - - BOOST_CONTAINER_FORCEINLINE ptr_alloc_ptr priv_allocate_map(size_type n) - { return this->ptr_alloc().allocate(n); } - - BOOST_CONTAINER_FORCEINLINE void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { this->ptr_alloc().deallocate(p, n); } - - BOOST_CONTAINER_FORCEINLINE deque_base(size_type num_elements, const allocator_type& a) - : members_(a) - { this->priv_initialize_map(num_elements); } - - BOOST_CONTAINER_FORCEINLINE explicit deque_base(const allocator_type& a) - : members_(a) - {} - - BOOST_CONTAINER_FORCEINLINE deque_base() - : members_() - {} - - BOOST_CONTAINER_FORCEINLINE explicit deque_base(BOOST_RV_REF(deque_base) x) - : members_( boost::move(x.ptr_alloc()) - , boost::move(x.alloc()) ) - {} - - ~deque_base() - { - if (this->members_.m_map) { - this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1); - this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size); - } - } - - private: - deque_base(const deque_base&); - - protected: - - void swap_members(deque_base &x) BOOST_NOEXCEPT_OR_NOTHROW - { - ::boost::adl_move_swap(this->members_.m_start, x.members_.m_start); - ::boost::adl_move_swap(this->members_.m_finish, x.members_.m_finish); - ::boost::adl_move_swap(this->members_.m_map, x.members_.m_map); - ::boost::adl_move_swap(this->members_.m_map_size, x.members_.m_map_size); - } - - void priv_initialize_map(size_type num_elements) - { -// if(num_elements){ - size_type num_nodes = num_elements / get_block_size() + 1; - - this->members_.m_map_size = dtl::max_value((size_type) InitialMapSize, num_nodes + 2); - this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size); - - ptr_alloc_ptr nstart = this->members_.m_map + difference_type(this->members_.m_map_size - num_nodes) / 2; - ptr_alloc_ptr nfinish = nstart + difference_type(num_nodes); - - BOOST_CONTAINER_TRY { - this->priv_create_nodes(nstart, nfinish); - } - BOOST_CONTAINER_CATCH(...){ - this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size); - this->members_.m_map = 0; - this->members_.m_map_size = 0; - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - - this->members_.m_start.priv_set_node(nstart, get_block_size()); - this->members_.m_finish.priv_set_node(nfinish - 1, get_block_size()); - this->members_.m_start.m_cur = this->members_.m_start.m_first; - this->members_.m_finish.m_cur = this->members_.m_finish.m_first + difference_type(num_elements % get_block_size()); -// } - } - - void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) - { - ptr_alloc_ptr cur = nstart; - BOOST_CONTAINER_TRY { - for (; cur < nfinish; ++cur) - *cur = this->priv_allocate_node(); - } - BOOST_CONTAINER_CATCH(...){ - this->priv_destroy_nodes(nstart, cur); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - } - - void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW - { - for (ptr_alloc_ptr n = nstart; n < nfinish; ++n) - this->priv_deallocate_node(*n); - } - - void priv_clear_map() BOOST_NOEXCEPT_OR_NOTHROW - { - if (this->members_.m_map) { - this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1); - this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size); - this->members_.m_map = 0; - this->members_.m_map_size = 0; - this->members_.m_start = iterator(); - this->members_.m_finish = this->members_.m_start; - } - } - - enum { InitialMapSize = 8 }; - - protected: - struct members_holder - : public ptr_alloc_t - , public allocator_type - { - members_holder() - : map_allocator_type(), allocator_type() - , m_map(0), m_map_size(0) - , m_start(), m_finish(m_start) - {} - - explicit members_holder(const allocator_type &a) - : map_allocator_type(a), allocator_type(a) - , m_map(0), m_map_size(0) - , m_start(), m_finish(m_start) - {} - - template - members_holder(BOOST_FWD_REF(PtrAllocConvertible) pa, BOOST_FWD_REF(ValAllocConvertible) va) - : map_allocator_type(boost::forward(pa)) - , allocator_type (boost::forward(va)) - , m_map(0), m_map_size(0) - , m_start(), m_finish(m_start) - {} - - ptr_alloc_ptr m_map; - val_alloc_size m_map_size; - iterator m_start; - iterator m_finish; - } members_; - - BOOST_CONTAINER_FORCEINLINE ptr_alloc_t &ptr_alloc() BOOST_NOEXCEPT_OR_NOTHROW - { return members_; } - - BOOST_CONTAINER_FORCEINLINE const ptr_alloc_t &ptr_alloc() const BOOST_NOEXCEPT_OR_NOTHROW - { return members_; } - - BOOST_CONTAINER_FORCEINLINE allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW - { return members_; } - - BOOST_CONTAINER_FORCEINLINE const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW - { return members_; } -}; -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -//! A double-ended queue is a sequence that supports random access to elements, constant time insertion -//! and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle. -//! -//! \tparam T The type of object that is stored in the deque -//! \tparam A The allocator used for all internal memory management, use void -//! for the default allocator -//! \tparam Options A type produced from \c boost::container::deque_options. -template -#else -template -#endif -class deque : protected deque_base::type, Options> -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - typedef deque_base::type, Options> Base; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef typename real_allocator::type ValAllocator; - typedef constant_iterator c_it; - - public: - - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - - typedef T value_type; - typedef ValAllocator allocator_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator; - typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - private: // Internal typedefs - BOOST_COPYABLE_AND_MOVABLE(deque) - typedef typename Base::ptr_alloc_ptr index_pointer; - typedef allocator_traits allocator_traits_type; - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - using Base::get_block_ssize; - - public: - - using Base::get_block_size; - - - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructors a deque. - //! - //! Throws: If allocator_type's default constructor throws. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE deque() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) - : Base() - {} - - //! Effects: Constructs a deque taking the allocator as parameter. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit deque(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW - : Base(a) - {} - - //! Effects: Constructs a deque - //! and inserts n value initialized values. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's value initialization throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE explicit deque(size_type n) - : Base(n, allocator_type()) - { - dtl::insert_value_initialized_n_proxy proxy; - proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n); - //deque_base will deallocate in case of exception... - } - - //! Effects: Constructs a deque - //! and inserts n default initialized values. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default initialization or copy constructor throws. - //! - //! Complexity: Linear to n. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_FORCEINLINE deque(size_type n, default_init_t) - : Base(n, allocator_type()) - { - dtl::insert_default_initialized_n_proxy proxy; - proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n); - //deque_base will deallocate in case of exception... - } - - //! Effects: Constructs a deque that will use a copy of allocator a - //! and inserts n value initialized values. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's value initialization throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE explicit deque(size_type n, const allocator_type &a) - : Base(n, a) - { - dtl::insert_value_initialized_n_proxy proxy; - proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n); - //deque_base will deallocate in case of exception... - } - - //! Effects: Constructs a deque that will use a copy of allocator a - //! and inserts n default initialized values. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default initialization or copy constructor throws. - //! - //! Complexity: Linear to n. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_FORCEINLINE deque(size_type n, default_init_t, const allocator_type &a) - : Base(n, a) - { - dtl::insert_default_initialized_n_proxy proxy; - proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n); - //deque_base will deallocate in case of exception... - } - - //! Effects: Constructs a deque that will use a copy of allocator a - //! and inserts n copies of value. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE deque(size_type n, const value_type& value) - : Base(n, allocator_type()) - { this->priv_fill_initialize(value); } - - //! Effects: Constructs a deque that will use a copy of allocator a - //! and inserts n copies of value. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE deque(size_type n, const value_type& value, const allocator_type& a) - : Base(n, a) - { this->priv_fill_initialize(value); } - - //! Effects: Constructs a deque that will use a copy of allocator a - //! and inserts a copy of the range [first, last) in the deque. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced InIt throws. - //! - //! Complexity: Linear to the range [first, last). - template - BOOST_CONTAINER_FORCEINLINE deque(InIt first, InIt last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::disable_if_convertible - ::type * = 0 - #endif - ) - : Base(allocator_type()) - { - this->priv_range_initialize(first, last); - } - - //! Effects: Constructs a deque that will use a copy of allocator a - //! and inserts a copy of the range [first, last) in the deque. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced InIt throws. - //! - //! Complexity: Linear to the range [first, last). - template - BOOST_CONTAINER_FORCEINLINE deque(InIt first, InIt last, const allocator_type& a - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::disable_if_convertible - ::type * = 0 - #endif - ) - : Base(a) - { - this->priv_range_initialize(first, last); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs a deque that will use a copy of allocator a - //! and inserts a copy of the range [il.begin(), il.end()) in the deque. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced std::initializer_list iterator throws. - //! - //! Complexity: Linear to the range [il.begin(), il.end()). - BOOST_CONTAINER_FORCEINLINE deque(std::initializer_list il, const allocator_type& a = allocator_type()) - : Base(a) - { - this->priv_range_initialize(il.begin(), il.end()); - } -#endif - - //! Effects: Copy constructs a deque. - //! - //! Postcondition: x == *this. - //! - //! Complexity: Linear to the elements x contains. - BOOST_CONTAINER_FORCEINLINE deque(const deque& x) - : Base(allocator_traits_type::select_on_container_copy_construction(x.alloc())) - { - if(x.size()){ - this->priv_initialize_map(x.size()); - boost::container::uninitialized_copy_alloc - (this->alloc(), x.begin(), x.end(), this->members_.m_start); - } - } - - //! Effects: Move constructor. Moves x's resources to *this. - //! - //! Throws: If allocator_type's copy constructor throws. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE deque(BOOST_RV_REF(deque) x) BOOST_NOEXCEPT_OR_NOTHROW - : Base(BOOST_MOVE_BASE(Base, x)) - { this->swap_members(x); } - - //! Effects: Copy constructs a vector using the specified allocator. - //! - //! Postcondition: x == *this. - //! - //! Throws: If allocation - //! throws or T's copy constructor throws. - //! - //! Complexity: Linear to the elements x contains. - deque(const deque& x, const allocator_type &a) - : Base(a) - { - if(x.size()){ - this->priv_initialize_map(x.size()); - boost::container::uninitialized_copy_alloc - (this->alloc(), x.begin(), x.end(), this->members_.m_start); - } - } - - //! Effects: Move constructor using the specified allocator. - //! Moves x's resources to *this if a == allocator_type(). - //! Otherwise copies values from x to *this. - //! - //! Throws: If allocation or T's copy constructor throws. - //! - //! Complexity: Constant if a == x.get_allocator(), linear otherwise. - deque(BOOST_RV_REF(deque) x, const allocator_type &a) - : Base(a) - { - if(x.alloc() == a){ - this->swap_members(x); - } - else{ - if(x.size()){ - this->priv_initialize_map(x.size()); - boost::container::uninitialized_copy_alloc - ( this->alloc(), boost::make_move_iterator(x.begin()) - , boost::make_move_iterator(x.end()), this->members_.m_start); - } - } - } - - //! Effects: Destroys the deque. All stored values are destroyed - //! and used memory is deallocated. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements. - BOOST_CONTAINER_FORCEINLINE ~deque() BOOST_NOEXCEPT_OR_NOTHROW - { - this->priv_destroy_range(this->members_.m_start, this->members_.m_finish); - } - - //! Effects: Makes *this contain the same elements as x. - //! - //! Postcondition: this->size() == x.size(). *this contains a copy - //! of each of x's elements. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to the number of elements in x. - deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x) - { - if (BOOST_LIKELY(&x != this)){ - allocator_type &this_alloc = this->alloc(); - const allocator_type &x_alloc = x.alloc(); - dtl::bool_ flag; - if(flag && this_alloc != x_alloc){ - this->clear(); - this->shrink_to_fit(); - } - dtl::assign_alloc(this->alloc(), x.alloc(), flag); - dtl::assign_alloc(this->ptr_alloc(), x.ptr_alloc(), flag); - this->assign(x.cbegin(), x.cend()); - } - return *this; - } - - //! Effects: Move assignment. All x's values are transferred to *this. - //! - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or value_type's move constructor throws) - //! - //! Complexity: Constant if allocator_traits_type:: - //! propagate_on_container_move_assignment is true or - //! this->get>allocator() == x.get_allocator(). Linear otherwise. - deque& operator= (BOOST_RV_REF(deque) x) - BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value - || allocator_traits_type::is_always_equal::value) - { - if (BOOST_LIKELY(this != &x)) { - allocator_type &this_alloc = this->alloc(); - allocator_type &x_alloc = x.alloc(); - const bool propagate_alloc = allocator_traits_type:: - propagate_on_container_move_assignment::value; - dtl::bool_ flag; - const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; - //Resources can be transferred if both allocators are - //going to be equal after this function (either propagated or already equal) - if(propagate_alloc || allocators_equal){ - //Destroy objects but retain memory in case x reuses it in the future - this->clear(); - //Move allocator if needed - dtl::move_alloc(this_alloc, x_alloc, flag); - dtl::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag); - //Nothrow swap - this->swap_members(x); - } - //Else do a one by one move - else{ - this->assign( boost::make_move_iterator(x.begin()) - , boost::make_move_iterator(x.end())); - } - } - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Makes *this contain the same elements as il. - //! - //! Postcondition: this->size() == il.size(). *this contains a copy - //! of each of x's elements. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to the number of elements in il. - BOOST_CONTAINER_FORCEINLINE deque& operator=(std::initializer_list il) - { - this->assign(il.begin(), il.end()); - return *this; - } -#endif - - //! Effects: Assigns the n copies of val to *this. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& val) - { - this->assign(c_it(val, n), c_it()); - } - - //! Effects: Assigns the the range [first, last) to *this. - //! - //! Throws: If memory allocation throws or - //! T's constructor from dereferencing InIt throws. - //! - //! Complexity: Linear to n. - template - void assign(InIt first, InIt last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::disable_if_or - < void - , dtl::is_convertible - , dtl::is_not_input_iterator - >::type * = 0 - #endif - ) - { - iterator cur = this->begin(); - for ( ; first != last && cur != end(); ++cur, ++first){ - *cur = *first; - } - if (first == last){ - this->erase(cur, this->cend()); - } - else{ - this->insert(this->cend(), first, last); - } - } - - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - void assign(FwdIt first, FwdIt last - , typename dtl::disable_if_or - < void - , dtl::is_convertible - , dtl::is_input_iterator - >::type * = 0 - ) - { - const size_type len = boost::container::iterator_udistance(first, last); - if (len > size()) { - FwdIt mid = first; - boost::container::iterator_uadvance(mid, this->size()); - boost::container::copy(first, mid, begin()); - this->insert(this->cend(), mid, last); - } - else{ - this->erase(boost::container::copy(first, last, this->begin()), cend()); - } - } - #endif - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Assigns the the range [il.begin(), il.end()) to *this. - //! - //! Throws: If memory allocation throws or - //! T's constructor from dereferencing std::initializer_list iterator throws. - //! - //! Complexity: Linear to il.size(). - BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list il) - { this->assign(il.begin(), il.end()); } -#endif - - //! Effects: Returns a copy of the internal allocator. - //! - //! Throws: If allocator's copy constructor throws. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return Base::alloc(); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return Base::alloc(); } - - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW - { return Base::alloc(); } - - //! Effects: Returns an iterator to the first element contained in the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW - { return this->members_.m_start; } - - //! Effects: Returns a const_iterator to the first element contained in the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->members_.m_start; } - - //! Effects: Returns an iterator to the end of the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator end() BOOST_NOEXCEPT_OR_NOTHROW - { return this->members_.m_finish; } - - //! Effects: Returns a const_iterator to the end of the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->members_.m_finish; } - - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW - { return reverse_iterator(this->members_.m_finish); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_reverse_iterator(this->members_.m_finish); } - - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW - { return reverse_iterator(this->members_.m_start); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_reverse_iterator(this->members_.m_start); } - - //! Effects: Returns a const_iterator to the first element contained in the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->members_.m_start; } - - //! Effects: Returns a const_iterator to the end of the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->members_.m_finish; } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_reverse_iterator(this->members_.m_finish); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_reverse_iterator(this->members_.m_start); } - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// - - //! Effects: Returns true if the deque contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->members_.m_finish == this->members_.m_start; } - - //! Effects: Returns the number of the elements contained in the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW - { return size_type(this->members_.m_finish - this->members_.m_start); } - - //! Effects: Returns the largest possible size of the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return allocator_traits_type::max_size(this->alloc()); } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are value initialized. - //! - //! Throws: If memory allocation throws, or T's constructor throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - void resize(size_type new_size) - { - const size_type len = size(); - if (new_size < len) - this->priv_erase_last_n(len - new_size); - else{ - const size_type n = new_size - this->size(); - dtl::insert_value_initialized_n_proxy proxy; - priv_insert_back_aux_impl(n, proxy); - } - } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are default initialized. - //! - //! Throws: If memory allocation throws, or T's constructor throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - //! - //! Note: Non-standard extension - void resize(size_type new_size, default_init_t) - { - const size_type len = size(); - if (new_size < len) - this->priv_erase_last_n(len - new_size); - else{ - const size_type n = new_size - this->size(); - dtl::insert_default_initialized_n_proxy proxy; - priv_insert_back_aux_impl(n, proxy); - } - } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are copy constructed from x. - //! - //! Throws: If memory allocation throws, or T's copy constructor throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - void resize(size_type new_size, const value_type& x) - { - const size_type len = size(); - if (new_size < len) - this->erase(this->members_.m_start + difference_type(new_size), this->members_.m_finish); - else - this->insert(this->members_.m_finish, new_size - len, x); - } - - //! Effects: Tries to deallocate the excess of memory created - //! with previous allocations. The size of the deque is unchanged - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Constant. - void shrink_to_fit() - { - //This deque implementation already - //deallocates excess nodes when erasing - //so there is nothing to do except for - //empty deque - if(this->empty()){ - this->priv_clear_map(); - } - } - - ////////////////////////////////////////////// - // - // element access - // - ////////////////////////////////////////////// - - //! Requires: !empty() - //! - //! Effects: Returns a reference to the first - //! element of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference front() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return *this->members_.m_start; - } - - //! Requires: !empty() - //! - //! Effects: Returns a const reference to the first element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return *this->members_.m_start; - } - - //! Requires: !empty() - //! - //! Effects: Returns a reference to the last - //! element of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference back() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return *(end()-1); - } - - //! Requires: !empty() - //! - //! Effects: Returns a const reference to the last - //! element of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return *(cend()-1); - } - - //! Requires: size() > n. - //! - //! Effects: Returns a reference to the nth element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->size() > n); - return this->members_.m_start[difference_type(n)]; - } - - //! Requires: size() > n. - //! - //! Effects: Returns a const reference to the nth element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->size() > n); - return this->members_.m_start[difference_type(n)]; - } - - //! Requires: size() >= n. - //! - //! Effects: Returns an iterator to the nth element - //! from the beginning of the container. Returns end() - //! if n == size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->size() >= n); - return iterator(this->begin()+difference_type(n)); - } - - //! Requires: size() >= n. - //! - //! Effects: Returns a const_iterator to the nth element - //! from the beginning of the container. Returns end() - //! if n == size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->size() >= n); - return const_iterator(this->cbegin()+difference_type(n)); - } - - //! Requires: begin() <= p <= end(). - //! - //! Effects: Returns the index of the element pointed by p - //! and size() if p == end(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { - //Range checked priv_index_of - return this->priv_index_of(p); - } - - //! Requires: begin() <= p <= end(). - //! - //! Effects: Returns the index of the element pointed by p - //! and size() if p == end(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW - { - //Range checked priv_index_of - return this->priv_index_of(p); - } - - //! Requires: size() > n. - //! - //! Effects: Returns a reference to the nth element - //! from the beginning of the container. - //! - //! Throws: range_error if n >= size() - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference at(size_type n) - { - this->priv_throw_if_out_of_range(n); - return (*this)[n]; - } - - //! Requires: size() > n. - //! - //! Effects: Returns a const reference to the nth element - //! from the beginning of the container. - //! - //! Throws: range_error if n >= size() - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference at(size_type n) const - { - this->priv_throw_if_out_of_range(n); - return (*this)[n]; - } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the beginning of the deque. - //! - //! Returns: A reference to the created object. - //! - //! Throws: If memory allocation throws or the in-place constructor throws. - //! - //! Complexity: Amortized constant time - template - reference emplace_front(BOOST_FWD_REF(Args)... args) - { - if(this->priv_push_front_simple_available()){ - reference r = *this->priv_push_front_simple_pos(); - allocator_traits_type::construct - ( this->alloc() - , this->priv_push_front_simple_pos() - , boost::forward(args)...); - this->priv_push_front_simple_commit(); - return r; - } - else{ - typedef dtl::insert_nonmovable_emplace_proxy type; - return *this->priv_insert_front_aux_impl(1, type(boost::forward(args)...)); - } - } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the end of the deque. - //! - //! Returns: A reference to the created object. - //! - //! Throws: If memory allocation throws or the in-place constructor throws. - //! - //! Complexity: Amortized constant time - template - reference emplace_back(BOOST_FWD_REF(Args)... args) - { - if(this->priv_push_back_simple_available()){ - reference r = *this->priv_push_back_simple_pos(); - allocator_traits_type::construct - ( this->alloc() - , this->priv_push_back_simple_pos() - , boost::forward(args)...); - this->priv_push_back_simple_commit(); - return r; - } - else{ - typedef dtl::insert_nonmovable_emplace_proxy type; - return *this->priv_insert_back_aux_impl(1, type(boost::forward(args)...)); - } - } - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... before p - //! - //! Throws: If memory allocation throws or the in-place constructor throws. - //! - //! Complexity: If p is end(), amortized constant time - //! Linear time otherwise. - template - iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - if(p == this->cbegin()){ - this->emplace_front(boost::forward(args)...); - return this->begin(); - } - else if(p == this->cend()){ - this->emplace_back(boost::forward(args)...); - return (this->end()-1); - } - else{ - typedef dtl::insert_emplace_proxy type; - return this->priv_insert_aux_impl(p, 1, type(boost::forward(args)...)); - } - } - - #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ - reference emplace_front(BOOST_MOVE_UREF##N)\ - {\ - if(priv_push_front_simple_available()){\ - reference r = *this->priv_push_front_simple_pos();\ - allocator_traits_type::construct\ - ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - priv_push_front_simple_commit();\ - return r;\ - }\ - else{\ - typedef dtl::insert_nonmovable_emplace_proxy##N\ - type;\ - return *priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\ - }\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ - reference emplace_back(BOOST_MOVE_UREF##N)\ - {\ - if(priv_push_back_simple_available()){\ - reference r = *this->priv_push_back_simple_pos();\ - allocator_traits_type::construct\ - ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - priv_push_back_simple_commit();\ - return r;\ - }\ - else{\ - typedef dtl::insert_nonmovable_emplace_proxy##N\ - type;\ - return *priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\ - }\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ - iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - BOOST_ASSERT(this->priv_in_range_or_end(p));\ - if(p == this->cbegin()){\ - this->emplace_front(BOOST_MOVE_FWD##N);\ - return this->begin();\ - }\ - else if(p == cend()){\ - this->emplace_back(BOOST_MOVE_FWD##N);\ - return (--this->end());\ - }\ - else{\ - typedef dtl::insert_emplace_proxy_arg##N\ - type;\ - return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\ - }\ - } - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE) - #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x at the front of the deque. - //! - //! Throws: If memory allocation throws or - //! T's copy constructor throws. - //! - //! Complexity: Amortized constant time. - void push_front(const T &x); - - //! Effects: Constructs a new element in the front of the deque - //! and moves the resources of x to this new element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Amortized constant time. - void push_front(T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x at the end of the deque. - //! - //! Throws: If memory allocation throws or - //! T's copy constructor throws. - //! - //! Complexity: Amortized constant time. - void push_back(const T &x); - - //! Effects: Constructs a new element in the end of the deque - //! and moves the resources of x to this new element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Amortized constant time. - void push_back(T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of x before p. - //! - //! Returns: an iterator to the inserted element. - //! - //! Throws: If memory allocation throws or x's copy constructor throws. - //! - //! Complexity: If p is end(), amortized constant time - //! Linear time otherwise. - iterator insert(const_iterator p, const T &x); - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a new element before p with x's resources. - //! - //! Returns: an iterator to the inserted element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: If p is end(), amortized constant time - //! Linear time otherwise. - iterator insert(const_iterator p, T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) - #endif - - //! Requires: pos must be a valid iterator of *this. - //! - //! Effects: Insert n copies of x before pos. - //! - //! Returns: an iterator to the first inserted element or pos if n is 0. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator pos, size_type n, const value_type& x) - { - //Range check of p is done by insert() - return this->insert(pos, c_it(x, n), c_it()); - } - - //! Requires: pos must be a valid iterator of *this. - //! - //! Effects: Insert a copy of the [first, last) range before pos. - //! - //! Returns: an iterator to the first inserted element or pos if first == last. - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced InIt throws or T's copy constructor throws. - //! - //! Complexity: Linear to distance [first, last). - template - iterator insert(const_iterator pos, InIt first, InIt last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::disable_if_or - < void - , dtl::is_convertible - , dtl::is_not_input_iterator - >::type * = 0 - #endif - ) - { - BOOST_ASSERT(this->priv_in_range_or_end(pos)); - size_type n = 0; - iterator it(pos.unconst()); - for(;first != last; ++first, ++n){ - it = this->emplace(it, *first); - ++it; - } - it -= difference_type(n); - return it; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Requires: pos must be a valid iterator of *this. - //! - //! Effects: Insert a copy of the [il.begin(), il.end()) range before pos. - //! - //! Returns: an iterator to the first inserted element or pos if il.begin() == il.end(). - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced std::initializer_list throws or T's copy constructor throws. - //! - //! Complexity: Linear to distance [il.begin(), il.end()). - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator pos, std::initializer_list il) - { - //Range check os pos is done in insert() - return insert(pos, il.begin(), il.end()); - } -#endif - - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, FwdIt first, FwdIt last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::disable_if_or - < void - , dtl::is_convertible - , dtl::is_input_iterator - >::type * = 0 - #endif - ) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - dtl::insert_range_proxy proxy(first); - return priv_insert_aux_impl(p, boost::container::iterator_udistance(first, last), proxy); - } - #endif - - //! Effects: Removes the first element from the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant time. - void pop_front() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) { - allocator_traits_type::destroy - ( this->alloc() - , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - ); - ++this->members_.m_start.m_cur; - } - else - this->priv_pop_front_aux(); - } - - //! Effects: Removes the last element from the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant time. - void pop_back() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) { - --this->members_.m_finish.m_cur; - allocator_traits_type::destroy - ( this->alloc() - , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur) - ); - } - else - this->priv_pop_back_aux(); - } - - //! Effects: Erases the element at p. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the elements between pos and the - //! last element (if pos is near the end) or the first element - //! if(pos is near the beginning). - //! Constant if pos is the first or the last element. - iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->priv_in_range(pos)); - iterator next = pos.unconst(); - ++next; - size_type index = size_type(pos - this->members_.m_start); - if (index < (this->size()/2)) { - boost::container::move_backward(this->begin(), pos.unconst(), next); - pop_front(); - } - else { - boost::container::move(next, this->end(), pos.unconst()); - pop_back(); - } - return this->members_.m_start + difference_type(index); - } - - //! Effects: Erases the elements pointed by [first, last). - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the distance between first and - //! last plus the elements between pos and the - //! last element (if pos is near the end) or the first element - //! if(pos is near the beginning). - iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(first == last || - (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last))); - if (first == this->members_.m_start && last == this->members_.m_finish) { - this->clear(); - return this->members_.m_finish; - } - else { - const size_type n = static_cast(last - first); - const size_type elems_before = static_cast(first - this->members_.m_start); - if (elems_before < (this->size() - n) - elems_before) { - boost::container::move_backward(begin(), first.unconst(), last.unconst()); - iterator new_start = this->members_.m_start + difference_type(n); - this->priv_destroy_range(this->members_.m_start, new_start); - this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node); - this->members_.m_start = new_start; - } - else { - boost::container::move(last.unconst(), end(), first.unconst()); - iterator new_finish = this->members_.m_finish - difference_type(n); - this->priv_destroy_range(new_finish, this->members_.m_finish); - this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1); - this->members_.m_finish = new_finish; - } - return this->members_.m_start + difference_type(elems_before); - } - } - - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE void swap(deque &x) - BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value - || allocator_traits_type::is_always_equal::value) - { - this->swap_members(x); - dtl::bool_ flag; - dtl::swap_alloc(this->alloc(), x.alloc(), flag); - dtl::swap_alloc(this->ptr_alloc(), x.ptr_alloc(), flag); - } - - //! Effects: Erases all the elements of the deque. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements in the deque. - void clear() BOOST_NOEXCEPT_OR_NOTHROW - { - if (this->members_.m_finish != this->members_.m_start) { - - for (index_pointer node = this->members_.m_start.m_node + 1; - node < this->members_.m_finish.m_node; - ++node) { - this->priv_destroy_range(*node, *node + get_block_ssize()); - this->priv_deallocate_node(*node); - } - - if (this->members_.m_start.m_node != this->members_.m_finish.m_node) { - this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last); - this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur); - this->priv_deallocate_node(this->members_.m_finish.m_first); - } - else - this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur); - - this->members_.m_finish = this->members_.m_start; - } - } - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const deque& x, const deque& y) - { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const deque& x, const deque& y) - { return !(x == y); } - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const deque& x, const deque& y) - { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const deque& x, const deque& y) - { return y < x; } - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const deque& x, const deque& y) - { return !(y < x); } - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const deque& x, const deque& y) - { return !(x < y); } - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE friend void swap(deque& x, deque& y) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) - { x.swap(y); } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - - BOOST_CONTAINER_FORCEINLINE size_type priv_index_of(const_iterator p) const - { - BOOST_ASSERT(this->cbegin() <= p); - BOOST_ASSERT(p <= this->cend()); - return static_cast(p - this->cbegin()); - } - - void priv_erase_last_n(size_type n) - { - if(n == this->size()) { - this->clear(); - } - else { - iterator new_finish = this->members_.m_finish - difference_type(n); - this->priv_destroy_range(new_finish, this->members_.m_finish); - this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1); - this->members_.m_finish = new_finish; - } - } - - void priv_throw_if_out_of_range(size_type n) const - { - if (n >= this->size()) - throw_out_of_range("deque::at out of range"); - } - - BOOST_CONTAINER_FORCEINLINE bool priv_in_range(const_iterator pos) const - { - return (this->begin() <= pos) && (pos < this->end()); - } - - BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const - { - return (this->begin() <= pos) && (pos <= this->end()); - } - - template - iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - if (p == cbegin()){ - this->push_front(::boost::forward(x)); - return begin(); - } - else if (p == cend()){ - this->push_back(::boost::forward(x)); - return --end(); - } - else { - return priv_insert_aux_impl - ( p, (size_type)1 - , dtl::get_insert_value_proxy(::boost::forward(x))); - } - } - - template - void priv_push_front(BOOST_FWD_REF(U) x) - { - if(this->priv_push_front_simple_available()){ - allocator_traits_type::construct - ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward(x)); - this->priv_push_front_simple_commit(); - } - else{ - priv_insert_aux_impl - ( this->cbegin(), (size_type)1 - , dtl::get_insert_value_proxy(::boost::forward(x))); - } - } - - template - void priv_push_back(BOOST_FWD_REF(U) x) - { - if(this->priv_push_back_simple_available()){ - allocator_traits_type::construct - ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward(x)); - this->priv_push_back_simple_commit(); - } - else{ - priv_insert_aux_impl - ( this->cend(), (size_type)1 - , dtl::get_insert_value_proxy(::boost::forward(x))); - } - } - - BOOST_CONTAINER_FORCEINLINE bool priv_push_back_simple_available() const - { - return this->members_.m_map && - (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1)); - } - - BOOST_CONTAINER_FORCEINLINE T *priv_push_back_simple_pos() const - { - return boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur); - } - - BOOST_CONTAINER_FORCEINLINE void priv_push_back_simple_commit() - { - ++this->members_.m_finish.m_cur; - } - - BOOST_CONTAINER_FORCEINLINE bool priv_push_front_simple_available() const - { - return this->members_.m_map && - (this->members_.m_start.m_cur != this->members_.m_start.m_first); - } - - BOOST_CONTAINER_FORCEINLINE T *priv_push_front_simple_pos() const - { return boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - 1; } - - BOOST_CONTAINER_FORCEINLINE void priv_push_front_simple_commit() - { --this->members_.m_start.m_cur; } - - void priv_destroy_range(iterator p, iterator p2) - { - if(!Base::traits_t::trivial_dctr){ - for(;p != p2; ++p){ - allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p)); - } - } - } - - void priv_destroy_range(pointer p, pointer p2) - { - if(!Base::traits_t::trivial_dctr){ - for(;p != p2; ++p){ - allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p)); - } - } - } - - template - iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy) - { - iterator pos(p.unconst()); - const size_type pos_n = size_type(p - this->cbegin()); - if(!this->members_.m_map){ - this->priv_initialize_map(0); - pos = this->begin(); - } - - const size_type elemsbefore = static_cast(pos - this->members_.m_start); - const size_type length = this->size(); - if (elemsbefore < length / 2) { - const iterator new_start = this->priv_reserve_elements_at_front(n); - const iterator old_start = this->members_.m_start; - if(!elemsbefore){ - proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n); - this->members_.m_start = new_start; - } - else{ - pos = this->members_.m_start + difference_type(elemsbefore); - if (elemsbefore >= n) { - const iterator start_n = this->members_.m_start + difference_type(n); - ::boost::container::uninitialized_move_alloc - (this->alloc(), this->members_.m_start, start_n, new_start); - this->members_.m_start = new_start; - boost::container::move(start_n, pos, old_start); - proxy.copy_n_and_update(this->alloc(), pos - difference_type(n), n); - } - else { - const size_type mid_count = n - elemsbefore; - const iterator mid_start = old_start - difference_type(mid_count); - proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count); - this->members_.m_start = mid_start; - ::boost::container::uninitialized_move_alloc - (this->alloc(), old_start, pos, new_start); - this->members_.m_start = new_start; - proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore); - } - } - } - else { - const iterator new_finish = this->priv_reserve_elements_at_back(n); - const iterator old_finish = this->members_.m_finish; - const size_type elemsafter = length - elemsbefore; - if(!elemsafter){ - proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n); - this->members_.m_finish = new_finish; - } - else{ - pos = old_finish - difference_type(elemsafter); - if (elemsafter >= n) { - iterator finish_n = old_finish - difference_type(n); - ::boost::container::uninitialized_move_alloc - (this->alloc(), finish_n, old_finish, old_finish); - this->members_.m_finish = new_finish; - boost::container::move_backward(pos, finish_n, old_finish); - proxy.copy_n_and_update(this->alloc(), pos, n); - } - else { - const size_type raw_gap = n - elemsafter; - ::boost::container::uninitialized_move_alloc - (this->alloc(), pos, old_finish, old_finish + difference_type(raw_gap)); - BOOST_CONTAINER_TRY{ - proxy.copy_n_and_update(this->alloc(), pos, elemsafter); - proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap); - } - BOOST_CONTAINER_CATCH(...){ - this->priv_destroy_range(old_finish, old_finish + difference_type(elemsafter)); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - this->members_.m_finish = new_finish; - } - } - } - return this->begin() + difference_type(pos_n); - } - - template - iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy) - { - if(!this->members_.m_map){ - this->priv_initialize_map(0); - } - - iterator new_finish = this->priv_reserve_elements_at_back(n); - iterator old_finish = this->members_.m_finish; - proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n); - this->members_.m_finish = new_finish; - return iterator(this->members_.m_finish - difference_type(n)); - } - - template - iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy) - { - if(!this->members_.m_map){ - this->priv_initialize_map(0); - } - - iterator new_start = this->priv_reserve_elements_at_front(n); - proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n); - this->members_.m_start = new_start; - return new_start; - } - - BOOST_CONTAINER_FORCEINLINE iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x) - { - return this->insert(pos, c_it(x, n), c_it()); - } - - // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized, - // but none of the deque's elements have yet been constructed. - void priv_fill_initialize(const value_type& value) - { - index_pointer cur = this->members_.m_start.m_node; - BOOST_CONTAINER_TRY { - for ( ; cur < this->members_.m_finish.m_node; ++cur){ - boost::container::uninitialized_fill_alloc - (this->alloc(), *cur, *cur + get_block_ssize(), value); - } - boost::container::uninitialized_fill_alloc - (this->alloc(), this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value); - } - BOOST_CONTAINER_CATCH(...){ - this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur, get_block_size())); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - } - - template - void priv_range_initialize(InIt first, InIt last, typename iterator_enable_if_tag::type* =0) - { - this->priv_initialize_map(0); - BOOST_CONTAINER_TRY { - for ( ; first != last; ++first) - this->emplace_back(*first); - } - BOOST_CONTAINER_CATCH(...){ - this->clear(); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - } - - template - void priv_range_initialize(FwdIt first, FwdIt last, typename iterator_disable_if_tag::type* =0) - { - size_type n = 0; - n = boost::container::iterator_udistance(first, last); - this->priv_initialize_map(n); - - index_pointer cur_node = this->members_.m_start.m_node; - BOOST_CONTAINER_TRY { - for (; cur_node < this->members_.m_finish.m_node; ++cur_node) { - FwdIt mid = first; - boost::container::iterator_uadvance(mid, get_block_size()); - ::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node); - first = mid; - } - ::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.m_first); - } - BOOST_CONTAINER_CATCH(...){ - this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node, get_block_size())); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - } - - // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first. - void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW - { - this->priv_deallocate_node(this->members_.m_finish.m_first); - this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1, get_block_size()); - this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1; - allocator_traits_type::destroy - ( this->alloc() - , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur) - ); - } - - // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that - // if the deque has at least one element (a precondition for this member - // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque - // must have at least two nodes. - void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW - { - allocator_traits_type::destroy - ( this->alloc() - , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - ); - this->priv_deallocate_node(this->members_.m_start.m_first); - this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1, get_block_size()); - this->members_.m_start.m_cur = this->members_.m_start.m_first; - } - - iterator priv_reserve_elements_at_front(size_type n) - { - size_type vacancies = size_type(this->members_.m_start.m_cur - this->members_.m_start.m_first); - if (n > vacancies){ - size_type new_elems = n-vacancies; - size_type new_nodes = (new_elems + get_block_size() - 1u) / get_block_size(); - size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map); - if (new_nodes > s){ - this->priv_reallocate_map(new_nodes, true); - } - size_type i = 1; - BOOST_CONTAINER_TRY { - for (; i <= new_nodes; ++i) - *(this->members_.m_start.m_node - difference_type(i)) = this->priv_allocate_node(); - } - BOOST_CONTAINER_CATCH(...) { - for (size_type j = 1; j < i; ++j) - this->priv_deallocate_node(*(this->members_.m_start.m_node - difference_type(j))); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - } - return this->members_.m_start - difference_type(n); - } - - iterator priv_reserve_elements_at_back(size_type n) - { - size_type vacancies = size_type(this->members_.m_finish.m_last - this->members_.m_finish.m_cur - 1); - if (n > vacancies){ - size_type new_elems = size_type(n - vacancies); - size_type new_nodes = size_type(new_elems + get_block_size() - 1u)/get_block_size(); - size_type s = (size_type)(this->members_.m_map_size - size_type(this->members_.m_finish.m_node - this->members_.m_map)); - if (new_nodes + 1 > s){ - this->priv_reallocate_map(new_nodes, false); - } - size_type i = 1; - BOOST_CONTAINER_TRY { - for (; i <= new_nodes; ++i) - *(this->members_.m_finish.m_node + difference_type(i)) = this->priv_allocate_node(); - } - BOOST_CONTAINER_CATCH(...) { - for (size_type j = 1; j < i; ++j) - this->priv_deallocate_node(*(this->members_.m_finish.m_node + difference_type(j))); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - } - return this->members_.m_finish + difference_type(n); - } - - void priv_reallocate_map(size_type nodes_to_add, bool add_at_front) - { - size_type old_num_nodes = size_type(this->members_.m_finish.m_node - this->members_.m_start.m_node + 1); - size_type new_num_nodes = old_num_nodes + nodes_to_add; - - index_pointer new_nstart; - if (this->members_.m_map_size > 2 * new_num_nodes) { - new_nstart = this->members_.m_map + difference_type(this->members_.m_map_size - new_num_nodes) / 2 - + difference_type(add_at_front ? nodes_to_add : 0u); - if (new_nstart < this->members_.m_start.m_node) - boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart); - else - boost::container::move_backward - (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + difference_type(old_num_nodes)); - } - else { - size_type new_map_size = - this->members_.m_map_size + dtl::max_value(this->members_.m_map_size, nodes_to_add) + 2; - - index_pointer new_map = this->priv_allocate_map(new_map_size); - new_nstart = new_map + difference_type(new_map_size - new_num_nodes) / 2 - + difference_type(add_at_front ? nodes_to_add : 0u); - boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart); - this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size); - - this->members_.m_map = new_map; - this->members_.m_map_size = new_map_size; - } - - this->members_.m_start.priv_set_node(new_nstart, get_block_size()); - this->members_.m_finish.priv_set_node(new_nstart + difference_type(old_num_nodes - 1u), get_block_size()); - } - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD -template -deque(InputIterator, InputIterator) -> deque::value_type>; -template -deque(InputIterator, InputIterator, Allocator const&) -> deque::value_type, Allocator>; -#endif - -}} - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -namespace boost { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef typename boost::container::deque::allocator_type allocator_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; -}; - -} - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#include - -#endif // #ifndef BOOST_CONTAINER_DEQUE_HPP diff --git a/inst/i/b/container/devector.hpp b/inst/i/b/container/devector.hpp deleted file mode 100644 index 7ecf43e9a..000000000 --- a/inst/i/b/container/devector.hpp +++ /dev/null @@ -1,2961 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Benedek Thaler 2015-2016 -// (C) Copyright Ion Gaztanaga 2019-2020. 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_DEVECTOR_HPP -#define BOOST_CONTAINER_DEVECTOR_HPP - -#include -#include - -#include // memcpy - -#include - -#include -#include //new_allocator -#include //allocator_traits -#include //equal() -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -// move -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -//std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include //for std::initializer_list -#endif - -namespace boost { -namespace container { - -#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - -struct growth_factor_60; - -template -struct get_devector_opt -{ - typedef devector_opt< typename default_if_void::type - , typename default_if_void::type - , default_if_zero::value - > type; -}; - -template -struct get_devector_opt -{ - typedef devector_opt< growth_factor_60, AllocatorSizeType, relocate_on_90::value> type; -}; - -#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - -struct reserve_only_tag_t {}; -struct reserve_uninitialized_t {}; -struct review_implementation_t {}; - -//struct unsafe_uninitialized_tag_t {}; - -/** - * A vector-like sequence container providing front and back operations - * (e.g: `push_front`/`pop_front`/`push_back`/`pop_back`) with amortized constant complexity. - * - * Models the [SequenceContainer], [ReversibleContainer], and [AllocatorAwareContainer] concepts. - * - * **Requires**: - * - `T` shall be [MoveInsertable] into the devector. - * - `T` shall be [Erasable] from any `devector`. - * - `GrowthFactor`, and `Allocator` must model the concepts with the same names or be void. - * - * **Definition**: `T` is `NothrowConstructible` if it's either nothrow move constructible or - * nothrow copy constructible. - * - * **Definition**: `T` is `NothrowAssignable` if it's either nothrow move assignable or - * nothrow copy assignable. - * - * **Exceptions**: The exception specifications assume `T` is nothrow [Destructible]. - * - * Most methods providing the strong exception guarantee assume `T` either has a move - * constructor marked noexcept or is [CopyInsertable] into the devector. If it isn't true, - * and the move constructor throws, the guarantee is waived and the effects are unspecified. - * - * In addition to the exceptions specified in the **Throws** clause, the following operations - * of `T` can throw when any of the specified concept is required: - * - [DefaultInsertable][]: Default constructor - * - [MoveInsertable][]: Move constructor - * - [CopyInsertable][]: Copy constructor - * - [DefaultConstructible][]: Default constructor - * - [EmplaceConstructible][]: Constructor selected by the given arguments - * - [MoveAssignable][]: Move assignment operator - * - [CopyAssignable][]: Copy assignment operator - * - * Furthermore, not `noexcept` methods throws whatever the allocator throws - * if memory allocation fails. Such methods also throw `length_error` if the capacity - * exceeds `max_size()`. - * - * **Remark**: If a method invalidates some iterators, it also invalidates references - * and pointers to the elements pointed by the invalidated iterators. - * - *! \tparam Options A type produced from \c boost::container::devector_options. - * - * [SequenceContainer]: http://en.cppreference.com/w/cpp/concept/SequenceContainer - * [ReversibleContainer]: http://en.cppreference.com/w/cpp/concept/ReversibleContainer - * [AllocatorAwareContainer]: http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer - * [DefaultInsertable]: http://en.cppreference.com/w/cpp/concept/DefaultInsertable - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * [Erasable]: http://en.cppreference.com/w/cpp/concept/Erasable - * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible - * [Destructible]: http://en.cppreference.com/w/cpp/concept/Destructible - * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible - * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable - * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable - */ -template < typename T, class A BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void)> -class devector -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef boost::container::allocator_traits - ::type> allocator_traits_type; - typedef typename allocator_traits_type::size_type alloc_size_type; - typedef typename get_devector_opt::type options_type; - typedef typename options_type::growth_factor_type growth_factor_type; - typedef typename options_type::stored_size_type stored_size_type; - static const std::size_t devector_min_free_fraction = - options_type::free_fraction; - - #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - // Standard Interface Types: - typedef T value_type; - typedef BOOST_CONTAINER_IMPDEF - (typename real_allocator::type) allocator_type; - typedef allocator_type stored_allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef typename allocator_traits::reference reference; - typedef typename allocator_traits::const_reference const_reference; - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::difference_type difference_type; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef BOOST_CONTAINER_IMPDEF - (boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF - (boost::container::reverse_iterator) const_reverse_iterator; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(devector) - - // Guard to deallocate buffer on exception - typedef typename detail::allocation_guard allocation_guard; - - // Random access pseudo iterator always yielding to the same result - typedef constant_iterator cvalue_iterator; - - static size_type to_internal_capacity(size_type desired_capacity) - { - const size_type rounder = devector_min_free_fraction - 2u; - const size_type divisor = devector_min_free_fraction - 1u; - size_type const nc = ((desired_capacity + rounder) / divisor) * devector_min_free_fraction; - BOOST_ASSERT(desired_capacity <= (nc - nc / devector_min_free_fraction)); - return nc; - } - - #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - // Standard Interface - public: - // construct/copy/destroy - - /** - * **Effects**: Constructs an empty devector. - * - * **Postcondition**: `empty() && front_free_capacity() == 0 - * && back_free_capacity() == 0`. - * - * **Complexity**: Constant. - */ - devector() BOOST_NOEXCEPT - : m_() - {} - - /** - * **Effects**: Constructs an empty devector, using the specified allocator. - * - * **Postcondition**: `empty() && front_free_capacity() == 0 - * && back_free_capacity() == 0`. - * - * **Complexity**: Constant. - */ - explicit devector(const allocator_type& allocator) BOOST_NOEXCEPT - : m_(allocator) - {} - - /** - * **Effects**: Constructs an empty devector, using the specified allocator - * and reserves `n` slots as if `reserve(n)` was called. - * - * **Postcondition**: `empty() && capacity() >= n`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Constant. - */ - devector(size_type n, reserve_only_tag_t, const allocator_type& allocator = allocator_type()) - : m_(reserve_only_tag_t(), allocator, to_internal_capacity(n)) - {} - - /** - * **Effects**: Constructs an empty devector, using the specified allocator - * and reserves at least `front_free_cap + back_free_cap` slots as if `reserve_front(front_cap)` and - * `reserve_back(back_cap)` was called. - * - * **Postcondition**: `empty() && front_free_capacity() >= front_free_cap - * && back_free_capacity() >= back_free_cap`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Constant. - */ - devector(size_type front_free_cap, size_type back_free_cap, reserve_only_tag_t, const allocator_type& allocator = allocator_type()) - : m_(reserve_only_tag_t(), allocator, front_free_cap, back_free_cap) - {} - - /** - * [DefaultInsertable]: http://en.cppreference.com/w/cpp/concept/DefaultInsertable - * - * **Effects**: Constructs a devector with `n` value_initialized elements using the specified allocator. - * - * **Requires**: `T` shall be [DefaultInsertable] into `*this`. - * - * **Postcondition**: `size() == n`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in `n`. - */ - explicit devector(size_type n, const allocator_type& allocator = allocator_type()) - : m_(reserve_uninitialized_t(), allocator, n) - { - allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref()); - boost::container::uninitialized_value_init_alloc_n(get_allocator_ref(), n, this->priv_raw_begin()); - buffer_guard.release(); - BOOST_ASSERT(invariants_ok()); - } - - /** - * **Effects**: Constructs a devector with `n` default-initialized elements using the specified allocator. - * - * **Requires**: `T` shall be [DefaultInsertable] into `*this`. - * - * **Postcondition**: `size() == n`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in `n`. - */ - explicit devector(size_type n, default_init_t, const allocator_type& allocator = allocator_type()) - : m_(reserve_uninitialized_t(), allocator, n) - { - allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref()); - boost::container::uninitialized_default_init_alloc_n(get_allocator_ref(), n, this->priv_raw_begin()); - buffer_guard.release(); - BOOST_ASSERT(invariants_ok()); - } - - /** - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * - * **Effects**: Constructs a devector with `n` copies of `value`, using the specified allocator. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Postcondition**: `size() == n`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in `n`. - */ - devector(size_type n, const T& value, const allocator_type& allocator = allocator_type()) - : m_(reserve_uninitialized_t(), allocator, n) - { - construct_from_range(cvalue_iterator(value, n), cvalue_iterator()); - BOOST_ASSERT(invariants_ok()); - } - - /** - * **Effects**: Constructs a devector equal to the range `[first,last)`, using the specified allocator. - * - * **Requires**: `T` shall be [EmplaceConstructible] into `*this` from `*first`. If the specified - * iterator does not meet the forward iterator requirements, `T` shall also be [MoveInsertable] - * into `*this`. - * - * **Postcondition**: `size() == boost::container::iterator_distance(first, last) - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Makes only `N` calls to the copy constructor of `T` (where `N` is the distance between `first` - * and `last`), at most one allocation and no reallocations if iterators first and last are of forward, - * bidirectional, or random access categories. It makes `O(N)` calls to the copy constructor of `T` - * and `O(log(N)) reallocations if they are just input iterators. - * - * **Remarks**: Each iterator in the range `[first,last)` shall be dereferenced exactly once, - * unless an exception is thrown. - * - * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - */ - template - devector(InputIterator first, InputIterator last, const allocator_type& allocator = allocator_type() - //Input iterators - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or - < void - BOOST_MOVE_I dtl::is_convertible - BOOST_MOVE_I dtl::is_not_input_iterator - >::type * = 0) - ) - : m_(allocator) - { - BOOST_CONTAINER_TRY{ - while (first != last) { - this->emplace_back(*first++); - } - BOOST_ASSERT(invariants_ok()); - } - BOOST_CONTAINER_CATCH(...){ - this->destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx); - this->deallocate_buffer(); - } - BOOST_CONTAINER_CATCH_END - } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - template - devector(ForwardIterator first, ForwardIterator last, const allocator_type& allocator = allocator_type() - //Other iterators - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or - < void - BOOST_MOVE_I dtl::is_convertible - BOOST_MOVE_I dtl::is_input_iterator - >::type * = 0) - ) - : m_(reserve_uninitialized_t(), allocator, boost::container::iterator_udistance(first, last)) - { - this->construct_from_range(first, last); - BOOST_ASSERT(invariants_ok()); - } - - #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - /** - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * - * **Effects**: Copy constructs a devector. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Postcondition**: `this->size() == x.size()`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `x`. - */ - devector(const devector& x) - : m_(reserve_uninitialized_t(), allocator_traits_type::select_on_container_copy_construction(x.get_allocator_ref()), x.size()) - { - this->construct_from_range(x.begin(), x.end()); - BOOST_ASSERT(invariants_ok()); - } - - /** - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * - * **Effects**: Copy constructs a devector, using the specified allocator. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Postcondition**: `*this == x`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `x`. - */ - devector(const devector& x, const allocator_type& allocator) - : m_(reserve_uninitialized_t(), allocator, x.size()) - { - this->construct_from_range(x.begin(), x.end()); - BOOST_ASSERT(invariants_ok()); - } - - /** - * **Effects**: Moves `rhs`'s resources to `*this`. - * - * **Throws**: Nothing. - * - * **Postcondition**: *this has the same value `rhs` had before the operation. - * `rhs` is left in an unspecified but valid state. - * - * **Exceptions**: Strong exception guarantee if not `noexcept`. - * - * **Complexity**: Constant. - */ - devector(BOOST_RV_REF(devector) rhs) BOOST_NOEXCEPT_OR_NOTHROW - : m_(::boost::move(rhs.m_)) - { - BOOST_ASSERT( invariants_ok()); - BOOST_ASSERT(rhs.invariants_ok()); - } - - /** - * **Effects**: Moves `rhs`'s resources to `*this`, using the specified allocator. - * - * **Throws**: If allocation or T's move constructor throws. - * - * **Postcondition**: *this has the same value `rhs` had before the operation. - * `rhs` is left in an unspecified but valid state. - * - * **Exceptions**: Strong exception guarantee if not `noexcept`. - * - * **Complexity**: Linear if allocator != rhs.get_allocator(), otherwise constant. - */ - devector(BOOST_RV_REF(devector) rhs, const allocator_type& allocator) - : m_(review_implementation_t(), allocator, rhs.m_.buffer, rhs.m_.front_idx, rhs.m_.back_idx, rhs.m_.capacity) - { - // TODO should move elems-by-elems if the two allocators differ - // buffer is already acquired, reset rhs - rhs.m_.capacity = 0u; - rhs.m_.buffer = pointer(); - rhs.m_.front_idx = 0; - rhs.m_.back_idx = 0; - BOOST_ASSERT( invariants_ok()); - BOOST_ASSERT(rhs.invariants_ok()); - } - - #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - /** - * **Equivalent to**: `devector(il.begin(), il.end(), allocator)`. - */ - devector(const std::initializer_list& il, const allocator_type& allocator = allocator_type()) - : m_(reserve_uninitialized_t(), allocator, il.size()) - { - this->construct_from_range(il.begin(), il.end()); - BOOST_ASSERT(invariants_ok()); - } - #endif - -/** - * **Effects**: Destroys the devector. All stored values are destroyed and - * used memory, if any, deallocated. - * - * **Complexity**: Linear in the size of `*this`. - */ -~devector() BOOST_NOEXCEPT -{ - destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx); - deallocate_buffer(); -} - -/** - * **Effects**: Copies elements of `x` to `*this`. Previously - * held elements get copy assigned to or destroyed. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Postcondition**: `this->size() == x.size()`, the elements of - * `*this` are copies of elements in `x` in the same order. - * - * **Returns**: `*this`. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible` - * and the allocator is allowed to be propagated - * ([propagate_on_container_copy_assignment] is true), - * Basic exception guarantee otherwise. - * - * **Complexity**: Linear in the size of `x` and `*this`. - * - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * [propagate_on_container_copy_assignment]: http://en.cppreference.com/w/cpp/memory/allocator_traits - */ - - BOOST_CONTAINER_FORCEINLINE devector& operator=(BOOST_COPY_ASSIGN_REF(devector) rhs) - { - const devector &x = rhs; - if (this == &x) { return *this; } // skip self - - BOOST_IF_CONSTEXPR(allocator_traits_type::propagate_on_container_copy_assignment::value) - { - allocator_type &this_alloc = this->get_allocator_ref(); - const allocator_type &other_alloc = x.get_allocator_ref(); - if (this_alloc != other_alloc) - { - // new allocator cannot free existing storage - this->clear(); - this->deallocate_buffer(); - m_.capacity = 0u; - m_.buffer = pointer(); - } - - this_alloc = other_alloc; - } - - size_type n = x.size(); - if (m_.capacity >= n) - { - this->overwrite_buffer(x.begin(), x.end()); - } - else - { - this->allocate_and_copy_range(x.begin(), x.end()); - } - - BOOST_ASSERT(invariants_ok()); - - return *this; - } - - /** - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * - * **Effects**: Moves elements of `x` to `*this`. Previously - * held elements get move/copy assigned to or destroyed. - * - * **Requires**: `T` shall be [MoveInsertable] into `*this`. - * - * **Postcondition**: `x` is left in an unspecified but valid state. - * - * **Returns**: `*this`. - * - * **Exceptions**: Basic exception guarantee if not `noexcept`. - * - * **Complexity**: Constant if allocator_traits_type:: - * propagate_on_container_move_assignment is true or - * this->get>allocator() == x.get_allocator(). Linear otherwise. - */ - devector& operator=(BOOST_RV_REF(devector) x) - BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value - || allocator_traits_type::is_always_equal::value) - { - BOOST_CONSTEXPR_OR_CONST bool copy_alloc = allocator_traits_type::propagate_on_container_move_assignment::value; - - BOOST_IF_CONSTEXPR (copy_alloc || get_allocator_ref() == x.get_allocator_ref()) - { - this->clear(); - this->deallocate_buffer(); - - if (copy_alloc) - { - this->get_allocator_ref() = boost::move(x.get_allocator_ref()); - } - - m_.capacity = x.m_.capacity; - m_.buffer = x.m_.buffer; - m_.front_idx = x.m_.front_idx; - m_.back_idx = x.m_.back_idx; - - // leave x in valid state - x.m_.capacity = 0u; - x.m_.buffer = pointer(); - x.m_.back_idx = x.m_.front_idx = 0; - } - else - { - // if the allocator shouldn't be copied and they do not compare equal - // we can't steal memory. - - move_iterator xbegin = boost::make_move_iterator(x.begin()); - move_iterator xend = boost::make_move_iterator(x.end()); - - if (copy_alloc) - { - get_allocator_ref() = boost::move(x.get_allocator_ref()); - } - - if (m_.capacity >= x.size()) - { - overwrite_buffer(xbegin, xend); - } - else - { - allocate_and_copy_range(xbegin, xend); - } - } - - BOOST_ASSERT(invariants_ok()); - - return *this; - } - - #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - /** - * **Effects**: Copies elements of `il` to `*this`. Previously - * held elements get copy assigned to or destroyed. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this` and [CopyAssignable]. - * - * **Postcondition**: `this->size() == il.size()`, the elements of - * `*this` are copies of elements in `il` in the same order. - * - * **Exceptions**: Strong exception guarantee if `T` is nothrow copy assignable - * from `T` and `NothrowConstructible`, Basic exception guarantee otherwise. - * - * **Returns**: `*this`. - * - * **Complexity**: Linear in the size of `il` and `*this`. - * - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable - */ - BOOST_CONTAINER_FORCEINLINE devector& operator=(std::initializer_list il) - { - this->assign(il.begin(), il.end()); - return *this; - } - #endif - - /** - * **Effects**: Replaces elements of `*this` with a copy of `[first,last)`. - * Previously held elements get copy assigned to or destroyed. - * - * **Requires**: `T` shall be [EmplaceConstructible] from `*first`. If the specified iterator - * does not meet the forward iterator requirements, `T` shall be also [MoveInsertable] into `*this`. - * - * **Precondition**: `first` and `last` are not iterators into `*this`. - * - * **Postcondition**: `size() == N`, where `N` is the distance between `first` and `last`. - * - * **Exceptions**: Strong exception guarantee if `T` is nothrow copy assignable - * from `*first` and `NothrowConstructible`, Basic exception guarantee otherwise. - * - * **Complexity**: Linear in the distance between `first` and `last`. - * Makes a single reallocation at most if the iterators `first` and `last` - * are of forward, bidirectional, or random access categories. It makes - * `O(log(N))` reallocations if they are just input iterators. - * - * **Remarks**: Each iterator in the range `[first,last)` shall be dereferenced exactly once, - * unless an exception is thrown. - * - * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - */ - template - void assign(InputIterator first, InputIterator last - //Input iterators - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or - < void - BOOST_MOVE_I dtl::is_convertible - BOOST_MOVE_I dtl::is_not_input_iterator - >::type * = 0) - ) - { - first = overwrite_buffer_impl(first, last, dtl::false_()); - while (first != last) - { - this->emplace_back(*first++); - } - } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - template - void assign(ForwardIterator first, ForwardIterator last - //Other iterators - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or - < void - BOOST_MOVE_I dtl::is_convertible - BOOST_MOVE_I dtl::is_input_iterator - >::type * = 0) - ) - { - const size_type n = boost::container::iterator_udistance(first, last); - - if (m_.capacity >= n) - { - overwrite_buffer(first, last); - } - else - { - allocate_and_copy_range(first, last); - } - - BOOST_ASSERT(invariants_ok()); - } - - #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - /** - * **Effects**: Replaces elements of `*this` with `n` copies of `u`. - * Previously held elements get copy assigned to or destroyed. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this` and - * [CopyAssignable]. - * - * **Precondition**: `u` is not a reference into `*this`. - * - * **Postcondition**: `size() == n` and the elements of - * `*this` are copies of `u`. - * - * **Exceptions**: Strong exception guarantee if `T` is nothrow copy assignable - * from `u` and `NothrowConstructible`, Basic exception guarantee otherwise. - * - * **Complexity**: Linear in `n` and the size of `*this`. - * - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable - */ - BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& u) - { - cvalue_iterator first(u, n); - cvalue_iterator last; - this->assign(first, last); - } - - #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - /** **Equivalent to**: `assign(il.begin(), il.end())`. */ - BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list il) - { - this->assign(il.begin(), il.end()); - } - #endif - - /** - * **Returns**: A copy of the allocator associated with the container. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - allocator_type get_allocator() const BOOST_NOEXCEPT - { - return static_cast(m_); - } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const allocator_type &get_stored_allocator() const BOOST_NOEXCEPT - { - return static_cast(m_); - } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - allocator_type &get_stored_allocator() BOOST_NOEXCEPT - { - return static_cast(m_); - } - - // iterators - - /** - * **Returns**: A iterator pointing to the first element in the devector, - * or the past the end iterator if the devector is empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator begin() BOOST_NOEXCEPT - { - return m_.buffer + m_.front_idx; - } - - /** - * **Returns**: A constant iterator pointing to the first element in the devector, - * or the past the end iterator if the devector is empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator begin() const BOOST_NOEXCEPT - { - return m_.buffer + m_.front_idx; - } - - /** - * **Returns**: An iterator pointing past the last element of the container. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator end() BOOST_NOEXCEPT - { - return m_.buffer + m_.back_idx; - } - - /** - * **Returns**: A constant iterator pointing past the last element of the container. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator end() const BOOST_NOEXCEPT - { - return m_.buffer + m_.back_idx; - } - - /** - * **Returns**: A reverse iterator pointing to the first element in the reversed devector, - * or the reverse past the end iterator if the devector is empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rbegin() BOOST_NOEXCEPT - { - return reverse_iterator(m_.buffer + m_.back_idx); - } - - /** - * **Returns**: A constant reverse iterator - * pointing to the first element in the reversed devector, - * or the reverse past the end iterator if the devector is empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rbegin() const BOOST_NOEXCEPT - { - return const_reverse_iterator(m_.buffer + m_.back_idx); - } - - /** - * **Returns**: A reverse iterator pointing past the last element in the - * reversed container, or to the beginning of the reversed container if it's empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rend() BOOST_NOEXCEPT - { - return reverse_iterator(m_.buffer + m_.front_idx); - } - - /** - * **Returns**: A constant reverse iterator pointing past the last element in the - * reversed container, or to the beginning of the reversed container if it's empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rend() const BOOST_NOEXCEPT - { - return const_reverse_iterator(m_.buffer + m_.front_idx); - } - - /** - * **Returns**: A constant iterator pointing to the first element in the devector, - * or the past the end iterator if the devector is empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cbegin() const BOOST_NOEXCEPT - { - return m_.buffer + m_.front_idx; - } - - /** - * **Returns**: A constant iterator pointing past the last element of the container. - * - * **Complexity**: Constant. - */ - const_iterator cend() const BOOST_NOEXCEPT - { - return m_.buffer + m_.back_idx; - } - - /** - * **Returns**: A constant reverse iterator - * pointing to the first element in the reversed devector, - * or the reverse past the end iterator if the devector is empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crbegin() const BOOST_NOEXCEPT - { - return const_reverse_iterator(m_.buffer + m_.back_idx); - } - - /** - * **Returns**: A constant reverse iterator pointing past the last element in the - * reversed container, or to the beginning of the reversed container if it's empty. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crend() const BOOST_NOEXCEPT - { - return const_reverse_iterator(m_.buffer + m_.front_idx); - } - - // capacity - - /** - * **Returns**: True, if `size() == 0`, false otherwise. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool empty() const BOOST_NOEXCEPT - { - return m_.front_idx == m_.back_idx; - } - - /** - * **Returns**: The number of elements the devector contains. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type size() const BOOST_NOEXCEPT - { - return size_type(m_.back_idx - m_.front_idx); - } - - /** - * **Returns**: The maximum number of elements the devector could possibly hold. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type max_size() const BOOST_NOEXCEPT - { - size_type alloc_max = allocator_traits_type::max_size(get_allocator_ref()); - size_type size_type_max = (size_type)-1; - return (alloc_max <= size_type_max) ? size_type(alloc_max) : size_type_max; - } - - /** - * **Returns**: The *minimum* number of elements that can be inserted into devector using - * position-based insertions without requiring a reallocation. Note that, unlike in - * typical sequence containers like `vector`, `capacity()`, `capacity()` can be smaller than `size()`. - * This can happen if a user inserts elements in a particular way (usually inserting at - * front up to front_free_capacity() and at back up to back_free_capacity()). - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type capacity() const BOOST_NOEXCEPT - { - size_type const cap_reserve = m_.capacity/devector_min_free_fraction; - return m_.capacity > cap_reserve ? (m_.capacity - cap_reserve) : 0u; - } - - /** - * **Returns**: The total number of elements that can be pushed to the front of the - * devector without requiring reallocation. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type front_free_capacity() const BOOST_NOEXCEPT - { - return m_.front_idx; - } - - /** - * **Returns**: The total number of elements that can be pushed to the back of the - * devector without requiring reallocation. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type back_free_capacity() const BOOST_NOEXCEPT - { - return size_type(m_.capacity - m_.back_idx); - } - - /** - * **Effects**: If `sz` is greater than the size of `*this`, - * additional value-initialized elements are inserted. Invalidates iterators - * if reallocation is needed. If `sz` is smaller than than the size of `*this`, - * elements are erased from the extremes. - * - * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible]. - * - * **Postcondition**: `sz == size()`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `*this` and `sz`. - * - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible - */ - BOOST_CONTAINER_FORCEINLINE void resize(size_type sz) - { - this->resize_back(sz); - } - - /** - * **Effects**: Same as resize(sz) but creates default-initialized - * value-initialized. - */ - BOOST_CONTAINER_FORCEINLINE void resize(size_type sz, default_init_t) - { - this->resize_back(sz, default_init); - } - - /** - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * - * **Effects**: If `sz` is greater than the size of `*this`, - * copies of `c` are inserted at extremes. - * If `sz` is smaller than than the size of `*this`, - * elements are popped from the extremes. - * - * **Postcondition**: `sz == size()`. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `*this` and `sz`. - */ - BOOST_CONTAINER_FORCEINLINE void resize(size_type sz, const T& c) - { - this->resize_back(sz, c); - } - - /** - * **Effects**: If `sz` is greater than the size of `*this`, - * additional value-initialized elements are inserted - * to the front. Invalidates iterators if reallocation is needed. - * If `sz` is smaller than than the size of `*this`, - * elements are popped from the front. - * - * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible]. - * - * **Postcondition**: `sz == size()`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `*this` and `sz`. - * - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible - */ - BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz) - { - resize_front_impl(sz); - BOOST_ASSERT(invariants_ok()); - } - - /** - * **Effects**: If `sz` is greater than the size of `*this`, - * additional value-initialized elements are inserted - * to the front. Invalidates iterators if reallocation is needed. - * If `sz` is smaller than than the size of `*this`, - * elements are popped from the front. - * - * **Requires**: T shall be [MoveInsertable] into *this and default_initializable. - * - * **Postcondition**: `sz == size()`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `*this` and `sz`. - * - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - */ - BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz, default_init_t) - { - resize_front_impl(sz, default_init); - BOOST_ASSERT(invariants_ok()); - } - - /** - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * - * **Effects**: If `sz` is greater than the size of `*this`, - * copies of `c` are inserted to the front. - * Invalidates iterators if reallocation is needed. - * If `sz` is smaller than than the size of `*this`, - * elements are popped from the front. - * - * **Postcondition**: `sz == size()`. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `*this` and `sz`. - */ - BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz, const T& c) - { - resize_front_impl(sz, c); - BOOST_ASSERT(invariants_ok()); - } - - /** - * **Effects**: If `sz` is greater than the size of `*this`, - * additional value-initialized elements are inserted - * to the back. Invalidates iterators if reallocation is needed. - * If `sz` is smaller than than the size of `*this`, - * elements are popped from the back. - * - * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible]. - * - * **Postcondition**: `sz == size()`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `*this` and `sz`. - * - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible - */ - BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz) - { - resize_back_impl(sz); - BOOST_ASSERT(invariants_ok()); - } - - /** - * **Effects**: If `sz` is greater than the size of `*this`, - * additional value-initialized elements are inserted - * to the back. Invalidates iterators if reallocation is needed. - * If `sz` is smaller than than the size of `*this`, - * elements are popped from the back. - * - * **Requires**: T shall be [MoveInsertable] into *this and default initializable. - * - * **Postcondition**: `sz == size()`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `*this` and `sz`. - * - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - */ - BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz, default_init_t) - { - resize_back_impl(sz, default_init); - BOOST_ASSERT(invariants_ok()); - } - - /** - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * - * **Effects**: If `sz` is greater than the size of `*this`, - * copies of `c` are inserted to the back. - * If `sz` is smaller than than the size of `*this`, - * elements are popped from the back. - * - * **Postcondition**: `sz == size()`. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of `*this` and `sz`. - */ - BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz, const T& c) - { - resize_back_impl(sz, c); - BOOST_ASSERT(invariants_ok()); - } - - /** - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * - * **Effects**: Ensures that at least `n` elements can be inserted - * without requiring reallocation, where `n` is `new_capacity - size()`, - * if `n` is positive. Otherwise, there are no effects. - * Invalidates iterators if reallocation is needed. - * - * **Requires**: `T` shall be [MoveInsertable] into `*this`. - * - * **Complexity**: Linear in the size of *this. - * - * **Exceptions**: Strong exception guarantee. - * - * **Throws**: length_error if `new_capacity > max_size()`. - */ - BOOST_CONTAINER_FORCEINLINE void reserve(size_type new_capacity) - { - if (this->capacity() < new_capacity) { - const size_type rounder = devector_min_free_fraction - 2u; - const size_type divisor = devector_min_free_fraction - 1u; - size_type const nc = ((new_capacity + rounder)/divisor)*devector_min_free_fraction; - BOOST_ASSERT(new_capacity <= (nc - nc / devector_min_free_fraction)); - size_type const sz = this->size(); - reallocate_at(nc, (nc-sz)/2u); - } - BOOST_ASSERT(invariants_ok()); - } - - /** - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * - * **Effects**: Ensures that `n` elements can be pushed to the front - * without requiring reallocation, where `n` is `new_capacity - size()`, - * if `n` is positive. Otherwise, there are no effects. - * Invalidates iterators if reallocation is needed. - * - * **Requires**: `T` shall be [MoveInsertable] into `*this`. - * - * **Complexity**: Linear in the size of *this. - * - * **Exceptions**: Strong exception guarantee. - * - * **Throws**: `length_error` if `new_capacity > max_size()`. - */ - BOOST_CONTAINER_FORCEINLINE void reserve_front(size_type new_capacity) - { - if (front_capacity() >= new_capacity) { return; } - - reallocate_at(new_capacity + back_free_capacity(), new_capacity - size()); - - BOOST_ASSERT(invariants_ok()); - } - - /** - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * - * **Effects**: Ensures that `n` elements can be pushed to the back - * without requiring reallocation, where `n` is `new_capacity - size()`, - * if `n` is positive. Otherwise, there are no effects. - * Invalidates iterators if reallocation is needed. - * - * **Requires**: `T` shall be [MoveInsertable] into `*this`. - * - * **Complexity**: Linear in the size of *this. - * - * **Exceptions**: Strong exception guarantee. - * - * **Throws**: length_error if `new_capacity > max_size()`. - */ - BOOST_CONTAINER_FORCEINLINE void reserve_back(size_type new_capacity) - { - if (back_capacity() >= new_capacity) { return; } - - reallocate_at(new_capacity + front_free_capacity(), m_.front_idx); - - BOOST_ASSERT(invariants_ok()); - } - - - /** - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * - * **Effects**: Reduces `capacity()` to `size()`. Invalidates iterators. - * - * **Requires**: `T` shall be [MoveInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Linear in the size of *this. - */ - BOOST_CONTAINER_FORCEINLINE void shrink_to_fit() - { - if(this->front_capacity() || this->back_capacity()) - this->reallocate_at(size(), 0); - } - - // element access: - - /** - * **Returns**: A reference to the `n`th element in the devector. - * - * **Precondition**: `n < size()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference operator[](size_type n) BOOST_NOEXCEPT - { - BOOST_ASSERT(n < size()); - return m_.buffer[m_.front_idx + n]; - } - - /** - * **Returns**: A constant reference to the `n`th element in the devector. - * - * **Precondition**: `n < size()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference operator[](size_type n) const BOOST_NOEXCEPT - { - BOOST_ASSERT(n < size()); - return m_.buffer[m_.front_idx + n]; - } - - /** - * **Returns**: A reference to the `n`th element in the devector. - * - * **Throws**: `out_of_range`, if `n >= size()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference at(size_type n) - { - if (size() <= n) - throw_out_of_range("devector::at out of range"); - return (*this)[n]; - } - - /** - * **Returns**: A constant reference to the `n`th element in the devector. - * - * **Throws**: `out_of_range`, if `n >= size()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference at(size_type n) const - { - if (size() <= n) - throw_out_of_range("devector::at out of range"); - return (*this)[n]; - } - - /** - * **Returns**: A reference to the first element in the devector. - * - * **Precondition**: `!empty()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference front() BOOST_NOEXCEPT - { - BOOST_ASSERT(!empty()); - - return m_.buffer[m_.front_idx]; - } - - /** - * **Returns**: A constant reference to the first element in the devector. - * - * **Precondition**: `!empty()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference front() const BOOST_NOEXCEPT - { - BOOST_ASSERT(!empty()); - - return m_.buffer[m_.front_idx]; - } - - /** - * **Returns**: A reference to the last element in the devector. - * - * **Precondition**: `!empty()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference back() BOOST_NOEXCEPT - { - BOOST_ASSERT(!empty()); - - return m_.buffer[m_.back_idx - 1u]; - } - - /** - * **Returns**: A constant reference to the last element in the devector. - * - * **Precondition**: `!empty()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference back() const BOOST_NOEXCEPT - { - BOOST_ASSERT(!empty()); - - return m_.buffer[m_.back_idx - 1u]; - } - - /** - * **Returns**: A pointer to the underlying array serving as element storage. - * The range `[data(); data() + size())` is always valid. For a non-empty devector, - * `data() == &front()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - T* data() BOOST_NOEXCEPT - { - return boost::movelib::to_raw_pointer(m_.buffer) + m_.front_idx; - } - - /** - * **Returns**: A constant pointer to the underlying array serving as element storage. - * The range `[data(); data() + size())` is always valid. For a non-empty devector, - * `data() == &front()`. - * - * **Complexity**: Constant. - */ - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const T* data() const BOOST_NOEXCEPT - { - return boost::movelib::to_raw_pointer(m_.buffer) + m_.front_idx; - } - - // modifiers: - - /** - * **Effects**: Pushes a new element to the front of the devector. - * The element is constructed in-place, using the perfect forwarded `args` - * as constructor arguments. Invalidates iterators if reallocation is needed. - * (`front_free_capacity() == 0`) - * - * **Requires**: `T` shall be [EmplaceConstructible] from `args` and [MoveInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Amortized constant in the size of `*this`. - * (Constant, if `front_free_capacity() > 0`) - * - * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - */ - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - reference emplace_front(Args&&... args) - { - if (BOOST_LIKELY(front_free_capacity() != 0)) // fast path - { - pointer const p = m_.buffer + (m_.front_idx - 1u); - this->alloc_construct(p, boost::forward(args)...); - --m_.front_idx; - BOOST_ASSERT(invariants_ok()); - return *p; - } - else - { - typedef dtl::insert_emplace_proxy proxy_t; - return *this->insert_range_slow_path(this->begin(), 1, proxy_t(::boost::forward(args)...)); - } - } - - #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #define BOOST_CONTAINER_DEVECTOR_EMPLACE_FRONT(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE reference emplace_front(BOOST_MOVE_UREF##N)\ - {\ - if (front_free_capacity())\ - {\ - pointer const p = m_.buffer + (m_.front_idx - 1u);\ - this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - --m_.front_idx;\ - return *p;\ - }\ - else\ - {\ - typedef dtl::insert_emplace_proxy_arg##N proxy_t;\ - return *this->insert_range_slow_path(this->begin(), 1, proxy_t(BOOST_MOVE_FWD##N));\ - }\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE_FRONT) - #undef BOOST_CONTAINER_DEVECTOR_EMPLACE_FRONT - - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - /** - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * - * **Effects**: Pushes the copy of `x` to the front of the devector. - * Invalidates iterators if reallocation is needed. - * (`front_free_capacity() == 0`) - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Amortized constant in the size of `*this`. - * (Constant, if `front_free_capacity() > 0`) - */ - void push_front(const T& x); - - /** - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * - * **Effects**: Move constructs a new element at the front of the devector using `x`. - * Invalidates iterators if reallocation is needed. - * (`front_free_capacity() == 0`) - * - * **Requires**: `T` shall be [MoveInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee, not regarding the state of `x`. - * - * **Complexity**: Amortized constant in the size of `*this`. - * (Constant, if `front_free_capacity() > 0`) - */ - void push_front(T&& x); - - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front) - #endif - - /** - * **Effects**: Removes the first element of `*this`. - * - * **Precondition**: `!empty()`. - * - * **Postcondition**: `front_free_capacity()` is incremented by 1. - * - * **Complexity**: Constant. - */ - void pop_front() BOOST_NOEXCEPT - { - BOOST_ASSERT(!empty()); - allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(m_.buffer + m_.front_idx)); - ++m_.front_idx; - BOOST_ASSERT(invariants_ok()); - } - - /** - * **Effects**: Pushes a new element to the back of the devector. - * The element is constructed in-place, using the perfect forwarded `args` - * as constructor arguments. Invalidates iterators if reallocation is needed. - * (`back_free_capacity() == 0`) - * - * **Requires**: `T` shall be [EmplaceConstructible] from `args` and [MoveInsertable] into `*this`, - * and [MoveAssignable]. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Amortized constant in the size of `*this`. - * (Constant, if `back_free_capacity() > 0`) - * - * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable - */ - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - BOOST_CONTAINER_FORCEINLINE reference emplace_back(Args&&... args) - { - if (BOOST_LIKELY(this->back_free_capacity() != 0)){ - pointer const p = m_.buffer + m_.back_idx; - this->alloc_construct(p, boost::forward(args)...); - ++m_.back_idx; - BOOST_ASSERT(invariants_ok()); - return *p; - } - else { - typedef dtl::insert_emplace_proxy proxy_t; - return *this->insert_range_slow_path(this->end(), 1, proxy_t(::boost::forward(args)...)); - } - } - - #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #define BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_MOVE_UREF##N)\ - {\ - if (this->back_free_capacity()){\ - pointer const p = m_.buffer + m_.back_idx;\ - this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - ++m_.back_idx;\ - return *p;\ - }\ - else {\ - typedef dtl::insert_emplace_proxy_arg##N proxy_t;\ - return *this->insert_range_slow_path(this->end(), 1, proxy_t(BOOST_MOVE_FWD##N));\ - }\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK) - #undef BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK - - #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - /** - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * - * **Effects**: Pushes the copy of `x` to the back of the devector. - * Invalidates iterators if reallocation is needed. - * (`back_free_capacity() == 0`) - * - * **Requires**: `T` shall be [CopyInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee. - * - * **Complexity**: Amortized constant in the size of `*this`. - * (Constant, if `back_free_capacity() > 0`) - */ - void push_back(const T& x); - - /** - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * - * **Effects**: Move constructs a new element at the back of the devector using `x`. - * Invalidates iterators if reallocation is needed. - * (`back_free_capacity() == 0`) - * - * **Requires**: `T` shall be [MoveInsertable] into `*this`. - * - * **Exceptions**: Strong exception guarantee, not regarding the state of `x`. - * - * **Complexity**: Amortized constant in the size of `*this`. - * (Constant, if `back_free_capacity() > 0`) - */ - void push_back(T&& x); - - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) - #endif - - /** - * **Effects**: Removes the last element of `*this`. - * - * **Precondition**: `!empty()`. - * - * **Postcondition**: `back_free_capacity()` is incremented by 1. - * - * **Complexity**: Constant. - */ - void pop_back() BOOST_NOEXCEPT - { - BOOST_ASSERT(! empty()); - --m_.back_idx; - allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(m_.buffer + m_.back_idx)); - BOOST_ASSERT(invariants_ok()); - } - - /** - * **Effects**: Constructs a new element before the element pointed by `position`. - * The element is constructed in-place, using the perfect forwarded `args` - * as constructor arguments. Invalidates iterators if reallocation is needed. - * - * **Requires**: `T` shall be [EmplaceConstructible], and [MoveInsertable] into `*this`, - * and [MoveAssignable]. - * - * **Returns**: Iterator pointing to the newly constructed element. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible` - * and `NothrowAssignable`, Basic exception guarantee otherwise. - * - * **Complexity**: Linear in the size of `*this`. - * - * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable - */ - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - iterator emplace(const_iterator position, Args&&... args) - { - BOOST_ASSERT(position >= begin()); - BOOST_ASSERT(position <= end()); - typedef dtl::insert_emplace_proxy proxy_t; - bool prefer_move_back; - if (position == end()){ - if(back_free_capacity()) // fast path - { - pointer const p = m_.buffer + m_.back_idx; - this->alloc_construct(p, boost::forward(args)...); - ++m_.back_idx; - return iterator(p); - } - prefer_move_back = true; - } - else if (position == begin()){ - if(front_free_capacity()) // secondary fast path - { - pointer const p = m_.buffer + (m_.front_idx - 1); - this->alloc_construct(p, boost::forward(args)...); - --m_.front_idx; - return iterator(p); - } - prefer_move_back = false; - } - else{ - iterator nonconst_pos = unconst_iterator(position); - prefer_move_back = should_move_back(position); - - if(prefer_move_back){ - if(back_free_capacity()){ - boost::container::expand_forward_and_insert_nonempty_middle_alloc - ( get_allocator_ref() - , boost::movelib::to_raw_pointer(nonconst_pos) - , this->priv_raw_end() - , 1, proxy_t(::boost::forward(args)...)); - ++m_.back_idx; - return nonconst_pos; - } - } - else{ - if (front_free_capacity()){ - boost::container::expand_backward_and_insert_nonempty_middle_alloc - (get_allocator_ref() - , this->priv_raw_begin() - , boost::movelib::to_raw_pointer(nonconst_pos) - , 1, proxy_t(::boost::forward(args)...)); - --m_.front_idx; - return --nonconst_pos; - } - } - } - return this->insert_range_slow_path(position, 1, proxy_t(::boost::forward(args)...)); - } - - #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #define BOOST_CONTAINER_DEVECTOR_EMPLACE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - iterator emplace(const_iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - BOOST_ASSERT(position >= begin());\ - BOOST_ASSERT(position <= end());\ - typedef dtl::insert_emplace_proxy_arg##N proxy_t;\ - bool prefer_move_back;\ - if (position == end()){\ - if(back_free_capacity())\ - {\ - pointer const p = m_.buffer + m_.back_idx;\ - this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - ++m_.back_idx;\ - return iterator(p);\ - }\ - prefer_move_back = true;\ - }\ - else if (position == begin()){\ - if(front_free_capacity())\ - {\ - pointer const p = m_.buffer + (m_.front_idx - 1);\ - this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - --m_.front_idx;\ - return iterator(p);\ - }\ - prefer_move_back = false;\ - }\ - else{\ - iterator nonconst_pos = unconst_iterator(position);\ - prefer_move_back = should_move_back(position);\ - \ - if(prefer_move_back){\ - if(back_free_capacity()){\ - boost::container::expand_forward_and_insert_nonempty_middle_alloc\ - ( get_allocator_ref()\ - , boost::movelib::to_raw_pointer(nonconst_pos)\ - , this->priv_raw_end()\ - , 1, proxy_t(BOOST_MOVE_FWD##N));\ - ++m_.back_idx;\ - return nonconst_pos;\ - }\ - }\ - else{\ - if (front_free_capacity()){\ - boost::container::expand_backward_and_insert_nonempty_middle_alloc\ - (get_allocator_ref()\ - , this->priv_raw_begin()\ - , boost::movelib::to_raw_pointer(nonconst_pos)\ - , 1, proxy_t(BOOST_MOVE_FWD##N));\ - --m_.front_idx;\ - return --nonconst_pos;\ - }\ - }\ - }\ - return this->insert_range_slow_path(position, 1, proxy_t(BOOST_MOVE_FWD##N));\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE) - #undef BOOST_CONTAINER_DEVECTOR_EMPLACE - - #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - /** - * **Effects**: Copy constructs a new element before the element pointed by `position`, - * using `x` as constructor argument. Invalidates iterators if reallocation is needed. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this` and and [CopyAssignable]. - * - * **Returns**: Iterator pointing to the newly constructed element. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible` - * and `NothrowAssignable`, Basic exception guarantee otherwise. - * - * **Complexity**: Linear in the size of `*this`. - * - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable - */ - iterator insert(const_iterator position, const T &x); - - /** - * **Effects**: Move constructs a new element before the element pointed by `position`, - * using `x` as constructor argument. Invalidates iterators if reallocation is needed. - * - * **Requires**: `T` shall be [MoveInsertable] into `*this` and and [CopyAssignable]. - * - * **Returns**: Iterator pointing to the newly constructed element. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible` - * and `NothrowAssignable` (not regarding the state of `x`), - * Basic exception guarantee otherwise. - * - * **Complexity**: Linear in the size of `*this`. - * - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable - */ - iterator insert(const_iterator position, T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) - #endif - - /** - * **Effects**: Copy constructs `n` elements before the element pointed by `position`, - * using `x` as constructor argument. Invalidates iterators if reallocation is needed. - * - * **Requires**: `T` shall be [CopyInsertable] into `*this` and and [CopyAssignable]. - * - * **Returns**: Iterator pointing to the first inserted element, or `position`, if `n` is zero. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible` - * and `NothrowAssignable`, Basic exception guarantee otherwise. - * - * **Complexity**: Linear in the size of `*this` and `n`. - * - * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable - * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable - */ - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, size_type n, const T& x) - { - cvalue_iterator first(x, n); - cvalue_iterator last = first + n; - return this->insert_range(position, first, last); - } - - /** - * **Effects**: Copy constructs elements before the element pointed by position - * using each element in the range pointed by `first` and `last` as constructor arguments. - * Invalidates iterators if reallocation is needed. - * - * **Requires**: `T` shall be [EmplaceConstructible] into `*this` from `*first`. If the specified iterator - * does not meet the forward iterator requirements, `T` shall also be [MoveInsertable] into `*this` - * and [MoveAssignable]. - * - * **Precondition**: `first` and `last` are not iterators into `*this`. - * - * **Returns**: Iterator pointing to the first inserted element, or `position`, if `first == last`. - * - * **Complexity**: Linear in the size of `*this` and `N` (where `N` is the distance between `first` and `last`). - * Makes only `N` calls to the constructor of `T` and no reallocations if iterators `first` and `last` - * are of forward, bidirectional, or random access categories. It makes 2N calls to the copy constructor of `T` - * and `O(log(N)) reallocations if they are just input iterators. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible` - * and `NothrowAssignable`, Basic exception guarantee otherwise. - * - * **Remarks**: Each iterator in the range `[first,last)` shall be dereferenced exactly once, - * unless an exception is thrown. - * - * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable - */ - template - iterator insert(const_iterator position, InputIterator first, InputIterator last - //Input iterators - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or - < void - BOOST_MOVE_I dtl::is_convertible - BOOST_MOVE_I dtl::is_not_input_iterator - >::type * = 0) - ) - { - if (position == end()) - { - size_type insert_index = size(); - - for (; first != last; ++first) - { - this->emplace_back(*first); - } - - return begin() + insert_index; - } - else - { - const size_type insert_index = static_cast(position - this->cbegin()); - const size_type old_size = static_cast(this->size()); - - for (; first != last; ++first) { - this->emplace_back(*first); - } - iterator rit (this->begin() + insert_index); - boost::movelib::rotate_gcd(rit, this->begin() + old_size, this->begin() + this->size()); - return rit; - } - } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - template - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, ForwardIterator first, ForwardIterator last - //Other iterators - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or - < void - BOOST_MOVE_I dtl::is_convertible - BOOST_MOVE_I dtl::is_input_iterator - >::type * = 0) - ) - { - return insert_range(position, first, last); - } - - #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - /** **Equivalent to**: `insert(position, il.begin(), il.end())` */ - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, std::initializer_list il) - { - return this->insert(position, il.begin(), il.end()); - } - #endif - - /** - * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable - * - * **Effects**: Destroys the element pointed by `position` and removes it from the devector. - * Invalidates iterators. - * - * **Requires**: `T` shall be [MoveAssignable]. - * - * **Precondition**: `position` must be in the range of `[begin(), end())`. - * - * **Returns**: Iterator pointing to the element immediately following the erased element - * prior to its erasure. If no such element exists, `end()` is returned. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowAssignable`, - * Basic exception guarantee otherwise. - * - * **Complexity**: Linear in half the size of `*this`. - */ - iterator erase(const_iterator position) - { - return erase(position, position + 1); - } - - /** - * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable - * - * **Effects**: Destroys the range `[first,last)` and removes it from the devector. - * Invalidates iterators. - * - * **Requires**: `T` shall be [MoveAssignable]. - * - * **Precondition**: `[first,last)` must be in the range of `[begin(), end())`. - * - * **Returns**: Iterator pointing to the element pointed to by `last` prior to any elements - * being erased. If no such element exists, `end()` is returned. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowAssignable`, - * Basic exception guarantee otherwise. - * - * **Complexity**: Linear in half the size of `*this` - * plus the distance between `first` and `last`. - */ - iterator erase(const_iterator first, const_iterator last) - { - iterator nc_first = unconst_iterator(first); - iterator nc_last = unconst_iterator(last); - return erase(nc_first, nc_last); - } - - /** - * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable - * - * **Effects**: Destroys the range `[first,last)` and removes it from the devector. - * Invalidates iterators. - * - * **Requires**: `T` shall be [MoveAssignable]. - * - * **Precondition**: `[first,last)` must be in the range of `[begin(), end())`. - * - * **Returns**: Iterator pointing to the element pointed to by `last` prior to any elements - * being erased. If no such element exists, `end()` is returned. - * - * **Exceptions**: Strong exception guarantee if `T` is `NothrowAssignable`, - * Basic exception guarantee otherwise. - * - * **Complexity**: Linear in half the size of `*this`. - */ - iterator erase(iterator first, iterator last) - { - size_type front_distance = pos_to_index(last); - size_type back_distance = size_type(end() - first); - size_type n = boost::container::iterator_udistance(first, last); - - if (front_distance < back_distance) - { - // move n to the right - boost::container::move_backward(begin(), first, last); - - for (iterator i = begin(); i != begin() + n; ++i) - { - allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(i)); - } - //n is always less than max stored_size_type - m_.set_front_idx(m_.front_idx + n); - - BOOST_ASSERT(invariants_ok()); - return last; - } - else { - // move n to the left - boost::container::move(last, end(), first); - - for (iterator i = end() - n; i != end(); ++i) - { - allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(i)); - } - //n is always less than max stored_size_type - m_.set_back_idx(m_.back_idx - n); - - BOOST_ASSERT(invariants_ok()); - return first; - } - } - - /** - * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable - * - * **Effects**: exchanges the contents of `*this` and `b`. - * - * **Requires**: instances of `T` must be swappable by unqualified call of `swap` - * and `T` must be [MoveInsertable] into `*this`. - * - * **Precondition**: The allocators should allow propagation or should compare equal. - * - * **Exceptions**: Basic exceptions guarantee if not `noexcept`. - * - * **Complexity**: Constant. - */ - void swap(devector& b) - BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value - || allocator_traits_type::is_always_equal::value) - { - BOOST_CONSTEXPR_OR_CONST bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value; - BOOST_ASSERT(propagate_alloc || get_allocator_ref() == b.get_allocator_ref()); // else it's undefined behavior - - swap_big_big(*this, b); - - // swap indices - boost::adl_move_swap(m_.front_idx, b.m_.front_idx); - boost::adl_move_swap(m_.back_idx, b.m_.back_idx); - - //And now swap the allocator - dtl::swap_alloc(this->get_allocator_ref(), b.get_allocator_ref(), dtl::bool_()); - - BOOST_ASSERT( invariants_ok()); - BOOST_ASSERT(b.invariants_ok()); - } - - /** - * **Effects**: Destroys all elements in the devector. - * Invalidates all references, pointers and iterators to the - * elements of the devector. - * - * **Postcondition**: `empty() && front_free_capacity() == 0 - * && back_free_capacity() == old capacity`. - * - * **Complexity**: Linear in the size of `*this`. - * - * **Remarks**: Does not free memory. - */ - void clear() BOOST_NOEXCEPT - { - destroy_elements(begin(), end()); - m_.front_idx = m_.back_idx = 0; - } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const devector& x, const devector& y) - { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const devector& x, const devector& y) - { return !(x == y); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator< (const devector& x, const devector& y) - { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const devector& x, const devector& y) - { return y < x; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const devector& x, const devector& y) - { return !(y < x); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const devector& x, const devector& y) - { return !(x < y); } - - BOOST_CONTAINER_FORCEINLINE friend void swap(devector& x, devector& y) - BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value - || allocator_traits_type::is_always_equal::value) - { x.swap(y); } - - private: - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type pos_to_index(const_iterator i) const - { - return static_cast(i - cbegin()); - } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool should_move_back(const_iterator i) const - { - return static_cast(this->pos_to_index(i)) >= this->size()/2u; - } - - BOOST_CONTAINER_FORCEINLINE static iterator unconst_iterator(const_iterator i) - { - return boost::intrusive::pointer_traits::const_cast_from(i); - } - - BOOST_CONTAINER_FORCEINLINE size_type front_capacity() const - { - return m_.back_idx; - } - - BOOST_CONTAINER_FORCEINLINE size_type back_capacity() const - { - return size_type(m_.capacity - m_.front_idx); - } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - BOOST_CONTAINER_FORCEINLINE T* priv_raw_begin() BOOST_NOEXCEPT - { return boost::movelib::to_raw_pointer(m_.buffer) + m_.front_idx; } - - BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() BOOST_NOEXCEPT - { return boost::movelib::to_raw_pointer(m_.buffer) + m_.back_idx; } - - - template - BOOST_CONTAINER_FORCEINLINE void priv_push_front(BOOST_FWD_REF(U) u) - { - this->emplace_front(boost::forward(u)); - } - - template - BOOST_CONTAINER_FORCEINLINE void priv_push_back(BOOST_FWD_REF(U) u) - { - this->emplace_back(boost::forward(u)); - } - - template - BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator pos, BOOST_FWD_REF(U) u) - { - return this->emplace(pos, boost::forward(u)); - } - - // allocator_type wrappers - - BOOST_CONTAINER_FORCEINLINE allocator_type& get_allocator_ref() BOOST_NOEXCEPT - { - return static_cast(m_); - } - - BOOST_CONTAINER_FORCEINLINE const allocator_type& get_allocator_ref() const BOOST_NOEXCEPT - { - return static_cast(m_); - } - - pointer allocate(size_type capacity) - { - pointer const p = impl::do_allocate(get_allocator_ref(), capacity); - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - ++m_.capacity_alloc_count; - #endif // BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - return p; - } - - void destroy_elements(pointer begin, pointer end) - { - for (; begin != end; ++begin) - { - allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(begin)); - } - } - - void deallocate_buffer() - { - if (m_.buffer) - { - allocator_traits_type::deallocate(get_allocator_ref(), m_.buffer, m_.capacity); - } - } - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - BOOST_CONTAINER_FORCEINLINE void alloc_construct(pointer dst, Args&&... args) - { - allocator_traits_type::construct( - get_allocator_ref(), - boost::movelib::to_raw_pointer(dst), - boost::forward(args)... - ); - } - - template - void construct_n(pointer buffer, size_type n, Args&&... args) - { - detail::construction_guard ctr_guard(buffer, get_allocator_ref()); - guarded_construct_n(buffer, n, ctr_guard, boost::forward(args)...); - ctr_guard.release(); - } - - template - void guarded_construct_n(pointer buffer, size_type n, detail::construction_guard& ctr_guard, Args&&... args) - { - for (size_type i = 0; i < n; ++i) { - this->alloc_construct(buffer + i, boost::forward(args)...); - ctr_guard.extend(); - } - } - - #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #define BOOST_CONTAINER_DEVECTOR_ALLOC_CONSTRUCT(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE void alloc_construct(pointer dst BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - allocator_traits_type::construct(\ - get_allocator_ref(), boost::movelib::to_raw_pointer(dst) BOOST_MOVE_I##N BOOST_MOVE_FWD##N );\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - void construct_n(pointer buffer, size_type n BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - detail::construction_guard ctr_guard(buffer, get_allocator_ref());\ - guarded_construct_n(buffer, n, ctr_guard BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - ctr_guard.release();\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - void guarded_construct_n(pointer buffer, size_type n, detail::construction_guard& ctr_guard BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - for (size_type i = 0; i < n; ++i) {\ - this->alloc_construct(buffer + i BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - ctr_guard.extend();\ - }\ - } - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_ALLOC_CONSTRUCT) - #undef BOOST_CONTAINER_DEVECTOR_ALLOC_CONSTRUCT - - #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - size_type calculate_new_capacity(size_type requested_capacity) - { - size_type max = allocator_traits_type::max_size(this->get_allocator_ref()); - (clamp_by_stored_size_type)(max, stored_size_type()); - const size_type remaining_additional_cap = max - size_type(m_.capacity); - const size_type min_additional_cap = requested_capacity - size_type(m_.capacity); - if ( remaining_additional_cap < min_additional_cap ) - boost::container::throw_length_error("devector: get_next_capacity, max size exceeded"); - - return growth_factor_type()( size_type(m_.capacity), min_additional_cap, max); - } - - void buffer_move_or_copy(pointer dst) - { - detail::construction_guard guard(dst, get_allocator_ref()); - - buffer_move_or_copy(dst, guard); - - guard.release(); - } - - void buffer_move_or_copy(pointer dst, detail::construction_guard& guard) - { - opt_move_or_copy(begin(), end(), dst, guard); - - destroy_elements(data(), data() + size()); - deallocate_buffer(); - } - - template - void opt_move_or_copy(pointer begin, pointer end, pointer dst, Guard& guard) - { - // if trivial copy and default allocator, memcpy - boost::container::uninitialized_move_alloc(get_allocator_ref(), begin, end, dst); - guard.extend(); - } - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - template - void resize_impl(size_type sz, Args&&... args) - { - const size_type old_sz = this->size(); - if (sz > old_sz) - { - const size_type n = sz - old_sz; - - if (sz <= m_.capacity) - { - //Construct at back - const size_type bfc = this->back_free_capacity(); - const size_type b = n < bfc ? n : bfc; - construct_n(m_.buffer + m_.back_idx, b, boost::forward(args)...); - m_.set_back_idx(m_.back_idx + b); - - //Construct remaining at front - const size_type f = n - b; - construct_n(m_.buffer + m_.front_idx - f, f, boost::forward(args)...); - m_.set_front_idx(m_.front_idx - f); - } - else - { - resize_back_slow_path(sz, n, boost::forward(args)...); - } - } - else - { - const size_type n = old_sz - sz; - const size_type new_bidx = m_.back_idx - n; - destroy_elements(m_.buffer + new_bidx, m_.buffer + m_.back_idx); - m_.set_back_idx(new_bidx); - } - } - - template - void resize_front_impl(size_type sz , Args&&... args) - { - const size_type old_sz = this->size(); - if (sz > old_sz) - { - const size_type n = sz - old_sz; - - if (sz <= this->front_capacity()) - { - construct_n(m_.buffer + m_.front_idx - n, n, boost::forward(args)...); - m_.set_front_idx(m_.front_idx - n); - } - else - { - resize_front_slow_path(sz, n, boost::forward(args)...); - } - } - else { - const size_type n = old_sz - sz; - const size_type new_fidx = m_.front_idx + n; - destroy_elements(m_.buffer + m_.front_idx, m_.buffer + new_fidx); - m_.set_front_idx(new_fidx); - } - } - - template - void resize_front_slow_path(size_type sz, size_type n, Args&&... args) - { - const size_type new_capacity = calculate_new_capacity(sz + back_free_capacity()); - pointer new_buffer = allocate(new_capacity); - allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref()); - - const size_type old_sz = this->size(); - const size_type new_old_elem_index = new_capacity - old_sz; - const size_type new_elem_index = new_old_elem_index - n; - - detail::construction_guard guard(new_buffer + new_elem_index, get_allocator_ref()); - guarded_construct_n(new_buffer + new_elem_index, n, guard, boost::forward(args)...); - - buffer_move_or_copy(new_buffer + new_old_elem_index, guard); - - guard.release(); - new_buffer_guard.release(); - - m_.buffer = new_buffer; - m_.set_capacity(new_capacity); - m_.set_front_idx(new_elem_index); - m_.set_back_idx(new_elem_index + old_sz + n); - } - - template - void resize_back_impl(size_type sz, Args&&... args) - { - const size_type old_sz = this->size(); - if (sz > old_sz) - { - const size_type n = sz - old_sz; - - if (sz <= this->back_capacity()) - { - construct_n(m_.buffer + m_.back_idx, n, boost::forward(args)...); - m_.set_back_idx(m_.back_idx + n); - } - else - { - resize_back_slow_path(sz, n, boost::forward(args)...); - } - } - else - { - const size_type n = old_sz - sz; - const size_type new_bidx = m_.back_idx - n; - destroy_elements(m_.buffer + new_bidx, m_.buffer + m_.back_idx); - m_.set_back_idx(new_bidx); - } - } - - template - void resize_back_slow_path(size_type sz, size_type n, Args&&... args) - { - const size_type new_capacity = calculate_new_capacity(sz + front_free_capacity()); - pointer new_buffer = allocate(new_capacity); - allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref()); - - detail::construction_guard guard(new_buffer + m_.back_idx, get_allocator_ref()); - guarded_construct_n(new_buffer + m_.back_idx, n, guard, boost::forward(args)...); - - buffer_move_or_copy(new_buffer + m_.front_idx); - - guard.release(); - new_buffer_guard.release(); - - m_.buffer = new_buffer; - m_.set_capacity(new_capacity); - m_.set_back_idx(m_.back_idx + n); - } - - #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #define BOOST_CONTAINER_DEVECTOR_SLOW_PATH(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - void resize_front_impl(size_type sz BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - if (sz > size())\ - {\ - const size_type n = sz - size();\ - if (sz <= front_capacity()){\ - construct_n(m_.buffer + m_.front_idx - n, n BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - m_.set_front_idx(m_.front_idx - n);\ - }\ - else\ - {\ - resize_front_slow_path(sz, n BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - }\ - }\ - else {\ - while (this->size() > sz)\ - {\ - this->pop_front();\ - }\ - }\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - void resize_front_slow_path(size_type sz, size_type n BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - const size_type new_capacity = calculate_new_capacity(sz + back_free_capacity());\ - pointer new_buffer = allocate(new_capacity);\ - allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());\ - \ - const size_type new_old_elem_index = new_capacity - size();\ - const size_type new_elem_index = new_old_elem_index - n;\ - \ - detail::construction_guard guard(new_buffer + new_elem_index, get_allocator_ref());\ - guarded_construct_n(new_buffer + new_elem_index, n, guard BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - \ - buffer_move_or_copy(new_buffer + new_old_elem_index, guard);\ - \ - guard.release();\ - new_buffer_guard.release();\ - m_.buffer = new_buffer;\ - m_.set_capacity(new_capacity);\ - m_.set_back_idx(new_old_elem_index + m_.back_idx - m_.front_idx);\ - m_.set_front_idx(new_elem_index);\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - void resize_back_impl(size_type sz BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - if (sz > size())\ - {\ - const size_type n = sz - size();\ - \ - if (sz <= back_capacity())\ - {\ - construct_n(m_.buffer + m_.back_idx, n BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - m_.set_back_idx(m_.back_idx + n);\ - }\ - else\ - {\ - resize_back_slow_path(sz, n BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - }\ - }\ - else\ - {\ - while (size() > sz)\ - {\ - pop_back();\ - }\ - }\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - void resize_back_slow_path(size_type sz, size_type n BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - const size_type new_capacity = calculate_new_capacity(sz + front_free_capacity());\ - pointer new_buffer = allocate(new_capacity);\ - allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());\ - \ - detail::construction_guard guard(new_buffer + m_.back_idx, get_allocator_ref());\ - guarded_construct_n(new_buffer + m_.back_idx, n, guard BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - \ - buffer_move_or_copy(new_buffer + m_.front_idx);\ - \ - guard.release();\ - new_buffer_guard.release();\ - \ - m_.buffer = new_buffer;\ - m_.set_capacity(new_capacity);\ - m_.set_back_idx(m_.back_idx + n);\ - }\ - \ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_SLOW_PATH) - #undef BOOST_CONTAINER_DEVECTOR_SLOW_PATH - - #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - void reallocate_at(size_type new_capacity, size_type buffer_offset) - { - pointer new_buffer = allocate(new_capacity); - { - allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref()); - boost::container::uninitialized_move_alloc(get_allocator_ref(), this->begin(), this->end(), new_buffer + buffer_offset); - new_buffer_guard.release(); - } - destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx); - deallocate_buffer(); - - m_.buffer = new_buffer; - //Safe cast, allocate() will handle stored_size_type overflow - m_.set_capacity(new_capacity); - m_.set_back_idx(size_type(m_.back_idx - m_.front_idx) + buffer_offset); - m_.set_front_idx(buffer_offset); - - BOOST_ASSERT(invariants_ok()); - } - - template - iterator insert_range(const_iterator position, ForwardIterator first, ForwardIterator last) - { - BOOST_ASSERT(position >= begin()); - BOOST_ASSERT(position <= end()); - typedef dtl::insert_range_proxy proxy_t; - - size_type const n = boost::container::iterator_udistance(first, last); - bool prefer_move_back; - if (BOOST_UNLIKELY(!n)) { - return begin() + size_type(position - cbegin()); - } - else if (position == end()) { - if(back_free_capacity() >= n) // fast path - { - iterator r(this->end()); - boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->priv_raw_end()); - m_.set_back_idx(m_.back_idx + n); - return r; - } - prefer_move_back = true; - } - else if (position == begin()) { - if(front_free_capacity() >= n) {// secondary fast path - boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->priv_raw_begin() - n); - m_.set_front_idx(m_.front_idx - n); - return begin(); - } - prefer_move_back = false; - } - else{ - iterator nonconst_pos = unconst_iterator(position); - prefer_move_back = should_move_back(position); - - if(prefer_move_back){ - if(back_free_capacity() >= n){ - boost::container::expand_forward_and_insert_nonempty_middle_alloc - ( get_allocator_ref() - , boost::movelib::to_raw_pointer(nonconst_pos) - , this->priv_raw_end() - , n, proxy_t(first)); - m_.set_back_idx(m_.back_idx + n); - return nonconst_pos; - } - } - else{ - if (front_free_capacity() >= n){ - boost::container::expand_backward_and_insert_nonempty_middle_alloc - ( get_allocator_ref() - , this->priv_raw_begin() - , boost::movelib::to_raw_pointer(nonconst_pos) - , n, proxy_t(first)); - m_.set_front_idx(m_.front_idx - n); - return (nonconst_pos -= n); - } - } - } - return this->insert_range_slow_path(position, n, proxy_t(first)); - } - - template - BOOST_CONTAINER_NOINLINE iterator insert_range_slow_path - (const_iterator p, const size_type n, const InsertionProxy proxy) - { - size_type const back_free_cap = back_free_capacity(); - size_type const front_free_cap = front_free_capacity(); - size_type const free_cap = front_free_cap + back_free_cap; - size_type const index = size_type(p - cbegin()); - - size_type const cap = m_.capacity; - //Test if enough free memory would be left - if (free_cap >= n && (free_cap - n) >= cap/devector_min_free_fraction) { - //Make sure relocation is happening because there was no enough space - size_type const old_size = this->size(); - BOOST_ASSERT(should_move_back(p) ? (back_free_cap < n) : (front_free_cap < n)); - - T* const raw_pos = const_cast(boost::movelib::to_raw_pointer(p)); - size_type const new_size = old_size + n; - size_type const new_front_idx = (cap - new_size) / 2u; - - T* const raw_beg = this->priv_raw_begin(); - T* const new_raw_beg = raw_beg - std::ptrdiff_t(m_.front_idx - new_front_idx); - m_.back_idx = 0u; - m_.front_idx = 0u; - boost::container::expand_backward_forward_and_insert_alloc - (raw_beg, old_size, new_raw_beg, raw_pos, n, proxy, get_allocator_ref()); - m_.set_front_idx(new_front_idx); - m_.set_back_idx(new_front_idx + new_size); - } - else { - // reallocate - const size_type new_capacity = calculate_new_capacity(m_.capacity + n); - pointer new_buffer = allocate(new_capacity); - - // guard allocation - allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref()); - - size_type const old_size = this->size(); - const size_type new_front_index = (new_capacity - old_size - n) / 2u; - - T* const raw_pos = const_cast(boost::movelib::to_raw_pointer(p)); - T* const raw_new_start = const_cast(boost::movelib::to_raw_pointer(new_buffer)) + new_front_index; - - boost::container::uninitialized_move_and_insert_alloc - (get_allocator_ref(), this->priv_raw_begin(), raw_pos, this->priv_raw_end(), raw_new_start, n, proxy); - new_buffer_guard.release(); - - // cleanup - destroy_elements(begin(), end()); - deallocate_buffer(); - - // rebind members - m_.set_capacity(new_capacity); - m_.buffer = new_buffer; - m_.set_back_idx(new_front_index + old_size + n); - m_.set_front_idx(new_front_index); - } - return begin() + index; - } - - - template - void construct_from_range(Iterator begin, Iterator end) - { - allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref()); - boost::container::uninitialized_copy_alloc(get_allocator_ref(), begin, end, m_.buffer); - buffer_guard.release(); - } - - template - void allocate_and_copy_range(ForwardIterator first, ForwardIterator last) - { - size_type n = boost::container::iterator_udistance(first, last); - - pointer new_buffer = n ? allocate(n) : pointer(); - allocation_guard new_buffer_guard(new_buffer, n, get_allocator_ref()); - boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, new_buffer); - destroy_elements(begin(), end()); - deallocate_buffer(); - - m_.set_capacity(n); - m_.buffer = new_buffer; - m_.front_idx = 0; - m_.set_back_idx(n); - - new_buffer_guard.release(); - } - - static void swap_big_big(devector& a, devector& b) BOOST_NOEXCEPT - { - boost::adl_move_swap(a.m_.capacity, b.m_.capacity); - boost::adl_move_swap(a.m_.buffer, b.m_.buffer); - } - - template - void overwrite_buffer_impl(ForwardIterator first, ForwardIterator last, dtl::true_) - { - const size_type n = boost::container::iterator_udistance(first, last); - - BOOST_ASSERT(m_.capacity >= n); - boost::container::uninitialized_copy_alloc_n - ( get_allocator_ref(), first - , n, boost::movelib::to_raw_pointer(m_.buffer)); - m_.front_idx = 0; - m_.set_back_idx(n); - } - - template - InputIterator overwrite_buffer_impl(InputIterator first, InputIterator last, dtl::false_) - { - pointer pos = m_.buffer; - detail::construction_guard front_guard(pos, get_allocator_ref()); - - while (first != last && pos != begin()) { - this->alloc_construct(pos++, *first++); - front_guard.extend(); - } - - while (first != last && pos != end()) { - *pos++ = *first++; - } - - detail::construction_guard back_guard(pos, get_allocator_ref()); - - iterator capacity_end = m_.buffer + m_.capacity; - while (first != last && pos != capacity_end) { - this->alloc_construct(pos++, *first++); - back_guard.extend(); - } - - pointer destroy_after = dtl::min_value(dtl::max_value(begin(), pos), end()); - destroy_elements(destroy_after, end()); - - front_guard.release(); - back_guard.release(); - - m_.front_idx = 0; - m_.set_back_idx(pos_to_index(pos)); - return first; - } - - template - BOOST_CONTAINER_FORCEINLINE void overwrite_buffer(ForwardIterator first, ForwardIterator last) - { - this->overwrite_buffer_impl(first, last, - dtl::bool_::value>()); - } - - bool invariants_ok() - { - return (! m_.capacity || m_.buffer ) - && m_.front_idx <= m_.back_idx - && m_.back_idx <= m_.capacity; - } - - struct impl : allocator_type - { - BOOST_MOVABLE_BUT_NOT_COPYABLE(impl) - - public: - allocator_type &get_al() - { return *this; } - - static pointer do_allocate(allocator_type &a, size_type cap) - { - if (cap) { - //First detect overflow on smaller stored_size_types - if (cap > stored_size_type(-1)){ - boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); - } - return allocator_traits_type::allocate(a, cap); - } - else { - return pointer(); - } - } - - impl() - : allocator_type(), buffer(), front_idx(), back_idx(), capacity() - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count(0) - #endif - {} - - explicit impl(const allocator_type &a) - : allocator_type(a), buffer(), front_idx(), back_idx(), capacity() - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count(0) - #endif - {} - - impl(reserve_uninitialized_t, const allocator_type& a, size_type c) - : allocator_type(a), buffer(do_allocate(get_al(), c) ) - //static cast sizes, as the allocation function will take care of overflows - , front_idx(static_cast(0u)) - , back_idx(static_cast(c)) - , capacity(static_cast(c)) - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count(size_type(buffer != pointer())) - #endif - {} - - impl(reserve_only_tag_t, const allocator_type &a, size_type const ffc, size_type const bfc) - : allocator_type(a), buffer(do_allocate(get_al(), ffc+bfc) ) - //static cast sizes, as the allocation function will take care of overflows - , front_idx(static_cast(ffc)) - , back_idx(static_cast(ffc)) - , capacity(static_cast(ffc + bfc)) - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count(size_type(buffer != pointer())) - #endif - {} - - impl(reserve_only_tag_t, const allocator_type &a, size_type const c) - : allocator_type(a), buffer(do_allocate(get_al(), c) ) - //static cast sizes, as the allocation function will take care of overflows - , front_idx(static_cast(c/2u)) - , back_idx(static_cast(c/2u)) - , capacity(static_cast(c)) - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count(size_type(buffer != pointer())) - #endif - {} - - impl(review_implementation_t, const allocator_type &a, pointer p, size_type fi, size_type bi, size_type c) - : allocator_type(a), buffer(p) - //static cast sizes, as the allocation function will take care of overflows - , front_idx(static_cast(fi)) - , back_idx(static_cast(bi)) - , capacity(static_cast(c)) - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count(0) - #endif - {} - - impl(BOOST_RV_REF(impl) m) - : allocator_type(BOOST_MOVE_BASE(allocator_type, m)) - , buffer(static_cast(m).buffer) - , front_idx(static_cast(m).front_idx) - , back_idx(static_cast(m).back_idx) - , capacity(static_cast(m).capacity) - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count(0) - #endif - { - impl &i = static_cast(m); - // buffer is already acquired, reset rhs - i.capacity = 0u; - i.buffer = pointer(); - i.front_idx = 0; - i.back_idx = 0; - } - - BOOST_CONTAINER_FORCEINLINE void set_back_idx(size_type bi) - { - back_idx = static_cast(bi); - } - - BOOST_CONTAINER_FORCEINLINE void set_front_idx(size_type fi) - { - front_idx = static_cast(fi); - } - - BOOST_CONTAINER_FORCEINLINE void set_capacity(size_type c) - { - capacity = static_cast(c); - } - - pointer buffer; - stored_size_type front_idx; - stored_size_type back_idx; - stored_size_type capacity; - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - size_type capacity_alloc_count; - #endif - } m_; - - #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - public: - void reset_alloc_stats() - { - m_.capacity_alloc_count = 0; - } - - size_type get_alloc_count() const - { - return m_.capacity_alloc_count; - } - - #endif // ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - - #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -}} // namespace boost::container - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -namespace boost { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef typename boost::container::devector::allocator_type allocator_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; -}; - -} - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#include - -#endif // BOOST_CONTAINER_DEVECTOR_HPP diff --git a/inst/i/b/container/flat_map.hpp b/inst/i/b/container/flat_map.hpp deleted file mode 100644 index 647ec483a..000000000 --- a/inst/i/b/container/flat_map.hpp +++ /dev/null @@ -1,3067 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2005-2013. 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_FLAT_MAP_HPP -#define BOOST_CONTAINER_FLAT_MAP_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -// container -#include -#include -#include //new_allocator -#include -// container/detail -#include -#include -#include -#include //equal() -#include -// move -#include -#include -// move/detail -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -#include -#include -// intrusive -#include //pair -#include //less, equal - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -namespace boost { -namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -template -class flat_multimap; - -namespace dtl{ - -template -BOOST_CONTAINER_FORCEINLINE static D &force(S &s) -{ return *move_detail::force_ptr(&s); } - -template -BOOST_CONTAINER_FORCEINLINE static const D &force(const S &s) -{ return *move_detail::force_ptr(&s); } - -template -BOOST_CONTAINER_FORCEINLINE static D force_copy(const S &s) -{ - const D *const vp = move_detail::force_ptr(&s); - D ret_val(*vp); - return ret_val; -} - -} //namespace dtl{ - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! A flat_map is a kind of associative container that supports unique keys (contains at -//! most one of each key value) and provides for fast retrieval of values of another -//! type T based on the keys. -//! -//! A flat_map satisfies all of the requirements of a container, a reversible -//! container and an associative container. A flat_map also provides -//! most operations described for unique keys. For a -//! flat_map the key_type is Key and the value_type is std::pair -//! (unlike std::map which value_type is std::pair<const Key, T>). -//! -//! flat_map is similar to std::map but it's implemented by as an ordered sequence container. -//! The underlying sequence container is by default vector but it can also work -//! user-provided vector-like SequenceContainers (like static_vector or small_vector). -//! -//! Using vector-like sequence containers means that inserting a new element into a flat_map might invalidate -//! previous iterators and references (unless that sequence container is stable_vector or a similar -//! container that offers stable pointers and references). Similarly, erasing an element might invalidate -//! iterators and references pointing to elements that come after (their keys are bigger) the erased element. -//! -//! This container provides random-access iterators. -//! -//! \tparam Key is the key_type of the map -//! \tparam Value is the mapped_type -//! \tparam Compare is the ordering function for Keys (e.g. std::less). -//! \tparam AllocatorOrContainer is either: -//! - The allocator to allocate value_types (e.g. allocator< std::pair > ). -//! (in this case sequence_type will be vector) -//! - The SequenceContainer to be used as the underlying sequence_type. It must be a vector-like -//! sequence container with random-access iterators. -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class AllocatorOrContainer = new_allocator< std::pair< Key, T> > > -#else -template -#endif -class flat_map -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(flat_map) - //This is the tree that we should store if pair was movable - typedef dtl::flat_tree< - std::pair, - dtl::select1st, - Compare, - AllocatorOrContainer> tree_t; - - //This is the real tree stored here. It's based on a movable pair - typedef dtl::flat_tree< - dtl::pair, - dtl::select1st, - Compare, - typename dtl::container_or_allocator_rebind >::type - > impl_tree_t; - impl_tree_t m_flat_tree; // flat tree representing flat_map - - typedef typename impl_tree_t::value_type impl_value_type; - typedef typename impl_tree_t::const_iterator impl_const_iterator; - typedef typename impl_tree_t::iterator impl_iterator; - typedef typename impl_tree_t::allocator_type impl_allocator_type; - #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - typedef std::initializer_list impl_initializer_list; - #endif - - typedef dtl::flat_tree_value_compare - < Compare - , dtl::select1st - , std::pair > value_compare_t; - typedef typename tree_t::iterator iterator_t; - typedef typename tree_t::const_iterator const_iterator_t; - typedef typename tree_t::reverse_iterator reverse_iterator_t; - typedef typename tree_t::const_reverse_iterator const_reverse_iterator_t; - - public: - typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type; - typedef typename impl_tree_t::sequence_type impl_sequence_type; - - BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree() - { return m_flat_tree; } - - BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const - { return m_flat_tree; } - - private: - typedef typename tree_t::get_stored_allocator_const_return_t get_stored_allocator_const_return_t; - typedef typename tree_t::get_stored_allocator_noconst_return_t get_stored_allocator_noconst_return_t; - typedef typename impl_tree_t::get_stored_allocator_const_return_t impl_get_stored_allocator_const_return_t; - typedef typename impl_tree_t::get_stored_allocator_noconst_return_t impl_get_stored_allocator_noconst_return_t; - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - typedef Key key_type; - typedef T mapped_type; - typedef Compare key_compare; - typedef std::pair value_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type; - typedef typename sequence_type::allocator_type allocator_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename sequence_type::pointer pointer; - typedef typename sequence_type::const_pointer const_pointer; - typedef typename sequence_type::reference reference; - typedef typename sequence_type::const_reference const_reference; - typedef typename sequence_type::size_type size_type; - typedef typename sequence_type::difference_type difference_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare; - - typedef typename sequence_type::iterator iterator; - typedef typename sequence_type::const_iterator const_iterator; - typedef typename sequence_type::reverse_iterator reverse_iterator; - typedef typename sequence_type::const_reverse_iterator const_reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; - - //AllocatorOrContainer::value_type must be std::pair - BOOST_STATIC_ASSERT((dtl::is_same, value_type>::value)); - - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructs an empty flat_map. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE flat_map() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value && - dtl::is_nothrow_default_constructible::value) - : m_flat_tree() - {} - - //! Effects: Constructs an empty flat_map using the specified allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit flat_map(const allocator_type& a) - : m_flat_tree(dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_map using the specified - //! comparison object. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit flat_map(const Compare& comp) - : m_flat_tree(comp) - {} - - //! Effects: Constructs an empty flat_map using the specified - //! comparison object and allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE flat_map(const Compare& comp, const allocator_type& a) - : m_flat_tree(comp, dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_map and - //! and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last) - : m_flat_tree(true, first, last) - {} - - //! Effects: Constructs an empty flat_map using the specified - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const allocator_type& a) - : m_flat_tree(true, first, last, dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object and - //! and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp) - : m_flat_tree(true, first, last, comp) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object and - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : m_flat_tree(true, first, last, comp, dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_map - //! and inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_map(ordered_unique_range_t, InputIterator first, InputIterator last) - : m_flat_tree(ordered_range, first, last) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object and - //! inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp) - : m_flat_tree(ordered_range, first, last, comp) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object and - //! allocator, and inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : m_flat_tree(ordered_range, first, last, comp, dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_map using the specified allocator and - //! inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) - : m_flat_tree(ordered_range, first, last, Compare(), a) - {} - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs an empty flat_map and - //! inserts elements from the range [il.begin() ,il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list il) - : m_flat_tree( true - , dtl::force(il).begin() - , dtl::force(il).end()) - {} - - //! Effects: Constructs an empty flat_map using the specified - //! allocator, and inserts elements from the range [il.begin() ,il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list il, const allocator_type& a) - : m_flat_tree( true - , dtl::force(il).begin() - , dtl::force(il).end() - , dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object and - //! inserts elements from the range [il.begin() ,il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list il, const Compare& comp) - : m_flat_tree(true - , dtl::force(il).begin() - , dtl::force(il).end() - , comp) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object and - //! allocator, and inserts elements from the range [il.begin() ,il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list il, const Compare& comp, const allocator_type& a) - : m_flat_tree(true - , dtl::force(il).begin() - , dtl::force(il).end() - , comp - , dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_map using 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list il) - : m_flat_tree(ordered_unique_range - , dtl::force(il).begin() - , dtl::force(il).end()) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list il, const Compare& comp) - : m_flat_tree(ordered_unique_range - , dtl::force(il).begin() - , dtl::force(il).end() - , comp) - {} - - //! Effects: Constructs an empty flat_map 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list il, const Compare& comp, const allocator_type& a) - : m_flat_tree( ordered_unique_range - , dtl::force(il).begin() - , dtl::force(il).end() - , comp - , dtl::force(a)) - {} -#endif - - //! Effects: Copy constructs a flat_map. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x) - : m_flat_tree(x.m_flat_tree) - {} - - //! Effects: Move constructs a flat_map. - //! Constructs *this using x's resources. - //! - //! Complexity: Constant. - //! - //! Postcondition: x is emptied. - BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : m_flat_tree(boost::move(x.m_flat_tree)) - {} - - //! Effects: Copy constructs a flat_map using the specified allocator. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x, const allocator_type &a) - : m_flat_tree(x.m_flat_tree, dtl::force(a)) - {} - - //! Effects: Move constructs a flat_map using the specified allocator. - //! Constructs *this using x's resources. - //! - //! Complexity: Constant if x.get_allocator() == a, linear otherwise. - BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a) - : m_flat_tree(boost::move(x.m_flat_tree), dtl::force(a)) - {} - - //! Effects: Makes *this a copy of x. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x) - { m_flat_tree = x.m_flat_tree; return *this; } - - //! Effects: Move constructs a flat_map. - //! Constructs *this using x's resources. - //! - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or value_type's move constructor throws) - //! - //! Complexity: Constant if allocator_traits_type:: - //! propagate_on_container_move_assignment is true or - //! this->get>allocator() == x.get_allocator(). Linear otherwise. - BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_RV_REF(flat_map) x) - BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value || - allocator_traits_type::is_always_equal::value) && - boost::container::dtl::is_nothrow_move_assignable::value) - { m_flat_tree = boost::move(x.m_flat_tree); return *this; } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Assign elements from il to *this - flat_map& operator=(std::initializer_list il) - { - this->clear(); - this->insert(il.begin(), il.end()); - return *this; - } -#endif - - //! Effects: Returns a copy of the allocator that - //! was passed to the object's constructor. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.get_allocator()); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - get_stored_allocator_noconst_return_t get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW - { - impl_get_stored_allocator_noconst_return_t r = m_flat_tree.get_stored_allocator(); - return dtl::force(r); - } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - get_stored_allocator_const_return_t get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { - impl_get_stored_allocator_const_return_t r = m_flat_tree.get_stored_allocator(); - return dtl::force(r); - } - - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// - - //! Effects: Returns an iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.begin()); } - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.begin()); } - - //! Effects: Returns an iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator end() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.end()); } - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.end()); } - - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.rbegin()); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.rbegin()); } - - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.rend()); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.rend()); } - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.cbegin()); } - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.cend()); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.crbegin()); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.crend()); } - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// - - //! Effects: Returns true if the container contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.empty(); } - - //! Effects: Returns the number of the elements contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.size(); } - - //! Effects: Returns the largest possible size of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.max_size(); } - - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.capacity(); } - - //! Effects: If n is less than or equal to capacity(), or the - //! underlying container has no `reserve` member, this call has no - //! effect. Otherwise, it is a request for allocation of additional memory. - //! If the request is successful, then capacity() is greater than or equal to - //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. - //! - //! Throws: If memory allocation allocation throws or T's copy constructor throws. - //! - //! Note: If capacity() is less than "cnt", iterators and references to - //! to values might be invalidated. - BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt) - { m_flat_tree.reserve(cnt); } - - //! Effects: Tries to deallocate the excess of memory created - // with previous allocations. The size of the vector is unchanged - //! - //! Throws: If memory allocation throws, or T's copy constructor throws. - //! - //! Complexity: Linear to size(). - BOOST_CONTAINER_FORCEINLINE void shrink_to_fit() - { m_flat_tree.shrink_to_fit(); } - - ////////////////////////////////////////////// - // - // element access - // - ////////////////////////////////////////////// - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: If there is no key equivalent to x in the flat_map, inserts - //! value_type(x, T()) into the flat_map. - //! - //! Returns: A reference to the mapped_type corresponding to x in *this. - //! - //! Complexity: Logarithmic search time plus linear insertion time in case no equivalent key is present. - mapped_type &operator[](const key_type& k); - - //! Effects: If there is no key equivalent to x in the flat_map, inserts - //! value_type(move(x), T()) into the flat_map (the key is move-constructed) - //! - //! Returns: A reference to the mapped_type corresponding to x in *this. - //! - //! Complexity: Logarithmic search time plus linear insertion time in case no equivalent key is present. - 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 - BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](const key_type &k) { return this->priv_subscript(k); } - BOOST_CONTAINER_FORCEINLINE 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) - #endif - - //! Effects: If a key equivalent to k already exists in the container, assigns forward(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(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 search time plus linear insertion time in case no equivalent key is present. - template - BOOST_CONTAINER_FORCEINLINE std::pair insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj) - { - return dtl::force_copy< std::pair > - (this->m_flat_tree.insert_or_assign - ( impl_const_iterator(), k, ::boost::forward(obj)) - ); - } - - //! Effects: If a key equivalent to k already exists in the container, assigns forward(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 - BOOST_CONTAINER_FORCEINLINE std::pair insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj) - { - return dtl::force_copy< std::pair > - (this->m_flat_tree.insert_or_assign - ( impl_const_iterator(), ::boost::move(k), ::boost::forward(obj)) - ); - } - - //! Effects: If a key equivalent to k already exists in the container, assigns forward(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(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 - BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj) - { - return dtl::force_copy - (this->m_flat_tree.insert_or_assign - ( dtl::force_copy(hint) - , k, ::boost::forward(obj)).first - ); - } - - //! Effects: If a key equivalent to k already exists in the container, assigns forward(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 - BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj) - { - return dtl::force_copy - (this->m_flat_tree.insert_or_assign - ( dtl::force_copy(hint) - , ::boost::move(k), ::boost::forward(obj)).first - ); - } - - //! @copydoc ::boost::container::flat_set::nth(size_type) - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.nth(n)); } - - //! @copydoc ::boost::container::flat_set::nth(size_type) const - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.nth(n)); } - - //! @copydoc ::boost::container::flat_set::index_of(iterator) - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.index_of(dtl::force_copy(p)); } - - //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.index_of(dtl::force_copy(p)); } - - //! Returns: A reference to the element whose key is equivalent to x. - //! - //! Throws: An exception object of type out_of_range if no such element is present. - //! - //! Complexity: logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD T& at(const key_type& k) - { - iterator i = this->find(k); - if(i == this->end()){ - throw_out_of_range("flat_map::at key not found"); - } - return i->second; - } - - //! Returns: A reference to the element whose key is equivalent to x. - //! - //! Throws: An exception object of type out_of_range if no such element is present. - //! - //! Complexity: logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD const T& at(const key_type& k) const - { - const_iterator i = this->find(k); - if(i == this->end()){ - throw_out_of_range("flat_map::at key not found"); - } - return i->second; - } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object x of type T constructed with - //! std::forward(args)... if and only if there is no element in the container - //! with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE std::pair emplace(BOOST_FWD_REF(Args)... args) - { return dtl::force_copy< std::pair >(m_flat_tree.emplace_unique(boost::forward(args)...)); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args) - { - return dtl::force_copy - (m_flat_tree.emplace_hint_unique( dtl::force_copy(hint) - , boost::forward(args)...)); - } - - //! Requires: value_type shall be EmplaceConstructible into map from piecewise_construct, - //! forward_as_tuple(k), forward_as_tuple(forward(args)...). - //! - //! Effects: 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)...). - //! - //! Returns: 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. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_FORCEINLINE std::pair try_emplace(const key_type& k, BOOST_FWD_REF(Args)... args) - { - return dtl::force_copy< std::pair >( - m_flat_tree.try_emplace(impl_const_iterator(), k, boost::forward(args)...)); - } - - //! Requires: value_type shall be EmplaceConstructible into map from piecewise_construct, - //! forward_as_tuple(k), forward_as_tuple(forward(args)...). - //! - //! Effects: 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)...). - //! - //! Returns: The returned iterator points to the map element whose key is equivalent to k. - //! - //! Complexity: Logarithmic in general, but amortized constant if value - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k, BOOST_FWD_REF(Args)... args) - { - return dtl::force_copy(m_flat_tree.try_emplace - (dtl::force_copy(hint), k, boost::forward(args)...).first); - } - - //! Requires: value_type shall be EmplaceConstructible into map from piecewise_construct, - //! forward_as_tuple(move(k)), forward_as_tuple(forward(args)...). - //! - //! Effects: 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)...). - //! - //! Returns: 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. - //! - //! Complexity: Logarithmic search time plus linear insertion time in case the key is not present. - template - BOOST_CONTAINER_FORCEINLINE std::pair try_emplace(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args) - { - return dtl::force_copy< std::pair > - (m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k), boost::forward(args)...)); - } - - //! Requires: value_type shall be EmplaceConstructible into map from piecewise_construct, - //! forward_as_tuple(move(k)), forward_as_tuple(forward(args)...). - //! - //! Effects: 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)...). - //! - //! Returns: The returned iterator points to the map element whose key is equivalent to k. - //! - //! Complexity: Logarithmic in general, but amortized constant if value - //! is inserted right before p. Linear insertion time in case no equivalent key is present. - template - BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args) - { - return dtl::force_copy - (m_flat_tree.try_emplace(dtl::force_copy - (hint), boost::move(k), boost::forward(args)...).first); - } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE std::pair emplace(BOOST_MOVE_UREF##N)\ - {\ - return dtl::force_copy< std::pair >\ - (m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - return dtl::force_copy(m_flat_tree.emplace_hint_unique\ - (dtl::force_copy(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 try_emplace(const key_type& k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - return dtl::force_copy< std::pair >\ - (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 dtl::force_copy(m_flat_tree.try_emplace\ - (dtl::force_copy(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 try_emplace(BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - return dtl::force_copy< std::pair >\ - (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 dtl::force_copy(m_flat_tree.try_emplace\ - (dtl::force_copy(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 - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - //! Effects: Inserts x if and only if there is no element in the container - //! with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE std::pair insert(const value_type& x) - { return dtl::force_copy >( - m_flat_tree.insert_unique(dtl::force(x))); } - - //! Effects: Inserts a new value_type move constructed from the pair if and - //! only if there is no element in the container with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE std::pair insert(BOOST_RV_REF(value_type) x) - { - return dtl::force_copy >( - m_flat_tree.insert_unique(boost::move(dtl::force(x)))); - } - - //! Effects: Inserts a new value_type constructed from the pair if and - //! only if there is no element in the container with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST - ( std::pair - , typename dtl::enable_if_c::value - BOOST_MOVE_I std::pair >::type) - insert(BOOST_FWD_REF(Pair) x) - { - return dtl::force_copy > - (m_flat_tree.emplace_unique(boost::forward(x))); - } - - //! Effects: Inserts a copy of x in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x) - { - return dtl::force_copy( - m_flat_tree.insert_unique( dtl::force_copy(p) - , dtl::force(x))); - } - - //! Effects: Inserts an element move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) - { - return dtl::force_copy - (m_flat_tree.insert_unique( dtl::force_copy(p) - , boost::move(dtl::force(x)))); - } - - //! Effects: Inserts an element constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST - ( iterator - , typename dtl::enable_if_c::value - BOOST_MOVE_I iterator>::type) - insert(const_iterator p, BOOST_FWD_REF(Pair) x) - { - return dtl::force_copy( - m_flat_tree.emplace_hint_unique(dtl::force_copy(p), boost::forward(x))); - } - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: N log(size()+N). - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { m_flat_tree.insert_unique(first, last); } - - //! Requires: first, last are not iterators into *this. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Effects: inserts each element from the range [first,last) if and only - //! if there is no element with key equivalent to the key of that element. This - //! function is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: Linear. - //! - //! Note: If an element is inserted it might invalidate elements. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last) - { m_flat_tree.insert_unique(ordered_unique_range, first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: inserts each element from the range [il.begin(), il.end()) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: N log(N). - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list il) - { - m_flat_tree.insert_unique( dtl::force(il).begin() - , dtl::force(il).end()); - } - - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Effects: inserts each element from the range [il.begin(), il.end()) if and only - //! if there is no element with key equivalent to the key of that element. This - //! function is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: Linear. - //! - //! Note: If an element is inserted it might invalidate elements. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list il) - { - m_flat_tree.insert_unique(ordered_unique_range - , dtl::force(il).begin() - , dtl::force(il).end()); - } -#endif - - //! Requires: this->get_allocator() == source.get_allocator(). - //! - //! Effects: Move-inserts each element from source into *this 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 moved from source. - //! - //! Complexity: Linear in this->size() + source.size(). - //! - //! Note: Invalidates all iterators and references. - template - BOOST_CONTAINER_FORCEINLINE void merge(flat_map& source) - { m_flat_tree.merge_unique(source.tree()); } - - //! @copydoc ::boost::container::flat_map::merge(flat_map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! @copydoc ::boost::container::flat_map::merge(flat_map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap& source) - { m_flat_tree.merge_unique(source.tree()); } - - //! @copydoc ::boost::container::flat_map::merge(flat_map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! Effects: Erases the element pointed to by p. - //! - //! Returns: Returns an iterator pointing to the element immediately - //! following q prior to the element being erased. If no such element exists, - //! returns end(). - //! - //! Complexity: Linear to the elements with keys bigger than p - //! - //! Note: Invalidates elements with keys - //! not less than the erased element. - BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p) - { - return dtl::force_copy - (m_flat_tree.erase(dtl::force_copy(p))); - } - - //! Effects: If present, erases the element in the container with key equivalent to x. - //! - //! Returns: Returns the number of erased elements (0/1). - //! - //! Complexity: Logarithmic search time plus erasure time - //! linear to the elements with bigger keys. - BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x) - { return m_flat_tree.erase_unique(x); } - - //! Effects: Erases all the elements in the range [first, last). - //! - //! Returns: Returns last. - //! - //! Complexity: size()*N where N is the distance from first to last. - //! - //! Complexity: Logarithmic search time plus erasure time - //! linear to the elements with bigger keys. - BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last) - { - return dtl::force_copy( - m_flat_tree.erase( dtl::force_copy(first) - , dtl::force_copy(last))); - } - - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE void swap(flat_map& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ) - { m_flat_tree.swap(x.m_flat_tree); } - - //! Effects: erase(begin(),end()). - //! - //! Postcondition: size() == 0. - //! - //! Complexity: linear in size(). - BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW - { m_flat_tree.clear(); } - - ////////////////////////////////////////////// - // - // observers - // - ////////////////////////////////////////////// - - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - key_compare key_comp() const - { return dtl::force_copy(m_flat_tree.key_comp()); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - value_compare value_comp() const - { return value_compare(dtl::force_copy(m_flat_tree.key_comp())); } - - ////////////////////////////////////////////// - // - // map operations - // - ////////////////////////////////////////////// - - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator find(const key_type& x) - { return dtl::force_copy(m_flat_tree.find(x)); } - - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator find(const key_type& x) const - { return dtl::force_copy(m_flat_tree.find(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator find(const K& x) - { return dtl::force_copy(m_flat_tree.find(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator find(const K& x) const - { return dtl::force_copy(m_flat_tree.find(x)); } - - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type count(const key_type& x) const - { return static_cast(m_flat_tree.find(x) != m_flat_tree.end()); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type count(const K& x) const - //Don't use find() != end optimization here as transparent comparators with key K might - //return a different range than key_type (which can only return a single element range) - { return m_flat_tree.count(x); } - - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool contains(const key_type& x) const - { return m_flat_tree.find(x) != m_flat_tree.end(); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool contains(const K& x) const - { return m_flat_tree.find(x) != m_flat_tree.end(); } - - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator lower_bound(const key_type& x) - { return dtl::force_copy(m_flat_tree.lower_bound(x)); } - - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator lower_bound(const key_type& x) const - { return dtl::force_copy(m_flat_tree.lower_bound(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator lower_bound(const K& x) - { return dtl::force_copy(m_flat_tree.lower_bound(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator lower_bound(const K& x) const - { return dtl::force_copy(m_flat_tree.lower_bound(x)); } - - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator upper_bound(const key_type& x) - { return dtl::force_copy(m_flat_tree.upper_bound(x)); } - - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator upper_bound(const key_type& x) const - { return dtl::force_copy(m_flat_tree.upper_bound(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator upper_bound(const K& x) - { return dtl::force_copy(m_flat_tree.upper_bound(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator upper_bound(const K& x) const - { return dtl::force_copy(m_flat_tree.upper_bound(x)); } - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - std::pair equal_range(const key_type& x) - { return dtl::force_copy >(m_flat_tree.lower_bound_range(x)); } - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - std::pair equal_range(const key_type& x) const - { return dtl::force_copy >(m_flat_tree.lower_bound_range(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - std::pair equal_range(const K& x) - //Don't use lower_bound_range optimization here as transparent comparators with key K might - //return a different range than key_type (which can only return a single element range) - { return dtl::force_copy >(m_flat_tree.equal_range(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - std::pair equal_range(const K& x) const - //Don't use lower_bound_range optimization here as transparent comparators with key K might - //return a different range than key_type (which can only return a single element range) - { return dtl::force_copy >(m_flat_tree.equal_range(x)); } - - //! Effects: Extracts the internal sequence container. - //! - //! Complexity: Same as the move constructor of sequence_type, usually constant. - //! - //! Postcondition: this->empty() - //! - //! Throws: If secuence_type's move constructor throws - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence() - { - return boost::move(dtl::force(m_flat_tree.get_sequence_ref())); - } - - //! Effects: Discards the internally hold sequence container and adopts the - //! one passed externally using the move assignment. Erases non-unique elements. - //! - //! Complexity: Assuming O(1) move assignment, O(NlogN) with N = seq.size() - //! - //! Throws: If the comparison or the move constructor throws - BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq) - { this->m_flat_tree.adopt_sequence_unique(boost::move(dtl::force(seq))); } - - //! Requires: seq shall be ordered according to this->compare() - //! and shall contain unique elements. - //! - //! Effects: Discards the internally hold sequence container and adopts the - //! one passed externally using the move assignment. - //! - //! Complexity: Assuming O(1) move assignment, O(1) - //! - //! Throws: If the move assignment throws - BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq) - { this->m_flat_tree.adopt_sequence_unique(ordered_unique_range_t(), boost::move(dtl::force(seq))); } - - //! Effects: Returns a const view of the underlying sequence. - //! - //! Complexity: Constant - //! - //! Throws: Nothing - BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT - { return dtl::force(m_flat_tree.get_sequence_cref()); } - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const flat_map& x, const flat_map& y) - { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const flat_map& x, const flat_map& y) - { return !(x == y); } - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const flat_map& x, const flat_map& y) - { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const flat_map& x, const flat_map& y) - { return y < x; } - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const flat_map& x, const flat_map& y) - { return !(y < x); } - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const flat_map& x, const flat_map& y) - { return !(x < y); } - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE friend void swap(flat_map& x, flat_map& y) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) - { x.swap(y); } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - mapped_type &priv_subscript(const key_type& k) - { - iterator i = this->lower_bound(k); - // i->first is greater than or equivalent to k. - if (i == end() || key_comp()(k, (*i).first)){ - dtl::value_init m; - impl_value_type v(k, ::boost::move(m.m_t)); - i = this->insert(i, ::boost::move(v)); - } - return (*i).second; - } - mapped_type &priv_subscript(BOOST_RV_REF(key_type) mk) - { - key_type &k = mk; - iterator i = this->lower_bound(k); - // i->first is greater than or equivalent to k. - if (i == end() || key_comp()(k, (*i).first)){ - dtl::value_init m; - impl_value_type v(::boost::move(k), ::boost::move(m.m_t)); - i = this->insert(i, ::boost::move(v)); - } - return (*i).second; - } - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -flat_map(InputIterator, InputIterator) -> - flat_map< it_based_non_const_first_type_t - , it_based_second_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> - flat_map(InputIterator, InputIterator, AllocatorOrCompare const&) -> - flat_map< it_based_non_const_first_type_t - , it_based_second_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator, it_based_second_type_t>> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -flat_map(InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_map< it_based_non_const_first_type_t - , it_based_second_type_t - , Compare - , Allocator>; - -template -flat_map(ordered_unique_range_t, InputIterator, InputIterator) -> - flat_map< it_based_non_const_first_type_t - , it_based_second_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> -flat_map(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> - flat_map< it_based_non_const_first_type_t - , it_based_second_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator, it_based_second_type_t>> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_map< it_based_non_const_first_type_t - , it_based_second_type_t - , Compare - , Allocator>; - -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef ::boost::container::dtl::pair value_t; - typedef typename ::boost::container::dtl::container_or_allocator_rebind::type alloc_or_cont_t; - typedef ::boost::container::dtl::flat_tree, Compare, alloc_or_cont_t> tree; - static const bool value = ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! A flat_multimap is a kind of associative container that supports equivalent keys -//! (possibly containing multiple copies of the same key value) and provides for -//! fast retrieval of values of another type T based on the keys. -//! -//! A flat_multimap satisfies all of the requirements of a container and of a reversible -//! container and of an associative container. For a -//! flat_multimap the key_type is Key and the value_type is std::pair -//! (unlike std::multimap which value_type is std::pair<const Key, T>). -//! -//! flat_multimap is similar to std::multimap but it's implemented by as an ordered sequence container. -//! The underlying sequence container is by default vector but it can also work -//! user-provided vector-like SequenceContainers (like static_vector or small_vector). -//! -//! Using vector-like sequence containers means that inserting a new element into a flat_multimap might invalidate -//! previous iterators and references (unless that sequence container is stable_vector or a similar -//! container that offers stable pointers and references). Similarly, erasing an element might invalidate -//! iterators and references pointing to elements that come after (their keys are bigger) the erased element. -//! -//! This container provides random-access iterators. -//! -//! \tparam Key is the key_type of the map -//! \tparam Value is the mapped_type -//! \tparam Compare is the ordering function for Keys (e.g. std::less). -//! \tparam AllocatorOrContainer is either: -//! - The allocator to allocate value_types (e.g. allocator< std::pair > ). -//! (in this case sequence_type will be vector) -//! - The SequenceContainer to be used as the underlying sequence_type. It must be a vector-like -//! sequence container with random-access iterators. -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class AllocatorOrContainer = new_allocator< std::pair< Key, T> > > -#else -template -#endif -class flat_multimap -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(flat_multimap) - typedef dtl::flat_tree< - std::pair, - dtl::select1st, - Compare, - AllocatorOrContainer> tree_t; - //This is the real tree stored here. It's based on a movable pair - typedef dtl::flat_tree< - dtl::pair, - dtl::select1st, - Compare, - typename dtl::container_or_allocator_rebind >::type - > impl_tree_t; - impl_tree_t m_flat_tree; // flat tree representing flat_map - - typedef typename impl_tree_t::value_type impl_value_type; - typedef typename impl_tree_t::const_iterator impl_const_iterator; - typedef typename impl_tree_t::iterator impl_iterator; - typedef typename impl_tree_t::allocator_type impl_allocator_type; - #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - typedef std::initializer_list impl_initializer_list; - #endif - - typedef dtl::flat_tree_value_compare - < Compare - , dtl::select1st - , std::pair > value_compare_t; - typedef typename tree_t::iterator iterator_t; - typedef typename tree_t::const_iterator const_iterator_t; - typedef typename tree_t::reverse_iterator reverse_iterator_t; - typedef typename tree_t::const_reverse_iterator const_reverse_iterator_t; - - public: - typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type; - typedef typename impl_tree_t::sequence_type impl_sequence_type; - - BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree() - { return m_flat_tree; } - - BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const - { return m_flat_tree; } - - private: - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - typedef Key key_type; - typedef T mapped_type; - typedef Compare key_compare; - typedef std::pair value_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type; - typedef typename sequence_type::allocator_type allocator_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename sequence_type::pointer pointer; - typedef typename sequence_type::const_pointer const_pointer; - typedef typename sequence_type::reference reference; - typedef typename sequence_type::const_reference const_reference; - typedef typename sequence_type::size_type size_type; - typedef typename sequence_type::difference_type difference_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare; - - typedef typename sequence_type::iterator iterator; - typedef typename sequence_type::const_iterator const_iterator; - typedef typename sequence_type::reverse_iterator reverse_iterator; - typedef typename sequence_type::const_reverse_iterator const_reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; - - //AllocatorOrContainer::value_type must be std::pair - BOOST_STATIC_ASSERT((dtl::is_same, value_type>::value)); - - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructs an empty flat_map. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE flat_multimap() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value && - dtl::is_nothrow_default_constructible::value) - : m_flat_tree() - {} - - //! Effects: Constructs an empty flat_multimap using the specified allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const allocator_type& a) - : m_flat_tree(dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison - //! object . - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const Compare& comp) - : m_flat_tree(comp) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison - //! object and allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(const Compare& comp, const allocator_type& a) - : m_flat_tree(comp, dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_multimap - //! and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE - flat_multimap(InputIterator first, InputIterator last) - : m_flat_tree(false, first, last) - {} - - //! Effects: Constructs an empty flat_multimap using the specified - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE - flat_multimap(InputIterator first, InputIterator last, const allocator_type& a) - : m_flat_tree(false, first, last, dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison object - //! and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE - flat_multimap(InputIterator first, InputIterator last, const Compare& comp) - : m_flat_tree(false, first, last, comp) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison object - //! and allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE - flat_multimap(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : m_flat_tree(false, first, last, comp, dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_multimap - //! and inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_multimap(ordered_range_t, InputIterator first, InputIterator last) - : m_flat_tree(ordered_range, first, last) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison object and - //! inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp) - : m_flat_tree(ordered_range, first, last, comp) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison object and - //! allocator, and inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : m_flat_tree(ordered_range, first, last, comp, a) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison object and - //! inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a) - : m_flat_tree(ordered_range, first, last, Compare(), a) - {} - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs an empty flat_map and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(std::initializer_list il) - : m_flat_tree( false - , dtl::force(il).begin() - , dtl::force(il).end()) - {} - - //! Effects: Constructs an empty flat_map using the specified - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(std::initializer_list il, const allocator_type& a) - : m_flat_tree(false - , dtl::force(il).begin() - , dtl::force(il).end() - , dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(std::initializer_list il, const Compare& comp) - : m_flat_tree(false - , dtl::force(il).begin() - , dtl::force(il).end(), comp) - {} - - //! Effects: Constructs an empty flat_map using the specified comparison object and - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(std::initializer_list il, const Compare& comp, const allocator_type& a) - : m_flat_tree( false - , dtl::force(il).begin() - , dtl::force(il).end() - , comp, dtl::force(a)) - {} - - //! Effects: Constructs an empty flat_multimap and - //! inserts elements from the ordered range [il.begin(), il.end()). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(ordered_range_t, std::initializer_list il) - : m_flat_tree( ordered_range - , dtl::force(il).begin() - , dtl::force(il).end()) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison object and - //! inserts elements from the ordered range [il.begin(), il.end()). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(ordered_range_t, std::initializer_list il, const Compare& comp) - : m_flat_tree( ordered_range - , dtl::force(il).begin() - , dtl::force(il).end(), comp) - {} - - //! Effects: Constructs an empty flat_multimap using the specified comparison object and - //! allocator, and inserts elements from the ordered range [il.begin(), il.end()). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(ordered_range_t, std::initializer_list il, const Compare& comp, const allocator_type& a) - : m_flat_tree( ordered_range - , dtl::force(il).begin() - , dtl::force(il).end() - , comp, dtl::force(a)) - {} -#endif - - //! Effects: Copy constructs a flat_multimap. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE - flat_multimap(const flat_multimap& x) - : m_flat_tree(x.m_flat_tree) - {} - - //! Effects: Move constructs a flat_multimap. Constructs *this using x's resources. - //! - //! Complexity: Constant. - //! - //! Postcondition: x is emptied. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(BOOST_RV_REF(flat_multimap) x) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : m_flat_tree(boost::move(x.m_flat_tree)) - {} - - //! Effects: Copy constructs a flat_multimap using the specified allocator. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE - flat_multimap(const flat_multimap& x, const allocator_type &a) - : m_flat_tree(x.m_flat_tree, dtl::force(a)) - {} - - //! Effects: Move constructs a flat_multimap using the specified allocator. - //! Constructs *this using x's resources. - //! - //! Complexity: Constant if a == x.get_allocator(), linear otherwise. - BOOST_CONTAINER_FORCEINLINE - flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a) - : m_flat_tree(boost::move(x.m_flat_tree), dtl::force(a)) - {} - - //! Effects: Makes *this a copy of x. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE - flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x) - { m_flat_tree = x.m_flat_tree; return *this; } - - //! Effects: this->swap(x.get()). - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE - flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x) - BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value || - allocator_traits_type::is_always_equal::value) && - boost::container::dtl::is_nothrow_move_assignable::value) - { m_flat_tree = boost::move(x.m_flat_tree); return *this; } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Assign content of il to *this - //! - //! Complexity: Linear in il.size(). - BOOST_CONTAINER_FORCEINLINE - flat_multimap& operator=(std::initializer_list il) - { - this->clear(); - this->insert(il.begin(), il.end()); - return *this; - } -#endif - - //! Effects: Returns a copy of the allocator that - //! was passed to the object's constructor. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.get_allocator()); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force(m_flat_tree.get_stored_allocator()); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force(m_flat_tree.get_stored_allocator()); } - - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// - - //! Effects: Returns an iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.begin()); } - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.begin()); } - - //! Effects: Returns an iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator end() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.end()); } - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.end()); } - - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.rbegin()); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.rbegin()); } - - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.rend()); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.rend()); } - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.cbegin()); } - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.cend()); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.crbegin()); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.crend()); } - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// - - //! Effects: Returns true if the container contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.empty(); } - - //! Effects: Returns the number of the elements contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.size(); } - - //! Effects: Returns the largest possible size of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.max_size(); } - - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.capacity(); } - - //! Effects: If n is less than or equal to capacity(), or the - //! underlying container has no `reserve` member, this call has no - //! effect. Otherwise, it is a request for allocation of additional memory. - //! If the request is successful, then capacity() is greater than or equal to - //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. - //! - //! Throws: If memory allocation allocation throws or T's copy constructor throws. - //! - //! Note: If capacity() is less than "cnt", iterators and references to - //! to values might be invalidated. - BOOST_CONTAINER_FORCEINLINE - void reserve(size_type cnt) - { m_flat_tree.reserve(cnt); } - - //! Effects: Tries to deallocate the excess of memory created - // with previous allocations. The size of the vector is unchanged - //! - //! Throws: If memory allocation throws, or T's copy constructor throws. - //! - //! Complexity: Linear to size(). - BOOST_CONTAINER_FORCEINLINE - void shrink_to_fit() - { m_flat_tree.shrink_to_fit(); } - - //! @copydoc ::boost::container::flat_set::nth(size_type) - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.nth(n)); } - - //! @copydoc ::boost::container::flat_set::nth(size_type) const - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { return dtl::force_copy(m_flat_tree.nth(n)); } - - //! @copydoc ::boost::container::flat_set::index_of(iterator) - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.index_of(dtl::force_copy(p)); } - - //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW - { return m_flat_tree.index_of(dtl::force_copy(p)); } - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE - iterator emplace(BOOST_FWD_REF(Args)... args) - { return dtl::force_copy(m_flat_tree.emplace_equal(boost::forward(args)...)); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant time if the value - //! is to be inserted before p) plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE - iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args) - { - return dtl::force_copy(m_flat_tree.emplace_hint_equal - (dtl::force_copy(hint), boost::forward(args)...)); - } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\ - { return dtl::force_copy(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - return dtl::force_copy(m_flat_tree.emplace_hint_equal\ - (dtl::force_copy(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE) - #undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - //! Effects: Inserts x and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x) - { - return dtl::force_copy( - m_flat_tree.insert_equal(dtl::force(x))); - } - - //! Effects: Inserts a new value constructed from x and returns - //! the iterator pointing to the newly inserted element. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST - ( iterator - , typename dtl::enable_if_c::value - BOOST_MOVE_I iterator >::type) - insert(BOOST_FWD_REF(Pair) x) - { return dtl::force_copy(m_flat_tree.emplace_equal(boost::forward(x))); } - - //! Effects: Inserts a copy of x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant time if the value - //! is to be inserted before p) plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x) - { - return dtl::force_copy - (m_flat_tree.insert_equal( dtl::force_copy(p) - , dtl::force(x))); - } - - //! Effects: Inserts a value constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant time if the value - //! is to be inserted before p) plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST - ( iterator - , typename dtl::enable_if_c::value - BOOST_MOVE_I iterator>::type) - insert(const_iterator p, BOOST_FWD_REF(Pair) x) - { - return dtl::force_copy( - m_flat_tree.emplace_hint_equal(dtl::force_copy(p), boost::forward(x))); - } - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) . - //! - //! Complexity: N log(N). - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { m_flat_tree.insert_equal(first, last); } - - //! Requires: first, last are not iterators into *this. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Effects: inserts each element from the range [first,last) if and only - //! if there is no element with key equivalent to the key of that element. This - //! function is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: Linear. - //! - //! Note: If an element is inserted it might invalidate elements. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last) - { m_flat_tree.insert_equal(ordered_range, first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: inserts each element from the range [il.begin(), il.end()) . - //! - //! Complexity: N log(N). - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list il) - { - m_flat_tree.insert_equal( dtl::force(il).begin() - , dtl::force(il).end()); - } - - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Effects: inserts each element from the range [il.begin(), il.end()) if and only - //! if there is no element with key equivalent to the key of that element. This - //! function is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: Linear. - //! - //! Note: If an element is inserted it might invalidate elements. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list il) - { - m_flat_tree.insert_equal( ordered_range - , dtl::force(il).begin() - , dtl::force(il).end()); - } -#endif - - //! Requires: this->get_allocator() == source.get_allocator(). - //! - //! Effects: Move-inserts each element from source into *this a using - //! the comparison object of *this. - //! - //! Complexity: Linear in this->size() + source.size(). - //! - //! Note: Invalidates all iterators and references. - template - BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap& source) - { m_flat_tree.merge_equal(source.tree()); } - - //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap&) - template - BOOST_CONTAINER_FORCEINLINE void merge(flat_map& source) - { m_flat_tree.merge_equal(source.tree()); } - - //! @copydoc ::boost::container::flat_multimap::merge(flat_map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! Effects: Erases the element pointed to by p. - //! - //! Returns: Returns an iterator pointing to the element immediately - //! following q prior to the element being erased. If no such element exists, - //! returns end(). - //! - //! Complexity: Linear to the elements with keys bigger than p - //! - //! Note: Invalidates elements with keys - //! not less than the erased element. - BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p) - { - return dtl::force_copy( - m_flat_tree.erase(dtl::force_copy(p))); - } - - //! Effects: Erases all elements in the container with key equivalent to x. - //! - //! Returns: Returns the number of erased elements. - //! - //! Complexity: Logarithmic search time plus erasure time - //! linear to the elements with bigger keys. - BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x) - { return m_flat_tree.erase(x); } - - //! Effects: Erases all the elements in the range [first, last). - //! - //! Returns: Returns last. - //! - //! Complexity: size()*N where N is the distance from first to last. - //! - //! Complexity: Logarithmic search time plus erasure time - //! linear to the elements with bigger keys. - BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last) - { - return dtl::force_copy - (m_flat_tree.erase( dtl::force_copy(first) - , dtl::force_copy(last))); - } - - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE void swap(flat_multimap& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ) - { m_flat_tree.swap(x.m_flat_tree); } - - //! Effects: erase(begin(),end()). - //! - //! Postcondition: size() == 0. - //! - //! Complexity: linear in size(). - BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW - { m_flat_tree.clear(); } - - ////////////////////////////////////////////// - // - // observers - // - ////////////////////////////////////////////// - - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - key_compare key_comp() const - { return dtl::force_copy(m_flat_tree.key_comp()); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - value_compare value_comp() const - { return value_compare(dtl::force_copy(m_flat_tree.key_comp())); } - - ////////////////////////////////////////////// - // - // map operations - // - ////////////////////////////////////////////// - - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator find(const key_type& x) - { return dtl::force_copy(m_flat_tree.find(x)); } - - //! Returns: An const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator find(const key_type& x) const - { return dtl::force_copy(m_flat_tree.find(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator find(const K& x) - { return dtl::force_copy(m_flat_tree.find(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator find(const K& x) const - { return dtl::force_copy(m_flat_tree.find(x)); } - - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type count(const key_type& x) const - { return m_flat_tree.count(x); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type count(const K& x) const - { return m_flat_tree.count(x); } - - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool contains(const key_type& x) const - { return m_flat_tree.find(x) != m_flat_tree.end(); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool contains(const K& x) const - { return m_flat_tree.find(x) != m_flat_tree.end(); } - - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator lower_bound(const key_type& x) - { return dtl::force_copy(m_flat_tree.lower_bound(x)); } - - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator lower_bound(const key_type& x) const - { return dtl::force_copy(m_flat_tree.lower_bound(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator lower_bound(const K& x) - { return dtl::force_copy(m_flat_tree.lower_bound(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator lower_bound(const K& x) const - { return dtl::force_copy(m_flat_tree.lower_bound(x)); } - - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator upper_bound(const key_type& x) - {return dtl::force_copy(m_flat_tree.upper_bound(x)); } - - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator upper_bound(const key_type& x) const - { return dtl::force_copy(m_flat_tree.upper_bound(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator upper_bound(const K& x) - {return dtl::force_copy(m_flat_tree.upper_bound(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator upper_bound(const K& x) const - { return dtl::force_copy(m_flat_tree.upper_bound(x)); } - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - std::pair equal_range(const key_type& x) - { return dtl::force_copy >(m_flat_tree.equal_range(x)); } - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - std::pair equal_range(const key_type& x) const - { return dtl::force_copy >(m_flat_tree.equal_range(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - std::pair equal_range(const K& x) - { return dtl::force_copy >(m_flat_tree.equal_range(x)); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - std::pair equal_range(const K& x) const - { return dtl::force_copy >(m_flat_tree.equal_range(x)); } - - //! Effects: Extracts the internal sequence container. - //! - //! Complexity: Same as the move constructor of sequence_type, usually constant. - //! - //! Postcondition: this->empty() - //! - //! Throws: If secuence_type's move constructor throws - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - sequence_type extract_sequence() - { return boost::move(dtl::force(m_flat_tree.get_sequence_ref())); } - - //! Effects: Discards the internally hold sequence container and adopts the - //! one passed externally using the move assignment. - //! - //! Complexity: Assuming O(1) move assignment, O(NlogN) with N = seq.size() - //! - //! Throws: If the comparison or the move constructor throws - BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq) - { this->m_flat_tree.adopt_sequence_equal(boost::move(dtl::force(seq))); } - - //! Requires: seq shall be ordered according to this->compare(). - //! - //! Effects: Discards the internally hold sequence container and adopts the - //! one passed externally using the move assignment. - //! - //! Complexity: Assuming O(1) move assignment, O(1) - //! - //! Throws: If the move assignment throws - BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq) - { this->m_flat_tree.adopt_sequence_equal(ordered_range_t(), boost::move(dtl::force(seq))); } - - //! Effects: Returns a const view of the underlying sequence. - //! - //! Complexity: Constant - //! - //! Throws: Nothing - BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT - { return dtl::force(m_flat_tree.get_sequence_cref()); } - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const flat_multimap& x, const flat_multimap& y) - { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const flat_multimap& x, const flat_multimap& y) - { return !(x == y); } - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const flat_multimap& x, const flat_multimap& y) - { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const flat_multimap& x, const flat_multimap& y) - { return y < x; } - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const flat_multimap& x, const flat_multimap& y) - { return !(y < x); } - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const flat_multimap& x, const flat_multimap& y) - { return !(x < y); } - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE friend void swap(flat_multimap& x, flat_multimap& y) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) - { x.swap(y); } -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -flat_multimap(InputIterator, InputIterator) -> - flat_multimap< it_based_non_const_first_type_t - , it_based_second_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> -flat_multimap(InputIterator, InputIterator, AllocatorOrCompare const&) -> - flat_multimap< it_based_non_const_first_type_t - , it_based_second_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator, it_based_second_type_t>> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -flat_multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_multimap< it_based_non_const_first_type_t - , it_based_second_type_t - , Compare - , Allocator>; - -template -flat_multimap(ordered_range_t, InputIterator, InputIterator) -> - flat_multimap< it_based_non_const_first_type_t - , it_based_second_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> -flat_multimap(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> - flat_multimap< it_based_non_const_first_type_t - , it_based_second_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator, it_based_second_type_t>> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_multimap< it_based_non_const_first_type_t - , it_based_second_type_t - , Compare - , Allocator>; - -#endif - -}} - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -namespace boost { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move< boost::container::flat_multimap > -{ - typedef ::boost::container::dtl::pair value_t; - typedef typename ::boost::container::dtl::container_or_allocator_rebind::type alloc_or_cont_t; - typedef ::boost::container::dtl::flat_tree, Compare, alloc_or_cont_t> tree; - static const bool value = ::boost::has_trivial_destructor_after_move::value; -}; - -} //namespace boost { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#include - -#endif // BOOST_CONTAINER_FLAT_MAP_HPP diff --git a/inst/i/b/container/flat_set.hpp b/inst/i/b/container/flat_set.hpp deleted file mode 100644 index 65dc504af..000000000 --- a/inst/i/b/container/flat_set.hpp +++ /dev/null @@ -1,1946 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2005-2013. 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_FLAT_SET_HPP -#define BOOST_CONTAINER_FLAT_SET_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include - -// container -#include -#include -#include //new_allocator -// container/detail -#include -#include -// move -#include -#include -// move/detail -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -#include -// intrusive/detail -#include //pair -#include //less, equal -// std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -namespace boost { -namespace container { - -#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -template -class flat_multiset; -#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. -//! -//! flat_set is similar to std::set but it's implemented by as an ordered sequence container. -//! The underlying sequence container is by default vector but it can also work -//! user-provided vector-like SequenceContainers (like static_vector or small_vector). -//! -//! Using vector-like sequence containers means that inserting a new element into a flat_set might invalidate -//! previous iterators and references (unless that sequence container is stable_vector or a similar -//! container that offers stable pointers and references). Similarly, erasing an element might invalidate -//! iterators and references pointing to elements that come after (their keys are bigger) the erased element. -//! -//! This container provides random-access iterators. -//! -//! \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 AllocatorOrContainer is either: -//! - The allocator to allocate value_types (e.g. allocator< std::pair > ). -//! (in this case sequence_type will be vector) -//! - The SequenceContainer to be used as the underlying sequence_type. It must be a vector-like -//! sequence container with random-access iterators. -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class AllocatorOrContainer = new_allocator > -#else -template -#endif -class flat_set - ///@cond - : public dtl::flat_tree, Compare, AllocatorOrContainer> - ///@endcond -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(flat_set) - typedef dtl::flat_tree, Compare, AllocatorOrContainer> tree_t; - - public: - tree_t &tree() - { return *this; } - - const tree_t &tree() const - { return *this; } - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - typedef Key key_type; - typedef Compare key_compare; - typedef Key value_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type; - typedef typename sequence_type::allocator_type allocator_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename sequence_type::pointer pointer; - typedef typename sequence_type::const_pointer const_pointer; - typedef typename sequence_type::reference reference; - typedef typename sequence_type::const_reference const_reference; - typedef typename sequence_type::size_type size_type; - typedef typename sequence_type::difference_type difference_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare; - - typedef typename sequence_type::iterator iterator; - typedef typename sequence_type::const_iterator const_iterator; - typedef typename sequence_type::reverse_iterator reverse_iterator; - typedef typename sequence_type::const_reverse_iterator const_reverse_iterator; - - public: - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructs an empty container. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE - flat_set() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value && - dtl::is_nothrow_default_constructible::value) - : tree_t() - {} - - //! Effects: Constructs an empty container using the specified - //! comparison object. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE - explicit flat_set(const Compare& comp) - : tree_t(comp) - {} - - //! Effects: Constructs an empty container using the specified allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE - explicit flat_set(const allocator_type& a) - : tree_t(a) - {} - - //! Effects: Constructs an empty container using the specified - //! comparison object and allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE - flat_set(const Compare& comp, const allocator_type& a) - : tree_t(comp, a) - {} - - //! Effects: Constructs an empty container and - //! inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! comp and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE - flat_set(InputIterator first, InputIterator last) - : tree_t(true, first, last) - {} - - //! Effects: Constructs an empty container using the specified - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! comp and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE - flat_set(InputIterator first, InputIterator last, const allocator_type& a) - : tree_t(true, first, last, a) - {} - - //! Effects: Constructs an empty container using the specified comparison object and - //! inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! comp and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE - flat_set(InputIterator first, InputIterator last, const Compare& comp) - : tree_t(true, first, last, comp) - {} - - //! Effects: Constructs an empty container using the specified comparison object and - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! comp and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE - flat_set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : tree_t(true, first, last, comp, a) - {} - - //! Effects: Constructs an empty container and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_set(ordered_unique_range_t, InputIterator first, InputIterator last) - : tree_t(ordered_unique_range, first, last) - {} - - //! Effects: Constructs an empty container using the specified comparison object and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp) - : tree_t(ordered_unique_range, first, last, comp) - {} - - //! Effects: Constructs an empty container using the specified comparison object and - //! allocator, and inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : tree_t(ordered_unique_range, first, last, comp, a) - {} - - //! Effects: Constructs an empty container using the specified allocator and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE - flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) - : tree_t(ordered_unique_range, first, last, Compare(), a) - {} - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs an empty container and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! comp and otherwise N logN, where N is il.begin() - il.end(). - BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list il) - : tree_t(true, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty container using the specified - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! comp and otherwise N logN, where N is il.begin() - il.end(). - BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list il, const allocator_type& a) - : tree_t(true, il.begin(), il.end(), a) - {} - - //! Effects: Constructs an empty container using the specified comparison object and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! comp and otherwise N logN, where N is il.begin() - il.end(). - BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list il, const Compare& comp) - : tree_t(true, il.begin(), il.end(), comp) - {} - - //! Effects: Constructs an empty container using the specified comparison object and - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! comp and otherwise N logN, where N is il.begin() - il.end(). - BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list il, const Compare& comp, const allocator_type& a) - : tree_t(true, il.begin(), il.end(), comp, a) - {} - - //! Effects: Constructs an empty container using the specified comparison object 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list il) - : tree_t(ordered_unique_range, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty container using the specified comparison object 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list il, const Compare& comp) - : tree_t(ordered_unique_range, il.begin(), il.end(), comp) - {} - - //! Effects: 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list il, const Compare& comp, const allocator_type& a) - : tree_t(ordered_unique_range, il.begin(), il.end(), comp, a) - {} -#endif - - //! Effects: Copy constructs the container. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE flat_set(const flat_set& x) - : tree_t(static_cast(x)) - {} - - //! Effects: Move constructs thecontainer. Constructs *this using x's resources. - //! - //! Complexity: Constant. - //! - //! Postcondition: x is emptied. - BOOST_CONTAINER_FORCEINLINE flat_set(BOOST_RV_REF(flat_set) x) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : tree_t(BOOST_MOVE_BASE(tree_t, x)) - {} - - //! Effects: Copy constructs a container using the specified allocator. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE flat_set(const flat_set& x, const allocator_type &a) - : tree_t(static_cast(x), a) - {} - - //! Effects: Move constructs a container using the specified allocator. - //! Constructs *this using x's resources. - //! - //! Complexity: Constant if a == x.get_allocator(), linear otherwise - BOOST_CONTAINER_FORCEINLINE flat_set(BOOST_RV_REF(flat_set) x, const allocator_type &a) - : tree_t(BOOST_MOVE_BASE(tree_t, x), a) - {} - - //! Effects: Makes *this a copy of x. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x) - { return static_cast(this->tree_t::operator=(static_cast(x))); } - - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or value_type's move constructor throws) - //! - //! Complexity: Constant if allocator_traits_type:: - //! propagate_on_container_move_assignment is true or - //! this->get>allocator() == x.get_allocator(). Linear otherwise. - BOOST_CONTAINER_FORCEINLINE flat_set& operator=(BOOST_RV_REF(flat_set) x) - BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value || - allocator_traits_type::is_always_equal::value) && - boost::container::dtl::is_nothrow_move_assignable::value) - { return static_cast(this->tree_t::operator=(BOOST_MOVE_BASE(tree_t, x))); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Copy all elements from il to *this. - //! - //! Complexity: Linear in il.size(). - flat_set& operator=(std::initializer_list il) - { - this->clear(); - this->insert(il.begin(), il.end()); - return *this; - } -#endif - - #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - //! Effects: Returns a copy of the allocator that - //! was passed to the object's constructor. - //! - //! Complexity: Constant. - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns an iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns an iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator end() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns true if the container contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns the number of the elements contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns the largest possible size of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: If n is less than or equal to capacity(), or the - //! underlying container has no `reserve` member, this call has no - //! effect. Otherwise, it is a request for allocation of additional memory. - //! If the request is successful, then capacity() is greater than or equal to - //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. - //! - //! Throws: If memory allocation allocation throws or T's copy constructor throws. - //! - //! Note: If capacity() is less than "cnt", iterators and references to - //! to values might be invalidated. - void reserve(size_type cnt); - - //! Effects: Tries to deallocate the excess of memory created - // with previous allocations. The size of the vector is unchanged - //! - //! Throws: If memory allocation throws, or Key's copy constructor throws. - //! - //! Complexity: Linear to size(). - void shrink_to_fit(); - - #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object x of type Key constructed with - //! std::forward(args)... if and only if there is no element in the container - //! with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE std::pair emplace(BOOST_FWD_REF(Args)... args) - { return this->tree_t::emplace_unique(boost::forward(args)...); } - - //! Effects: Inserts an object of type Key constructed with - //! std::forward(args)... in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args) - { return this->tree_t::emplace_hint_unique(p, boost::forward(args)...); } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE std::pair emplace(BOOST_MOVE_UREF##N)\ - { return this->tree_t::emplace_unique(BOOST_MOVE_FWD##N); }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->tree_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE) - #undef BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts x if and only if there is no element in the container - //! with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - std::pair insert(const value_type &x); - - //! Effects: Inserts a new value_type move constructed from the pair if and - //! only if there is no element in the container with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - std::pair insert(value_type &&x); - #else - private: - typedef std::pair insert_return_pair; - public: - BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->tree_t::insert_unique) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const_iterator p, const value_type &x); - - //! Effects: Inserts an element move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const_iterator p, value_type &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->tree_t::insert_unique, const_iterator, const_iterator) - #endif - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: N log(N). - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->tree_t::insert_unique(first, last); } - - //! Requires: first, last are not iterators into *this and - //! must be ordered according to the predicate and must be - //! unique values. - //! - //! Effects: inserts each element from the range [first,last) .This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: Linear. - //! - //! Note: Non-standard extension. If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last) - { this->tree_t::insert_unique(ordered_unique_range, first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: inserts each element from the range [il.begin(), il.end()) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: N log(N). - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list il) - { this->tree_t::insert_unique(il.begin(), il.end()); } - - //! Requires: Range [il.begin(), il.end()) must be ordered according to the predicate - //! and must be unique values. - //! - //! Effects: inserts each element from the range [il.begin(), il.end()) .This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: Linear. - //! - //! Note: Non-standard extension. If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list il) - { this->tree_t::insert_unique(ordered_unique_range, il.begin(), il.end()); } -#endif - - //! @copydoc ::boost::container::flat_map::merge(flat_map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(flat_set& source) - { this->tree_t::merge_unique(source.tree()); } - - //! @copydoc ::boost::container::flat_set::merge(flat_set&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! @copydoc ::boost::container::flat_map::merge(flat_multimap&) - template - BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset& source) - { this->tree_t::merge_unique(source.tree()); } - - //! @copydoc ::boost::container::flat_set::merge(flat_multiset&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! Effects: If present, erases the element in the container with key equivalent to x. - //! - //! Returns: Returns the number of erased elements (0/1). - //! - //! Complexity: Logarithmic search time plus erasure time - //! linear to the elements with bigger keys. - BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x) - { return this->tree_t::erase_unique(x); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Erases the element pointed to by p. - //! - //! Returns: Returns an iterator pointing to the element immediately - //! following q prior to the element being erased. If no such element exists, - //! returns end(). - //! - //! Complexity: Linear to the elements with keys bigger than p - //! - //! Note: Invalidates elements with keys - //! not less than the erased element. - iterator erase(const_iterator p); - - //! Effects: Erases all the elements in the range [first, last). - //! - //! Returns: Returns last. - //! - //! Complexity: size()*N where N is the distance from first to last. - //! - //! Complexity: Logarithmic search time plus erasure time - //! linear to the elements with bigger keys. - iterator erase(const_iterator first, const_iterator last); - - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(flat_set& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - //! Effects: erase(begin(),end()). - //! - //! Postcondition: size() == 0. - //! - //! Complexity: linear in size(). - void clear() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const; - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const; - - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - iterator find(const key_type& x); - - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - const_iterator find(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - iterator find(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - const_iterator find(const K& x) const; - - //! Requires: size() >= n. - //! - //! Effects: Returns an iterator to the nth element - //! from the beginning of the container. Returns end() - //! if n == size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW; - - //! Requires: size() >= n. - //! - //! Effects: Returns a const_iterator to the nth element - //! from the beginning of the container. Returns end() - //! if n == size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Requires: begin() <= p <= end(). - //! - //! Effects: Returns the index of the element pointed by p - //! and size() if p == end(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW; - - //! Requires: begin() <= p <= end(). - //! - //! Effects: Returns the index of the element pointed by p - //! and size() if p == end(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW; - - #else - using tree_t::erase; - #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const - { return static_cast(this->tree_t::find(x) != this->tree_t::cend()); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - template - BOOST_CONTAINER_FORCEINLINE size_type count(const K& x) const - //Don't use find() != end optimization here as transparent comparators with key K might - //return a different range than key_type (which can only return a single element range) - { return this->tree_t::count(x); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - bool contains(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - template - bool contains(const K& x) const; - - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator lower_bound(const key_type& x); - - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator lower_bound(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - iterator lower_bound(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - const_iterator lower_bound(const K& x) const; - - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator upper_bound(const key_type& x); - - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator upper_bound(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - iterator upper_bound(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - const_iterator upper_bound(const K& x) const; - - #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_FORCEINLINE std::pair equal_range(const key_type& x) const - { return this->tree_t::lower_bound_range(x); } - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_FORCEINLINE std::pair equal_range(const key_type& x) - { return this->tree_t::lower_bound_range(x); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - std::pair equal_range(const K& x) - //Don't use lower_bound_range optimization here as transparent comparators with key K might - //return a different range than key_type (which can only return a single element range) - { return this->tree_t::equal_range(x); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - std::pair equal_range(const K& x) const - //Don't use lower_bound_range optimization here as transparent comparators with key K might - //return a different range than key_type (which can only return a single element range) - { return this->tree_t::equal_range(x); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const flat_set& x, const flat_set& y); - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const flat_set& x, const flat_set& y); - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const flat_set& x, const flat_set& y); - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const flat_set& x, const flat_set& y); - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<=(const flat_set& x, const flat_set& y); - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>=(const flat_set& x, const flat_set& y); - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - friend void swap(flat_set& x, flat_set& y) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - //! Effects: Extracts the internal sequence container. - //! - //! Complexity: Same as the move constructor of sequence_type, usually constant. - //! - //! Postcondition: this->empty() - //! - //! Throws: If sequence_type's move constructor throws - sequence_type extract_sequence(); - - #endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - - //! Effects: Discards the internally hold sequence container and adopts the - //! one passed externally using the move assignment. Erases non-unique elements. - //! - //! Complexity: Assuming O(1) move assignment, O(NlogN) with N = seq.size() - //! - //! Throws: If the comparison or the move constructor throws - BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq) - { this->tree_t::adopt_sequence_unique(boost::move(seq)); } - - //! Requires: seq shall be ordered according to this->compare() - //! and shall contain unique elements. - //! - //! Effects: Discards the internally hold sequence container and adopts the - //! one passed externally using the move assignment. - //! - //! Complexity: Assuming O(1) move assignment, O(1) - //! - //! Throws: If the move assignment throws - BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq) - { this->tree_t::adopt_sequence_unique(ordered_unique_range_t(), boost::move(seq)); } - - //! Effects: Returns a const view of the underlying sequence. - //! - //! Complexity: Constant - //! - //! Throws: Nothing - BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT - { return this->get_sequence_cref(); } -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -flat_set(InputIterator, InputIterator) -> - flat_set< it_based_value_type_t >; - -template < typename InputIterator, typename AllocatorOrCompare> - flat_set(InputIterator, InputIterator, AllocatorOrCompare const&) -> - flat_set< it_based_value_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -flat_set(InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_set< it_based_value_type_t - , Compare - , Allocator>; - -template -flat_set(ordered_unique_range_t, InputIterator, InputIterator) -> - flat_set< it_based_value_type_t>; - - -template < typename InputIterator, typename AllocatorOrCompare> - flat_set(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> - flat_set< it_based_value_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_set< it_based_value_type_t - , Compare - , Allocator>; - -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef ::boost::container::dtl::flat_tree, Compare, AllocatorOrContainer> tree; - static const bool value = ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! flat_multiset is a Sorted Associative Container that stores objects of type Key and -//! can store multiple copies of the same key value. -//! -//! flat_multiset is similar to std::multiset but it's implemented by as an ordered sequence container. -//! The underlying sequence container is by default vector but it can also work -//! user-provided vector-like SequenceContainers (like static_vector or small_vector). -//! -//! Using vector-like sequence containers means that inserting a new element into a flat_multiset might invalidate -//! previous iterators and references (unless that sequence container is stable_vector or a similar -//! container that offers stable pointers and references). Similarly, erasing an element might invalidate -//! iterators and references pointing to elements that come after (their keys are bigger) the erased element. -//! -//! This container provides random-access iterators. -//! -//! \tparam Key is the type to be inserted in the multiset, which is also the key_type -//! \tparam Compare is the comparison functor used to order keys -//! \tparam AllocatorOrContainer is either: -//! - The allocator to allocate value_types (e.g. allocator< std::pair > ). -//! (in this case sequence_type will be vector) -//! - The SequenceContainer to be used as the underlying sequence_type. It must be a vector-like -//! sequence container with random-access iterators. -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class AllocatorOrContainer = new_allocator > -#else -template -#endif -class flat_multiset - ///@cond - : public dtl::flat_tree, Compare, AllocatorOrContainer> - ///@endcond -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(flat_multiset) - typedef dtl::flat_tree, Compare, AllocatorOrContainer> tree_t; - - public: - tree_t &tree() - { return *this; } - - const tree_t &tree() const - { return *this; } - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - typedef Key key_type; - typedef Compare key_compare; - typedef Key value_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type; - typedef typename sequence_type::allocator_type allocator_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename sequence_type::pointer pointer; - typedef typename sequence_type::const_pointer const_pointer; - typedef typename sequence_type::reference reference; - typedef typename sequence_type::const_reference const_reference; - typedef typename sequence_type::size_type size_type; - typedef typename sequence_type::difference_type difference_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare; - - typedef typename sequence_type::iterator iterator; - typedef typename sequence_type::const_iterator const_iterator; - typedef typename sequence_type::reverse_iterator reverse_iterator; - typedef typename sequence_type::const_reverse_iterator const_reverse_iterator; - - //! @copydoc ::boost::container::flat_set::flat_set() - BOOST_CONTAINER_FORCEINLINE flat_multiset() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value && - dtl::is_nothrow_default_constructible::value) - : tree_t() - {} - - //! @copydoc ::boost::container::flat_set::flat_set(const Compare&) - BOOST_CONTAINER_FORCEINLINE explicit flat_multiset(const Compare& comp) - : tree_t(comp) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(const allocator_type&) - BOOST_CONTAINER_FORCEINLINE explicit flat_multiset(const allocator_type& a) - : tree_t(a) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(const Compare&, const allocator_type&) - BOOST_CONTAINER_FORCEINLINE flat_multiset(const Compare& comp, const allocator_type& a) - : tree_t(comp, a) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator) - template - BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last) - : tree_t(false, first, last) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const allocator_type&) - template - BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const allocator_type& a) - : tree_t(false, first, last, a) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const Compare& comp) - template - BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const Compare& comp) - : tree_t(false, first, last, comp) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const Compare& comp, const allocator_type&) - template - BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : tree_t(false, first, last, comp, a) - {} - - //! Effects: Constructs an empty flat_multiset and - //! inserts elements from the ordered range [first ,last ). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last) - : tree_t(ordered_range, first, last) - {} - - //! Effects: Constructs an empty flat_multiset using the specified comparison object and - //! inserts elements from the ordered range [first ,last ). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp) - : tree_t(ordered_range, first, last, comp) - {} - - //! Effects: Constructs an empty flat_multiset using the specified comparison object and - //! allocator, and inserts elements from the ordered range [first, last ). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : tree_t(ordered_range, first, last, comp, a) - {} - - //! Effects: Constructs an empty flat_multiset using the specified allocator and - //! inserts elements from the ordered range [first ,last ). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a) - : tree_t(ordered_range, first, last, Compare(), a) - {} - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list il) - : tree_t(false, il.begin(), il.end()) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list, const allocator_type&) - BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list il, const allocator_type& a) - : tree_t(false, il.begin(), il.end(), a) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list, const Compare& comp) - BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list il, const Compare& comp) - : tree_t(false, il.begin(), il.end(), comp) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list, const Compare& comp, const allocator_type&) - BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list il, const Compare& comp, const allocator_type& a) - : tree_t(false, il.begin(), il.end(), comp, a) - {} - - //! Effects: Constructs an empty containerand - //! inserts elements from the ordered unique range [il.begin(), il.end()). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list il) - : tree_t(ordered_range, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty container using the specified comparison object 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list il, const Compare& comp) - : tree_t(ordered_range, il.begin(), il.end(), comp) - {} - - //! Effects: 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list il, const Compare& comp, const allocator_type& a) - : tree_t(ordered_range, il.begin(), il.end(), comp, a) - {} -#endif - - //! @copydoc ::boost::container::flat_set::flat_set(const flat_set &) - BOOST_CONTAINER_FORCEINLINE flat_multiset(const flat_multiset& x) - : tree_t(static_cast(x)) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(flat_set &&) - BOOST_CONTAINER_FORCEINLINE flat_multiset(BOOST_RV_REF(flat_multiset) x) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : tree_t(boost::move(static_cast(x))) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(const flat_set &, const allocator_type &) - BOOST_CONTAINER_FORCEINLINE flat_multiset(const flat_multiset& x, const allocator_type &a) - : tree_t(static_cast(x), a) - {} - - //! @copydoc ::boost::container::flat_set::flat_set(flat_set &&, const allocator_type &) - BOOST_CONTAINER_FORCEINLINE flat_multiset(BOOST_RV_REF(flat_multiset) x, const allocator_type &a) - : tree_t(BOOST_MOVE_BASE(tree_t, x), a) - {} - - //! @copydoc ::boost::container::flat_set::operator=(const flat_set &) - BOOST_CONTAINER_FORCEINLINE flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x) - { return static_cast(this->tree_t::operator=(static_cast(x))); } - - //! @copydoc ::boost::container::flat_set::operator=(flat_set &&) - BOOST_CONTAINER_FORCEINLINE flat_multiset& operator=(BOOST_RV_REF(flat_multiset) x) - BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value || - allocator_traits_type::is_always_equal::value) && - boost::container::dtl::is_nothrow_move_assignable::value) - { return static_cast(this->tree_t::operator=(BOOST_MOVE_BASE(tree_t, x))); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! @copydoc ::boost::container::flat_set::operator=(std::initializer_list) - flat_multiset& operator=(std::initializer_list il) - { - this->clear(); - this->insert(il.begin(), il.end()); - return *this; - } -#endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! @copydoc ::boost::container::flat_set::get_allocator() - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::get_stored_allocator() - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::get_stored_allocator() const - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::begin() - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::begin() const - const_iterator begin() const; - - //! @copydoc ::boost::container::flat_set::cbegin() const - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::end() - iterator end() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::end() const - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::cend() const - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::rbegin() - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::rbegin() const - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::crbegin() const - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::rend() - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::rend() const - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::crend() const - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::empty() const - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::size() const - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::max_size() const - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::capacity() const - size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::reserve(size_type) - void reserve(size_type cnt); - - //! @copydoc ::boost::container::flat_set::shrink_to_fit() - void shrink_to_fit(); - - #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type Key constructed with - //! std::forward(args)... and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args) - { return this->tree_t::emplace_equal(boost::forward(args)...); } - - //! Effects: Inserts an object of type Key constructed with - //! std::forward(args)... in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args) - { return this->tree_t::emplace_hint_equal(p, boost::forward(args)...); } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\ - { return this->tree_t::emplace_equal(BOOST_MOVE_FWD##N); }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->tree_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE) - #undef BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts x and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const value_type &x); - - //! Effects: Inserts a new value_type move constructed from x - //! and returns the iterator pointing to the newly inserted element. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(value_type &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->tree_t::insert_equal) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const_iterator p, const value_type &x); - - //! Effects: Inserts a new value move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const_iterator p, value_type &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->tree_t::insert_equal, const_iterator, const_iterator) - #endif - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) . - //! - //! Complexity: N log(N). - //! - //! Note: If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->tree_t::insert_equal(first, last); } - - //! Requires: first, last are not iterators into *this and - //! must be ordered according to the predicate. - //! - //! Effects: inserts each element from the range [first,last) .This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: Linear. - //! - //! Note: Non-standard extension. If an element is inserted it might invalidate elements. - template - BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last) - { this->tree_t::insert_equal(ordered_range, first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: inserts each element from the range [il.begin(), il.end()). - //! - //! Complexity: N log(N). - //! - //! Note: If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list il) - { this->tree_t::insert_equal(il.begin(), il.end()); } - - //! Requires: Range [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Effects: inserts each element from the range [il.begin(), il.end()). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: Linear. - //! - //! Note: Non-standard extension. If an element is inserted it might invalidate elements. - BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list il) - { this->tree_t::insert_equal(ordered_range, il.begin(), il.end()); } -#endif - - //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap&) - template - BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset& source) - { this->tree_t::merge_equal(source.tree()); } - - //! @copydoc ::boost::container::flat_multiset::merge(flat_multiset&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! @copydoc ::boost::container::flat_multimap::merge(flat_map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(flat_set& source) - { this->tree_t::merge_equal(source.tree()); } - - //! @copydoc ::boost::container::flat_multiset::merge(flat_set&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! @copydoc ::boost::container::flat_set::erase(const_iterator) - iterator erase(const_iterator p); - - //! @copydoc ::boost::container::flat_set::erase(const key_type&) - size_type erase(const key_type& x); - - //! @copydoc ::boost::container::flat_set::erase(const_iterator,const_iterator) - iterator erase(const_iterator first, const_iterator last); - - //! @copydoc ::boost::container::flat_set::swap - void swap(flat_multiset& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - //! @copydoc ::boost::container::flat_set::clear - void clear() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::key_comp - key_compare key_comp() const; - - //! @copydoc ::boost::container::flat_set::value_comp - value_compare value_comp() const; - - //! @copydoc ::boost::container::flat_set::find(const key_type& ) - iterator find(const key_type& x); - - //! @copydoc ::boost::container::flat_set::find(const key_type& ) const - const_iterator find(const key_type& x) const; - - //! @copydoc ::boost::container::flat_set::nth(size_type) - iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::nth(size_type) const - const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::index_of(iterator) - size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const - size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::flat_set::count(const key_type& ) const - size_type count(const key_type& x) const; - - //! @copydoc ::boost::container::flat_set::contains(const key_type& ) const - bool contains(const key_type& x) const; - - //! @copydoc ::boost::container::flat_set::contains(const K& ) const - template - bool contains(const K& x) const; - - //! @copydoc ::boost::container::flat_set::lower_bound(const key_type& ) - iterator lower_bound(const key_type& x); - - //! @copydoc ::boost::container::flat_set::lower_bound(const key_type& ) const - const_iterator lower_bound(const key_type& x) const; - - //! @copydoc ::boost::container::flat_set::upper_bound(const key_type& ) - iterator upper_bound(const key_type& x); - - //! @copydoc ::boost::container::flat_set::upper_bound(const key_type& ) const - const_iterator upper_bound(const key_type& x) const; - - //! @copydoc ::boost::container::flat_set::equal_range(const key_type& ) const - std::pair equal_range(const key_type& x) const; - - //! @copydoc ::boost::container::flat_set::equal_range(const key_type& ) - std::pair equal_range(const key_type& x); - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const flat_multiset& x, const flat_multiset& y); - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const flat_multiset& x, const flat_multiset& y); - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const flat_multiset& x, const flat_multiset& y); - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const flat_multiset& x, const flat_multiset& y); - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<=(const flat_multiset& x, const flat_multiset& y); - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>=(const flat_multiset& x, const flat_multiset& y); - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - friend void swap(flat_multiset& x, flat_multiset& y) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - //! Effects: Extracts the internal sequence container. - //! - //! Complexity: Same as the move constructor of sequence_type, usually constant. - //! - //! Postcondition: this->empty() - //! - //! Throws: If secuence_type's move constructor throws - sequence_type extract_sequence(); - - #endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - - //! Effects: Discards the internally hold sequence container and adopts the - //! one passed externally using the move assignment. - //! - //! Complexity: Assuming O(1) move assignment, O(NlogN) with N = seq.size() - //! - //! Throws: If the comparison or the move constructor throws - BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq) - { this->tree_t::adopt_sequence_equal(boost::move(seq)); } - - //! Requires: seq shall be ordered according to this->compare() - //! - //! Effects: Discards the internally hold sequence container and adopts the - //! one passed externally using the move assignment. - //! - //! Complexity: Assuming O(1) move assignment, O(1) - //! - //! Throws: If the move assignment throws - BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq) - { this->tree_t::adopt_sequence_equal(ordered_range_t(), boost::move(seq)); } - - //! Effects: Returns a const view of the underlying sequence. - //! - //! Complexity: Constant - //! - //! Throws: Nothing - BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT - { return this->get_sequence_cref(); } -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -flat_multiset(InputIterator, InputIterator) -> - flat_multiset< it_based_value_type_t >; - - -template < typename InputIterator, typename AllocatorOrCompare> -flat_multiset(InputIterator, InputIterator, AllocatorOrCompare const&) -> - flat_multiset < it_based_value_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -flat_multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_multiset< it_based_value_type_t - , Compare - , Allocator>; - -template -flat_multiset(ordered_range_t, InputIterator, InputIterator) -> - flat_multiset< it_based_value_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> -flat_multiset(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> - flat_multiset < it_based_value_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - flat_multiset< it_based_value_type_t - , Compare - , Allocator>; - -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef ::boost::container::dtl::flat_tree, Compare, AllocatorOrContainer> tree; - static const bool value = ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -}} - -#include - -#endif // BOOST_CONTAINER_FLAT_SET_HPP diff --git a/inst/i/b/container/list.hpp b/inst/i/b/container/list.hpp deleted file mode 100644 index 475706cc0..000000000 --- a/inst/i/b/container/list.hpp +++ /dev/null @@ -1,1511 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (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) -// -// See http://www.boost.org/libs/container for documentation. -// -////////////////////////////////////////////////////////////////////////////// -#ifndef BOOST_CONTAINER_LIST_HPP -#define BOOST_CONTAINER_LIST_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include - -// container -#include -#include //new_allocator -#include -// container/detail -#include -#include -#include -#include -#include -#include -#include -#include -// move -#include -#include -#include -// move/detail -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -# include -#endif -#include -#include - -// intrusive -#include -#include -// other -#include -// std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -namespace boost { -namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -namespace dtl { - -template -struct list_hook -{ - typedef typename dtl::bi::make_list_base_hook - , dtl::bi::link_mode >::type type; -}; - -template -struct iiterator_node_value_type< base_node > > -{ - typedef T type; -}; - -template -struct intrusive_list_type -{ - typedef boost::container::allocator_traits allocator_traits_type; - typedef typename allocator_traits_type::value_type value_type; - typedef typename boost::intrusive::pointer_traits - ::template - rebind_pointer::type - void_pointer; - typedef base_node > node_type; - typedef typename dtl::bi::make_list - < node_type - , dtl::bi::base_hook::type> - , dtl::bi::constant_time_size - , dtl::bi::size_type - - >::type container_type; - typedef container_type type ; -}; - -} //namespace dtl { -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! A list is a doubly linked list. That is, it is a Sequence that supports both -//! forward and backward traversal, and (amortized) constant time insertion and -//! removal of elements at the beginning or the end, or in the middle. Lists have -//! the important property that insertion and splicing do not invalidate iterators -//! to list elements, and that even removal invalidates only the iterators that point -//! to the elements that are removed. The ordering of iterators may be changed -//! (that is, list::iterator might have a different predecessor or successor -//! after a list operation than it did before), but the iterators themselves will -//! not be invalidated or made to point to different elements unless that invalidation -//! or mutation is explicit. -//! -//! \tparam T The type of object that is stored in the list -//! \tparam Allocator The allocator used for all internal memory management, use void -//! for the default allocator -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template -#else -template -#endif -class list - : protected dtl::node_alloc_holder - < typename real_allocator::type - , typename dtl::intrusive_list_type::type>::type> -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef typename real_allocator::type ValueAllocator; - typedef typename - dtl::intrusive_list_type::type Icont; - typedef dtl::node_alloc_holder AllocHolder; - typedef typename AllocHolder::NodePtr NodePtr; - typedef typename AllocHolder::NodeAlloc NodeAlloc; - typedef typename AllocHolder::ValAlloc ValAlloc; - typedef typename AllocHolder::Node Node; - typedef dtl::allocator_node_destroyer Destroyer; - typedef typename AllocHolder::alloc_version alloc_version; - typedef boost::container::allocator_traits allocator_traits_type; - typedef boost::container::equal_to_value - equal_to_value_type; - - BOOST_COPYABLE_AND_MOVABLE(list) - - typedef dtl::iterator_from_iiterator iterator_impl; - typedef dtl::iterator_from_iiterator const_iterator_impl; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - - typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef ValueAllocator allocator_type; - typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; - - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructs a list. - //! - //! Throws: If allocator_type's default constructor throws. - //! - //! Complexity: Constant. - list() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) - : AllocHolder() - {} - - //! Effects: Constructs a list taking the allocator as parameter. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - explicit list(const allocator_type &a) BOOST_NOEXCEPT_OR_NOTHROW - : AllocHolder(a) - {} - - //! Effects: Constructs a list - //! and inserts n value-initialized value_types. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - explicit list(size_type n) - : AllocHolder(ValueAllocator()) - { this->resize(n); } - - //! Effects: Constructs a list that will use a copy of allocator a - //! and inserts n copies of value. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - list(size_type n, const allocator_type &a) - : AllocHolder(a) - { this->resize(n); } - - //! Effects: Constructs a list that will use a copy of allocator a - //! and inserts n copies of value. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - list(size_type n, const T& value, const ValueAllocator& a = ValueAllocator()) - : AllocHolder(a) - { this->insert(this->cbegin(), n, value); } - - //! Effects: Copy constructs a list. - //! - //! Postcondition: x == *this. - //! - //! Throws: If allocator_type's default constructor throws. - //! - //! Complexity: Linear to the elements x contains. - list(const list& x) - : AllocHolder(x) - { this->insert(this->cbegin(), x.begin(), x.end()); } - - //! Effects: Move constructor. Moves x's resources to *this. - //! - //! Throws: If allocator_type's copy constructor throws. - //! - //! Complexity: Constant. - list(BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW - : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x)) - {} - - //! Effects: Copy constructs a list using the specified allocator. - //! - //! Postcondition: x == *this. - //! - //! Throws: If allocator_type's default constructor or copy constructor throws. - //! - //! Complexity: Linear to the elements x contains. - list(const list& x, const allocator_type &a) - : AllocHolder(a) - { this->insert(this->cbegin(), x.begin(), x.end()); } - - //! Effects: Move constructor sing the specified allocator. - //! Moves x's resources to *this. - //! - //! Throws: If allocation or value_type's copy constructor throws. - //! - //! Complexity: Constant if a == x.get_allocator(), linear otherwise. - list(BOOST_RV_REF(list) x, const allocator_type &a) - : AllocHolder(a) - { - if(this->node_alloc() == x.node_alloc()){ - this->icont().swap(x.icont()); - } - else{ - this->insert(this->cbegin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end())); - } - } - - //! Effects: Constructs a list that will use a copy of allocator a - //! and inserts a copy of the range [first, last) in the list. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced InIt throws. - //! - //! Complexity: Linear to the range [first, last). - template - list(InpIt first, InpIt last, const ValueAllocator &a = ValueAllocator()) - : AllocHolder(a) - { this->insert(this->cbegin(), first, last); } - - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs a list that will use a copy of allocator a - //! and inserts a copy of the range [il.begin(), il.end()) in the list. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced - //! std::initializer_list iterator throws. - //! - //! Complexity: Linear to the range [il.begin(), il.end()). - list(std::initializer_list il, const ValueAllocator &a = ValueAllocator()) - : AllocHolder(a) - { this->insert(this->cbegin(), il.begin(), il.end()); } -#endif - - //! Effects: Destroys the list. All stored values are destroyed - //! and used memory is deallocated. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements. - BOOST_CONTAINER_FORCEINLINE ~list() BOOST_NOEXCEPT_OR_NOTHROW - {} //AllocHolder clears the list - - //! Effects: Makes *this contain the same elements as x. - //! - //! Postcondition: this->size() == x.size(). *this contains a copy - //! of each of x's elements. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to the number of elements in x. - list& operator=(BOOST_COPY_ASSIGN_REF(list) x) - { - if (BOOST_LIKELY(this != &x)) { - NodeAlloc &this_alloc = this->node_alloc(); - const NodeAlloc &x_alloc = x.node_alloc(); - dtl::bool_ flag; - if(flag && this_alloc != x_alloc){ - this->clear(); - } - this->AllocHolder::copy_assign_alloc(x); - this->assign(x.begin(), x.end()); - } - return *this; - } - - //! Effects: Move assignment. All x's values are transferred to *this. - //! - //! Postcondition: x.empty(). *this contains a the elements x had - //! before the function. - //! - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or value_type's move constructor throws) - //! - //! Complexity: Constant if allocator_traits_type:: - //! propagate_on_container_move_assignment is true or - //! this->get>allocator() == x.get_allocator(). Linear otherwise. - list& operator=(BOOST_RV_REF(list) x) - BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value - || allocator_traits_type::is_always_equal::value) - { - if (BOOST_LIKELY(this != &x)) { - NodeAlloc &this_alloc = this->node_alloc(); - NodeAlloc &x_alloc = x.node_alloc(); - const bool propagate_alloc = allocator_traits_type:: - propagate_on_container_move_assignment::value; - const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; - //Resources can be transferred if both allocators are - //going to be equal after this function (either propagated or already equal) - if(propagate_alloc || allocators_equal){ - //Destroy - this->clear(); - //Move allocator if needed - this->AllocHolder::move_assign_alloc(x); - //Obtain resources - this->icont() = boost::move(x.icont()); - } - //Else do a one by one move - else{ - this->assign( boost::make_move_iterator(x.begin()) - , boost::make_move_iterator(x.end())); - } - } - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Makes *this contain the same elements as il. - //! - //! Postcondition: this->size() == il.size(). *this contains a copy - //! of each of x's elements. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to the number of elements in x. - BOOST_CONTAINER_FORCEINLINE list& operator=(std::initializer_list il) - { - this->assign(il.begin(), il.end()); - return *this; - } -#endif - - //! Effects: Assigns the n copies of val to *this. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& val) - { - typedef constant_iterator cvalue_iterator; - return this->assign(cvalue_iterator(val, n), cvalue_iterator()); - } - - //! Effects: Assigns the range [first, last) to *this. - //! - //! Throws: If memory allocation throws or - //! T's constructor from dereferencing InpIt throws. - //! - //! Complexity: Linear to n. - template - void assign(InpIt first, InpIt last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::disable_if_convertible::type * = 0 - #endif - ) - { - iterator first1 = this->begin(); - const iterator last1 = this->end(); - for ( ; first1 != last1 && first != last; ++first1, ++first) - *first1 = *first; - if (first == last) - this->erase(first1, last1); - else{ - this->insert(last1, first, last); - } - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Assigns the range [il.begin(), il.end()) to *this. - //! - //! Throws: If memory allocation throws or - //! T's constructor from dereferencing std::initializer_list iterator throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list il) - { this->assign(il.begin(), il.end()); } -#endif - - //! Effects: Returns a copy of the internal allocator. - //! - //! Throws: If allocator's copy constructor throws. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return allocator_type(this->node_alloc()); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW - { return this->node_alloc(); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->node_alloc(); } - - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// - - //! Effects: Returns an iterator to the first element contained in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->icont().begin()); } - - //! Effects: Returns a const_iterator to the first element contained in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->cbegin(); } - - //! Effects: Returns an iterator to the end of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator end() BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->icont().end()); } - - //! Effects: Returns a const_iterator to the end of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->cend(); } - - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW - { return reverse_iterator(end()); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->crbegin(); } - - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW - { return reverse_iterator(begin()); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->crend(); } - - //! Effects: Returns a const_iterator to the first element contained in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_iterator(this->non_const_icont().begin()); } - - //! Effects: Returns a const_iterator to the end of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_iterator(this->non_const_icont().end()); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_reverse_iterator(this->cend()); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_reverse_iterator(this->cbegin()); } - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// - - //! Effects: Returns true if the list contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW - { return !this->size(); } - - //! Effects: Returns the number of the elements contained in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->icont().size(); } - - //! Effects: Returns the largest possible size of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return AllocHolder::max_size(); } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are value initialized. - //! - //! Throws: If memory allocation throws, or T's copy constructor throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - void resize(size_type new_size) - { - if(!priv_try_shrink(new_size)){ - typedef value_init_construct_iterator value_init_iterator; - this->insert(this->cend(), value_init_iterator(new_size - this->size()), value_init_iterator()); - } - } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are copy constructed from x. - //! - //! Throws: If memory allocation throws, or T's copy constructor throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - void resize(size_type new_size, const T& x) - { - if(!priv_try_shrink(new_size)){ - this->insert(this->cend(), new_size - this->size(), x); - } - } - - ////////////////////////////////////////////// - // - // element access - // - ////////////////////////////////////////////// - - //! Requires: !empty() - //! - //! Effects: Returns a reference to the first element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference front() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return *this->begin(); - } - - //! Requires: !empty() - //! - //! Effects: Returns a const reference to the first element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return *this->begin(); - } - - //! Requires: !empty() - //! - //! Effects: Returns a reference to the first element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference back() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return *(--this->end()); - } - - //! Requires: !empty() - //! - //! Effects: Returns a const reference to the first element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return *(--this->end()); - } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the end of the list. - //! - //! Returns: A reference to the created object. - //! - //! Throws: If memory allocation throws or - //! T's in-place constructor throws. - //! - //! Complexity: Constant - template - reference emplace_back(BOOST_FWD_REF(Args)... args) - { return *this->emplace(this->cend(), boost::forward(args)...); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the beginning of the list. - //! - //! Returns: A reference to the created object. - //! - //! Throws: If memory allocation throws or - //! T's in-place constructor throws. - //! - //! Complexity: Constant - template - reference emplace_front(BOOST_FWD_REF(Args)... args) - { return *this->emplace(this->cbegin(), boost::forward(args)...); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... before p. - //! - //! Throws: If memory allocation throws or - //! T's in-place constructor throws. - //! - //! Complexity: Constant - template - iterator emplace(const_iterator position, BOOST_FWD_REF(Args)... args) - { - BOOST_ASSERT((priv_is_linked)(position)); - NodePtr pnode(AllocHolder::create_node(boost::forward(args)...)); - return iterator(this->icont().insert(position.get(), *pnode)); - } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_LIST_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - reference emplace_back(BOOST_MOVE_UREF##N)\ - { return *this->emplace(this->cend() BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - reference emplace_front(BOOST_MOVE_UREF##N)\ - { return *this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - iterator emplace(const_iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - BOOST_ASSERT(position == this->cend() || (--(++position) == position) );\ - NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\ - return iterator(this->icont().insert(position.get(), *pnode));\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE) - #undef BOOST_CONTAINER_LIST_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x at the beginning of the list. - //! - //! Throws: If memory allocation throws or - //! T's copy constructor throws. - //! - //! Complexity: Amortized constant time. - void push_front(const T &x); - - //! Effects: Constructs a new element in the beginning of the list - //! and moves the resources of x to this new element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Amortized constant time. - void push_front(T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x at the end of the list. - //! - //! Throws: If memory allocation throws or - //! T's copy constructor throws. - //! - //! Complexity: Amortized constant time. - void push_back(const T &x); - - //! Effects: Constructs a new element in the end of the list - //! and moves the resources of x to this new element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Amortized constant time. - void push_back(T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of x before p. - //! - //! Returns: an iterator to the inserted element. - //! - //! Throws: If memory allocation throws or x's copy constructor throws. - //! - //! Complexity: Amortized constant time. - iterator insert(const_iterator p, const T &x); - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a new element before p with x's resources. - //! - //! Returns: an iterator to the inserted element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Amortized constant time. - iterator insert(const_iterator p, T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) - #endif - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Inserts n copies of x before p. - //! - //! Returns: an iterator to the first inserted element or p if n is 0. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - iterator insert(const_iterator position, size_type n, const T& x) - { - //range check is done by insert - typedef constant_iterator cvalue_iterator; - return this->insert(position, cvalue_iterator(x, n), cvalue_iterator()); - } - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of the [first, last) range before p. - //! - //! Returns: an iterator to the first inserted element or p if first == last. - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced InpIt throws. - //! - //! Complexity: Linear to distance [first, last). - template - iterator insert(const_iterator p, InpIt first, InpIt last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::enable_if_c - < !dtl::is_convertible::value - && (dtl::is_input_iterator::value - || dtl::is_same::value - ) - >::type * = 0 - #endif - ) - { - BOOST_ASSERT((priv_is_linked)(p)); - const typename Icont::iterator ipos(p.get()); - iterator ret_it(ipos); - if(first != last){ - ret_it = iterator(this->icont().insert(ipos, *this->create_node_from_it(first))); - ++first; - } - for (; first != last; ++first){ - this->icont().insert(ipos, *this->create_node_from_it(first)); - } - return ret_it; - } - - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - iterator insert(const_iterator position, FwdIt first, FwdIt last - , typename dtl::enable_if_c - < !dtl::is_convertible::value - && !(dtl::is_input_iterator::value - || dtl::is_same::value - ) - >::type * = 0 - ) - { - BOOST_ASSERT((priv_is_linked)(position)); - //Optimized allocation and construction - insertion_functor func(this->icont(), position.get()); - iterator before_p(position.get()); - --before_p; - this->allocate_many_and_construct(first, boost::container::iterator_udistance(first, last), func); - return ++before_p; - } - #endif - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of the [il.begin(), il.end()) range before p. - //! - //! Returns: an iterator to the first inserted element or p if if.begin() == il.end(). - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced std::initializer_list iterator throws. - //! - //! Complexity: Linear to distance [il.begin(), il.end()). - iterator insert(const_iterator p, std::initializer_list il) - { - //position range check is done by insert() - return insert(p, il.begin(), il.end()); - } -#endif - - //! Effects: Removes the first element from the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Amortized constant time. - void pop_front() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - this->erase(this->cbegin()); - } - - //! Effects: Removes the last element from the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Amortized constant time. - void pop_back() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - const_iterator tmp = this->cend(); - this->erase(--tmp); - } - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Erases the element at p. - //! - //! Throws: Nothing. - //! - //! Complexity: Amortized constant time. - iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(p != this->cend() && (priv_is_linked)(p)); - return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); - } - - //! Requires: first and last must be valid iterator to elements in *this. - //! - //! Effects: Erases the elements pointed by [first, last). - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the distance between first and last. - iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW - { - 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())); - } - - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(list& x) - BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value - || allocator_traits_type::is_always_equal::value) - { - BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value || - allocator_traits_type::is_always_equal::value || - this->get_stored_allocator() == x.get_stored_allocator()); - AllocHolder::swap(x); - } - - //! Effects: Erases all the elements of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements in the list. - void clear() BOOST_NOEXCEPT_OR_NOTHROW - { AllocHolder::clear(alloc_version()); } - - ////////////////////////////////////////////// - // - // slist operations - // - ////////////////////////////////////////////// - - //! Requires: p must point to an element contained - //! by the list. x != *this. this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers all the elements of list x to this list, before the - //! the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of - //! this list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT((priv_is_linked)(p)); - BOOST_ASSERT(this != &x); - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().splice(p.get(), x.icont()); - } - - //! Requires: p must point to an element contained - //! by the list. x != *this. this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers all the elements of list x to this list, before the - //! the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of - //! this list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW - { - //Checks done in splice - this->splice(p, static_cast(x)); - } - - //! Requires: p must point to an element contained - //! by this list. i must point to an element contained in list x. - //! this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers the value pointed by i, from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! If p == i or p == ++i, this function is a null operation. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list &x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT((priv_is_linked)(p)); - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().splice(p.get(), x.icont(), i.get()); - } - - //! Requires: p must point to an element contained - //! by this list. i must point to an element contained in list x. - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the value pointed by i, from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! If p == i or p == ++i, this function is a null operation. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this != &x); - //Additional checks done in splice() - this->splice(p, static_cast(x), i); - } - - //! Requires: p must point to an element contained - //! by this list. first and last must point to elements contained in list x. - //! this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers the range pointed by first and last from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Linear to the number of elements transferred. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT((priv_is_linked)(p)); - BOOST_ASSERT(first == last || (first != x.cend() && x.priv_is_linked(first))); - BOOST_ASSERT(first == last || x.priv_is_linked(last)); - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().splice(p.get(), x.icont(), first.get(), last.get()); - } - - //! Requires: p must point to an element contained - //! by this list. first and last must point to elements contained in list x. - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the range pointed by first and last from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Linear to the number of elements transferred. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this != &x); - //Additional checks done in splice() - this->splice(p, static_cast(x), first, last); - } - - //! Requires: p must point to an element contained - //! by this list. first and last must point to elements contained in list x. - //! n == distance(first, last). this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers the range pointed by first and last from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - //! - //! Note: Non-standard extension - void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n); - } - - //! Requires: p must point to an element contained - //! by this list. first and last must point to elements contained in list x. - //! n == distance(first, last). this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers the range pointed by first and last from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - //! - //! Note: Non-standard extension - void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice(p, static_cast(x), first, last, n); } - - //! Effects: Removes all the elements that compare equal to value. - //! - //! Throws: If comparison throws. - //! - //! Complexity: Linear time. It performs exactly size() comparisons for equality. - //! - //! Note: The relative order of elements that are not removed is unchanged, - //! and iterators to elements that are not removed remain valid. - void remove(const T& value) - { this->remove_if(equal_to_value_type(value)); } - - //! Effects: Removes all the elements for which a specified - //! predicate is satisfied. - //! - //! Throws: If pred throws. - //! - //! Complexity: Linear time. It performs exactly size() calls to the predicate. - //! - //! Note: The relative order of elements that are not removed is unchanged, - //! and iterators to elements that are not removed remain valid. - template - void remove_if(Pred pred) - { - typedef value_to_node_compare value_to_node_compare_type; - this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc())); - } - - //! Effects: Removes adjacent duplicate elements or adjacent - //! elements that are equal from the list. - //! - //! Throws: If comparison throws. - //! - //! Complexity: Linear time (size()-1 comparisons equality comparisons). - //! - //! Note: The relative order of elements that are not removed is unchanged, - //! and iterators to elements that are not removed remain valid. - void unique() - { this->unique(value_equal_t()); } - - //! Effects: Removes adjacent duplicate elements or adjacent - //! elements that satisfy some binary predicate from the list. - //! - //! Throws: If pred throws. - //! - //! Complexity: Linear time (size()-1 comparisons calls to pred()). - //! - //! Note: The relative order of elements that are not removed is unchanged, - //! and iterators to elements that are not removed remain valid. - template - void unique(BinaryPredicate binary_pred) - { - typedef value_to_node_compare value_to_node_compare_type; - this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc())); - } - - //! Requires: The lists x and *this must be distinct. - //! - //! Effects: This function removes all of x's elements and inserts them - //! in order into *this according to std::less. The merge is stable; - //! that is, if an element from *this is equivalent to one from x, then the element - //! from *this will precede the one from x. - //! - //! Throws: If comparison throws. - //! - //! Complexity: This function is linear time: it performs at most - //! size() + x.size() - 1 comparisons. - void merge(list &x) - { this->merge(x, value_less_t()); } - - //! Requires: The lists x and *this must be distinct. - //! - //! Effects: This function removes all of x's elements and inserts them - //! in order into *this according to std::less. The merge is stable; - //! that is, if an element from *this is equivalent to one from x, then the element - //! from *this will precede the one from x. - //! - //! Throws: If comparison throws. - //! - //! Complexity: This function is linear time: it performs at most - //! size() + x.size() - 1 comparisons. - void merge(BOOST_RV_REF(list) x) - { this->merge(static_cast(x)); } - - //! Requires: p must be a comparison function that induces a strict weak - //! ordering and both *this and x must be sorted according to that ordering - //! The lists x and *this must be distinct. - //! - //! Effects: This function removes all of x's elements and inserts them - //! in order into *this. The merge is stable; that is, if an element from *this is - //! equivalent to one from x, then the element from *this will precede the one from x. - //! - //! Throws: If comp throws. - //! - //! Complexity: This function is linear time: it performs at most - //! size() + x.size() - 1 comparisons. - //! - //! Note: Iterators and references to *this are not invalidated. - template - void merge(list &x, const StrictWeakOrdering &comp) - { - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - typedef value_to_node_compare value_to_node_compare_type; - this->icont().merge(x.icont(), value_to_node_compare_type(comp)); - } - - //! Requires: p must be a comparison function that induces a strict weak - //! ordering and both *this and x must be sorted according to that ordering - //! The lists x and *this must be distinct. - //! - //! Effects: This function removes all of x's elements and inserts them - //! in order into *this. The merge is stable; that is, if an element from *this is - //! equivalent to one from x, then the element from *this will precede the one from x. - //! - //! Throws: If comp throws. - //! - //! Complexity: This function is linear time: it performs at most - //! size() + x.size() - 1 comparisons. - //! - //! Note: Iterators and references to *this are not invalidated. - template - void merge(BOOST_RV_REF(list) x, StrictWeakOrdering comp) - { this->merge(static_cast(x), comp); } - - //! Effects: This function sorts the list *this according to std::less. - //! The sort is stable, that is, the relative order of equivalent elements is preserved. - //! - //! Throws: If comparison throws. - //! - //! Notes: Iterators and references are not invalidated. - //! - //! Complexity: The number of comparisons is approximately N log N, where N - //! is the list's size. - void sort() - { this->sort(value_less_t()); } - - //! Effects: This function sorts the list *this according to std::less. - //! The sort is stable, that is, the relative order of equivalent elements is preserved. - //! - //! Throws: If comp throws. - //! - //! Notes: Iterators and references are not invalidated. - //! - //! Complexity: The number of comparisons is approximately N log N, where N - //! is the list's size. - template - void sort(StrictWeakOrdering comp) - { - // nothing if the list has length 0 or 1. - if (this->size() < 2) - return; - typedef value_to_node_compare value_to_node_compare_type; - this->icont().sort(value_to_node_compare_type(comp)); - } - - //! Effects: Reverses the order of elements in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: This function is linear time. - //! - //! Note: Iterators and references are not invalidated - void reverse() BOOST_NOEXCEPT_OR_NOTHROW - { this->icont().reverse(); } - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const list& x, const list& y) - { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const list& x, const list& y) - { return !(x == y); } - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const list& x, const list& y) - { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const list& x, const list& y) - { return y < x; } - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const list& x, const list& y) - { return !(y < x); } - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const list& x, const list& y) - { return !(x < y); } - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE friend void swap(list& x, list& y) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) - { x.swap(y); } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - - static bool priv_is_linked(const_iterator const position) - { - const_iterator cur(position); - //This list is circular including end nodes - return (--(++cur)) == position && (++(--cur)) == position; - } - - bool priv_try_shrink(size_type new_size) - { - const size_type len = this->size(); - if(len > new_size){ - const const_iterator iend = this->cend(); - size_type to_erase = len - new_size; - const_iterator ifirst; - if(to_erase < len/2u){ - ifirst = iend; - while(to_erase--){ - --ifirst; - } - } - else{ - ifirst = this->cbegin(); - size_type to_skip = len - to_erase; - while(to_skip--){ - ++ifirst; - } - } - this->erase(ifirst, iend); - return true; - } - else{ - return false; - } - } - - iterator priv_insert(const_iterator p, const T &x) - { - BOOST_ASSERT((priv_is_linked)(p)); - NodePtr tmp = AllocHolder::create_node(x); - return iterator(this->icont().insert(p.get(), *tmp)); - } - - iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x) - { - BOOST_ASSERT((priv_is_linked)(p)); - NodePtr tmp = AllocHolder::create_node(boost::move(x)); - return iterator(this->icont().insert(p.get(), *tmp)); - } - - template - void priv_push_back(BOOST_FWD_REF(U) x) - { this->icont().push_back(*this->create_node(::boost::forward(x))); } - - template - void priv_push_front(BOOST_FWD_REF(U) x) - { this->icont().push_front(*this->create_node(::boost::forward(x))); } - - class insertion_functor; - friend class insertion_functor; - - class insertion_functor - { - Icont &icont_; - typedef typename Icont::const_iterator iconst_iterator; - const iconst_iterator pos_; - - public: - insertion_functor(Icont &icont, typename Icont::const_iterator pos) - : icont_(icont), pos_(pos) - {} - - void operator()(Node &n) - { - this->icont_.insert(pos_, n); - } - }; - - typedef value_less value_less_t; - typedef value_equal value_equal_t; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD -template -list(InputIterator, InputIterator) -> - list::value_type>; - -template -list(InputIterator, InputIterator, ValueAllocator const&) -> - list::value_type, ValueAllocator>; -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef typename boost::container::list::allocator_type allocator_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -}} - -#include - -#endif // BOOST_CONTAINER_LIST_HPP diff --git a/inst/i/b/container/map.hpp b/inst/i/b/container/map.hpp deleted file mode 100644 index 9aa15e500..000000000 --- a/inst/i/b/container/map.hpp +++ /dev/null @@ -1,2315 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2005-2013. 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_MAP_HPP -#define BOOST_CONTAINER_MAP_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include - -// container -#include -#include //new_allocator -#include -// container/detail -#include -#include -#include -#include -#include -#include - -// move -#include -#include -// move/detail -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -#include -// intrusive/detail -#include //pair -#include //less, equal -// other -#include -// std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -namespace boost { -namespace container { - -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! A map is a kind of associative container that supports unique keys (contains at -//! most one of each key value) and provides for fast retrieval of values of another -//! type T based on the keys. The map class supports bidirectional iterators. -//! -//! A map satisfies all of the requirements of a container and of a reversible -//! container and of an associative container. The value_type stored -//! by this container is the value_type is std::pair. -//! -//! \tparam Key is the key_type of the map -//! \tparam T is the mapped_type -//! \tparam Compare is the ordering function for Keys (e.g. std::less). -//! \tparam Allocator is the allocator to allocate the value_types -//! (e.g. allocator< std::pair > ). -//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options. -template < class Key, class T, class Compare = std::less - , class Allocator = void, class Options = tree_assoc_defaults > -#else -template -#endif -class map - ///@cond - : public dtl::tree - < std::pair - , int - , Compare, Allocator, Options> - ///@endcond -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(map) - - typedef int select_1st_t; - typedef std::pair value_type_impl; - typedef dtl::tree - base_t; - typedef dtl::pair movable_value_type_impl; - typedef typename base_t::value_compare value_compare_impl; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - - typedef Key key_type; - typedef T mapped_type; - typedef typename base_t::allocator_type allocator_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename boost::container::allocator_traits::value_type value_type; - typedef typename boost::container::allocator_traits::pointer pointer; - typedef typename boost::container::allocator_traits::const_pointer const_pointer; - typedef typename boost::container::allocator_traits::reference reference; - typedef typename boost::container::allocator_traits::const_reference const_reference; - typedef typename boost::container::allocator_traits::size_type size_type; - typedef typename boost::container::allocator_traits::difference_type difference_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; - typedef Compare key_compare; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - 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 std::pair nonconst_value_type; - typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; - typedef BOOST_CONTAINER_IMPDEF(node_handle< - typename base_t::stored_allocator_type - BOOST_MOVE_I pair_key_mapped_of_value - >) node_type; - typedef BOOST_CONTAINER_IMPDEF - (insert_return_type_base) insert_return_type; - - //allocator_type::value_type type must be std::pair - BOOST_STATIC_ASSERT((dtl::is_same >::value)); - - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructs an empty map. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE - map() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value && - dtl::is_nothrow_default_constructible::value) - : base_t() - {} - - //! Effects: Constructs an empty map using the specified comparison object - //! and allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE map(const Compare& comp, const allocator_type& a) - : base_t(comp, a) - {} - - //! Effects: Constructs an empty map using the specified comparison object. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit map(const Compare& comp) - : base_t(comp) - {} - - //! Effects: Constructs an empty map using the specified allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit map(const allocator_type& a) - : base_t(a) - {} - - //! Effects: Constructs an empty map and - //! inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last) - : base_t(true, first, last) - {} - - //! Effects: Constructs an empty map using the specified - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const allocator_type& a) - : base_t(true, first, last, Compare(), a) - {} - - //! Effects: Constructs an empty map using the specified comparison object and - //! inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const Compare& comp) - : base_t(true, first, last, comp) - {} - - //! Effects: Constructs an empty map using the specified comparison object and - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : base_t(true, first, last, comp, a) - {} - - //! Effects: Constructs an empty map and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last) - : base_t(ordered_range, first, last) - {} - - //! Effects: Constructs an empty map using the specified comparison object and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp) - : base_t(ordered_range, first, last, comp) - {} - - //! Effects: Constructs an empty map using the specified comparison object and - //! allocator, and inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last - , const Compare& comp, const allocator_type& a) - : base_t(ordered_range, first, last, comp, a) - {} - - //! Effects: Constructs an empty map using the specified allocator object and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) - : base_t(ordered_range, first, last, Compare(), a) - {} - - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs an empty map and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted according - //! to the predicate and otherwise N logN, where N is il.first() - il.end(). - BOOST_CONTAINER_FORCEINLINE map(std::initializer_list il) - : base_t(true, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty map using the specified comparison object and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is il.first() - il.end(). - BOOST_CONTAINER_FORCEINLINE map(std::initializer_list il, const Compare& comp) - : base_t(true, il.begin(), il.end(), comp) - {} - - //! Effects: Constructs an empty map using the specified - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is il.first() - il.end(). - BOOST_CONTAINER_FORCEINLINE map(std::initializer_list il, const allocator_type& a) - : base_t(true, il.begin(), il.end(), Compare(), a) - {} - - //! Effects: Constructs an empty map using the specified comparison object and - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is il.first() - il.end(). - BOOST_CONTAINER_FORCEINLINE map(std::initializer_list il, const Compare& comp, const allocator_type& a) - : base_t(true, il.begin(), il.end(), comp, a) - {} - - //! Effects: Constructs an empty map 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, std::initializer_list il) - : base_t(ordered_range, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty map using the specified comparison object, - //! 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, std::initializer_list il, const Compare& comp) - : base_t(ordered_range, il.begin(), il.end(), comp) - {} - - //! Effects: Constructs an empty map 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, std::initializer_list il - , const Compare& comp, const allocator_type& a) - : base_t(ordered_range, il.begin(), il.end(), comp, a) - {} - -#endif - - //! Effects: Copy constructs a map. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE map(const map& x) - : base_t(static_cast(x)) - {} - - //! Effects: Move constructs a map. Constructs *this using x's resources. - //! - //! Complexity: Constant. - //! - //! Postcondition: x is emptied. - BOOST_CONTAINER_FORCEINLINE map(BOOST_RV_REF(map) x) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : base_t(BOOST_MOVE_BASE(base_t, x)) - {} - - //! Effects: Copy constructs a map using the specified allocator. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE map(const map& x, const allocator_type &a) - : base_t(static_cast(x), a) - {} - - //! Effects: Move constructs a map using the specified allocator. - //! Constructs *this using x's resources. - //! - //! Complexity: Constant if x == x.get_allocator(), linear otherwise. - //! - //! Postcondition: x is emptied. - BOOST_CONTAINER_FORCEINLINE map(BOOST_RV_REF(map) x, const allocator_type &a) - : base_t(BOOST_MOVE_BASE(base_t, x), a) - {} - - //! Effects: Makes *this a copy of x. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE map& operator=(BOOST_COPY_ASSIGN_REF(map) x) - { return static_cast(this->base_t::operator=(static_cast(x))); } - - //! Effects: this->swap(x.get()). - //! - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or value_type's move constructor throws) - //! - //! Complexity: Constant if allocator_traits_type:: - //! propagate_on_container_move_assignment is true or - //! this->get>allocator() == x.get_allocator(). Linear otherwise. - BOOST_CONTAINER_FORCEINLINE map& operator=(BOOST_RV_REF(map) x) - BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value || - allocator_traits_type::is_always_equal::value) && - boost::container::dtl::is_nothrow_move_assignable::value) - { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Assign content of il to *this. - //! - BOOST_CONTAINER_FORCEINLINE map& operator=(std::initializer_list il) - { - this->clear(); - insert(il.begin(), il.end()); - return *this; - } -#endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Returns a copy of the allocator that - //! was passed to the object's constructor. - //! - //! Complexity: Constant. - allocator_type get_allocator() const; - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns an iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns an iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator end() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns true if the container contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns the number of the elements contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns the largest possible size of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW; - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: If there is no key equivalent to x in the map, inserts - //! value_type(x, T()) into the map. - //! - //! Returns: A reference to the mapped_type corresponding to x in *this. - //! - //! Complexity: Logarithmic. - mapped_type& operator[](const key_type &k); - - //! Effects: If there is no key equivalent to x in the map, inserts - //! value_type(boost::move(x), T()) into the map (the key is move-constructed) - //! - //! Returns: A reference to the mapped_type corresponding to x in *this. - //! - //! 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 - BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](const key_type &k) { return this->priv_subscript(k); } - BOOST_CONTAINER_FORCEINLINE 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) - #endif - - //! Effects: If a key equivalent to k already exists in the container, assigns forward(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(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 - BOOST_CONTAINER_FORCEINLINE std::pair insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj) - { return this->base_t::insert_or_assign(const_iterator(), k, ::boost::forward(obj)); } - - //! Effects: If a key equivalent to k already exists in the container, assigns forward(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 - BOOST_CONTAINER_FORCEINLINE std::pair insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj) - { return this->base_t::insert_or_assign(const_iterator(), ::boost::move(k), ::boost::forward(obj)); } - - //! Effects: If a key equivalent to k already exists in the container, assigns forward(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(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 - BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj) - { return this->base_t::insert_or_assign(hint, k, ::boost::forward(obj)).first; } - - //! Effects: If a key equivalent to k already exists in the container, assigns forward(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 - BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj) - { return this->base_t::insert_or_assign(hint, ::boost::move(k), ::boost::forward(obj)).first; } - - //! Returns: A reference to the element whose key is equivalent to x. - //! Throws: An exception object of type out_of_range if no such element is present. - //! Complexity: logarithmic. - T& at(const key_type& k) - { - iterator i = this->find(k); - if(i == this->end()){ - throw_out_of_range("map::at key not found"); - } - return i->second; - } - - //! Returns: A reference to the element whose key is equivalent to x. - //! Throws: An exception object of type out_of_range if no such element is present. - //! Complexity: logarithmic. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD const T& at(const key_type& k) const - { - const_iterator i = this->find(k); - if(i == this->end()){ - throw_out_of_range("map::at key not found"); - } - return i->second; - } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// - - //! Effects: Inserts x if and only if there is no element in the container - //! with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_FORCEINLINE std::pair insert(const value_type& x) - { return this->base_t::insert_unique_convertible(x); } - - //! Effects: Move constructs a new value from x if and only if there is - //! no element in the container with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_FORCEINLINE std::pair insert(BOOST_RV_REF(value_type) x) - { return this->base_t::insert_unique_convertible(boost::move(x)); } - - //! Effects: Inserts a new value_type created from the pair if and only if - //! there is no element in the container with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST - ( std::pair - , typename dtl::enable_if_c< - dtl::is_convertible::value || - dtl::is_convertible::value - BOOST_MOVE_I std::pair >::type) - insert(BOOST_FWD_REF(Pair) x) - { return this->base_t::emplace_unique(boost::forward(x)); } - - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x) - { return this->base_t::insert_unique_hint_convertible(p, x); } - - //! Effects: Inserts a copy of x in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) - { return this->base_t::insert_unique_hint_convertible(p, boost::move(x)); } - - //! Effects: Inserts a copy of x in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST - ( iterator - , typename dtl::enable_if_c< - dtl::is_convertible::value || - dtl::is_convertible::value - BOOST_MOVE_I iterator >::type) - insert(const_iterator p, BOOST_FWD_REF(Pair) x) - { return this->base_t::emplace_hint_unique(p, boost::forward(x)); } - - -/* - //! Effects: Move constructs a new value from x if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x) - { return this->try_emplace(p, boost::move(x.first), boost::move(x.second)); } - - //! Effects: Move constructs a new value from x if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x) - { return this->try_emplace(p, boost::move(x.first), boost::move(x.second)); } - - //! Effects: Inserts a copy of x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const nonconst_value_type& x) - { return this->try_emplace(p, x.first, x.second); } - - -*/ - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - template - BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->base_t::insert_unique_range(first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: inserts each element from the range [il.begin(), il.end()) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: At most N log(size()+N) (N is the distance from il.begin() to il.end()) - BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list il) - { this->base_t::insert_unique_range(il.begin(), il.end()); } -#endif - - //! Requires: nh is empty or this->get_allocator() == nh.get_allocator(). - //! - //! Effects: If nh is empty, has no effect. Otherwise, inserts the element owned - //! by nh if and only if there is no element in the container with a key equivalent to nh.key(). - //! - //! Returns: If nh is empty, insert_return_type.inserted is false, insert_return_type.position - //! is end(), and insert_return_type.node is empty. Otherwise if the insertion took place, - //! insert_return_type.inserted is true, insert_return_type.position points to the inserted element, - //! and insert_return_type.node is empty; if the insertion failed, insert_return_type.inserted is - //! false, insert_return_type.node has the previous value of nh, and insert_return_type.position - //! points to an element with a key equivalent to nh.key(). - //! - //! Complexity: Logarithmic - insert_return_type insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh) - { - typename base_t::node_type n(boost::move(nh)); - typename base_t::insert_return_type base_ret(this->base_t::insert_unique_node(boost::move(n))); - return insert_return_type (base_ret.inserted, base_ret.position, boost::move(base_ret.node)); - } - - //! Effects: Same as `insert(node_type && nh)` but the element is inserted as close as possible - //! to the position just prior to "hint". - //! - //! Complexity: logarithmic in general, but amortized constant if the element is inserted - //! right before "hint". - insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh) - { - typename base_t::node_type n(boost::move(nh)); - typename base_t::insert_return_type base_ret(this->base_t::insert_unique_node(hint, boost::move(n))); - return insert_return_type (base_ret.inserted, base_ret.position, boost::move(base_ret.node)); - } - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object x of type T constructed with - //! std::forward(args)... in the container if and only if there is - //! no element in the container with an equivalent key. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE std::pair emplace(BOOST_FWD_REF(Args)... args) - { return this->base_t::emplace_unique(boost::forward(args)...); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the container if and only if there is - //! no element in the container with an equivalent key. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args) - { return this->base_t::emplace_hint_unique(p, boost::forward(args)...); } - - //! Requires: value_type shall be EmplaceConstructible into map from piecewise_construct, - //! forward_as_tuple(k), forward_as_tuple(forward(args)...). - //! - //! Effects: 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)...). - //! - //! Returns: 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. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_FORCEINLINE std::pair try_emplace(const key_type& k, BOOST_FWD_REF(Args)... args) - { return this->base_t::try_emplace(const_iterator(), k, boost::forward(args)...); } - - //! Requires: value_type shall be EmplaceConstructible into map from piecewise_construct, - //! forward_as_tuple(k), forward_as_tuple(forward(args)...). - //! - //! Effects: 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)...). - //! - //! Returns: The returned iterator points to the map element whose key is equivalent to k. - //! - //! Complexity: Logarithmic in general, but amortized constant if value - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k, BOOST_FWD_REF(Args)... args) - { return this->base_t::try_emplace(hint, k, boost::forward(args)...).first; } - - //! Requires: value_type shall be EmplaceConstructible into map from piecewise_construct, - //! forward_as_tuple(move(k)), forward_as_tuple(forward(args)...). - //! - //! Effects: 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)...). - //! - //! Returns: 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. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_FORCEINLINE std::pair try_emplace(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args) - { return this->base_t::try_emplace(const_iterator(), boost::move(k), boost::forward(args)...); } - - //! Requires: value_type shall be EmplaceConstructible into map from piecewise_construct, - //! forward_as_tuple(move(k)), forward_as_tuple(forward(args)...). - //! - //! Effects: 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)...). - //! - //! Returns: The returned iterator points to the map element whose key is equivalent to k. - //! - //! Complexity: Logarithmic in general, but amortized constant if value - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args) - { return this->base_t::try_emplace(hint, boost::move(k), boost::forward(args)...).first; } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE std::pair emplace(BOOST_MOVE_UREF##N)\ - { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->base_t::emplace_hint_unique(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 try_emplace(const key_type& k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->base_t::try_emplace(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 this->base_t::try_emplace(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 try_emplace(BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->base_t::try_emplace(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 this->base_t::try_emplace(hint, boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first; }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE) - #undef BOOST_CONTAINER_MAP_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - //! Effects: If present, erases the element in the container with key equivalent to x. - //! - //! Returns: Returns the number of erased elements (0/1). - //! - //! Complexity: log(size()) + count(k) - BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x) - { return this->base_t::erase_unique(x); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Erases the element pointed to by p. - //! - //! Returns: Returns an iterator pointing to the element immediately - //! following q prior to the element being erased. If no such element exists, - //! returns end(). - //! - //! Complexity: Amortized constant time - iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Erases all the elements in the range [first, last). - //! - //! Returns: Returns last. - //! - //! Complexity: log(size())+N where N is the distance from first to last. - iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW; - - #else - using base_t::erase; - #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Removes the first element in the container with key equivalent to k. - //! - //! Returns: A node_type owning the element if found, otherwise an empty node_type. - //! - //! Complexity: log(size()). - node_type extract(const key_type& k) - { - typename base_t::node_type base_nh(this->base_t::extract(k)); - node_type nh(boost::move(base_nh)); - return BOOST_MOVE_RET(node_type, nh); - } - - //! Effects: Removes the element pointed to by "position". - //! - //! Returns: A node_type owning the element, otherwise an empty node_type. - //! - //! Complexity: Amortized constant. - node_type extract(const_iterator position) - { - typename base_t::node_type base_nh(this->base_t::extract(position)); - node_type nh(boost::move(base_nh)); - return BOOST_MOVE_RET(node_type, nh); - } - - //! Requires: this->get_allocator() == source.get_allocator(). - //! - //! Effects: 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. - //! - //! Postcondition: 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. - //! - //! Throws: Nothing unless the comparison object throws. - //! - //! Complexity: N log(size() + N) (N has the value source.size()) - template - BOOST_CONTAINER_FORCEINLINE void merge(map& source) - { - typedef dtl::tree - base2_t; - this->merge_unique(static_cast(source)); - } - - //! @copydoc ::boost::container::map::merge(map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG map BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! @copydoc ::boost::container::map::merge(map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(multimap& source) - { - typedef dtl::tree - base2_t; - this->base_t::merge_unique(static_cast(source)); - } - - //! @copydoc ::boost::container::map::merge(map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multimap BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(map& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - //! Effects: erase(begin(),end()). - //! - //! Postcondition: size() == 0. - //! - //! Complexity: linear in size(). - void clear() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const; - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const; - - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - iterator find(const key_type& x); - - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - const_iterator find(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - iterator find(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - const_iterator find(const K& x) const; - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type count(const key_type& x) const - { return static_cast(this->find(x) != this->cend()); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type count(const K& x) const - { return static_cast(this->find(x) != this->cend()); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - bool contains(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - template - bool contains(const K& x) const; - - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator lower_bound(const key_type& x); - - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator lower_bound(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - iterator lower_bound(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - const_iterator lower_bound(const K& x) const; - - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator upper_bound(const key_type& x); - - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator upper_bound(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - iterator upper_bound(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - const_iterator upper_bound(const K& x) const; - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - std::pair equal_range(const key_type& x); - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - std::pair equal_range(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - std::pair equal_range(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - std::pair equal_range(const K& x) const; - - //! Effects: Rebalances the tree. It's a no-op for Red-Black and AVL trees. - //! - //! Complexity: Linear - void rebalance(); - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const map& x, const map& y); - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const map& x, const map& y); - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const map& x, const map& y); - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const map& x, const map& y); - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<=(const map& x, const map& y); - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>=(const map& x, const map& y); - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - friend void swap(map& x, map& y) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - template - BOOST_CONTAINER_FORCEINLINE mapped_type& priv_subscript(BOOST_FWD_REF(KeyConvertible) k) - { - return this->try_emplace(boost::forward(k)).first->second; - } - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -map(InputIterator, InputIterator) -> - map< it_based_non_const_first_type_t - , it_based_second_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> - map(InputIterator, InputIterator, AllocatorOrCompare const&) -> - map< it_based_non_const_first_type_t - , it_based_second_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator, it_based_second_type_t>> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -map(InputIterator, InputIterator, Compare const&, Allocator const&) -> - map< it_based_non_const_first_type_t - , it_based_second_type_t - , Compare - , Allocator>; - -template -map(ordered_unique_range_t, InputIterator, InputIterator) -> - map< it_based_non_const_first_type_t - , it_based_second_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> -map(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> - map< it_based_non_const_first_type_t - , it_based_second_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator, it_based_second_type_t>> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - map< it_based_non_const_first_type_t - , it_based_second_type_t - , Compare - , Allocator>; - -#endif - - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef ::boost::container::dtl::tree, int, Compare, Allocator, Options> tree; - static const bool value = ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! A multimap is a kind of associative container that supports equivalent keys -//! (possibly containing multiple copies of the same key value) and provides for -//! fast retrieval of values of another type T based on the keys. The multimap class -//! supports bidirectional iterators. -//! -//! A multimap satisfies all of the requirements of a container and of a reversible -//! container and of an associative container. The value_type stored -//! by this container is the value_type is std::pair. -//! -//! \tparam Key is the key_type of the map -//! \tparam Value is the mapped_type -//! \tparam Compare is the ordering function for Keys (e.g. std::less). -//! \tparam Allocator is the allocator to allocate the value_types -//! (e.g. allocator< std::pair > ). -//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options. -template < class Key, class T, class Compare = std::less - , class Allocator = new_allocator< std::pair< const Key, T> >, class Options = tree_assoc_defaults> -#else -template -#endif -class multimap - ///@cond - : public dtl::tree - < std::pair - , int - , Compare, Allocator, Options> - ///@endcond -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(multimap) - - typedef int select_1st_t; - typedef std::pair value_type_impl; - typedef dtl::tree - base_t; - typedef dtl::pair movable_value_type_impl; - typedef typename base_t::value_compare value_compare_impl; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - - typedef Key key_type; - typedef T mapped_type; - typedef typename base_t::allocator_type allocator_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename boost::container::allocator_traits::value_type value_type; - typedef typename boost::container::allocator_traits::pointer pointer; - typedef typename boost::container::allocator_traits::const_pointer const_pointer; - typedef typename boost::container::allocator_traits::reference reference; - typedef typename boost::container::allocator_traits::const_reference const_reference; - typedef typename boost::container::allocator_traits::size_type size_type; - typedef typename boost::container::allocator_traits::difference_type difference_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; - typedef Compare key_compare; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - 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 std::pair nonconst_value_type; - typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; - typedef BOOST_CONTAINER_IMPDEF(node_handle< - typename base_t::stored_allocator_type - BOOST_MOVE_I pair_key_mapped_of_value - >) node_type; - - //allocator_type::value_type type must be std::pair - BOOST_STATIC_ASSERT((dtl::is_same >::value)); - - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructs an empty multimap. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE multimap() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value && - dtl::is_nothrow_default_constructible::value) - : base_t() - {} - - //! Effects: Constructs an empty multimap using the specified allocator - //! object and allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit multimap(const allocator_type& a) - : base_t(a) - {} - - //! Effects: Constructs an empty multimap using the specified comparison. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit multimap(const Compare& comp) - : base_t(comp) - {} - - //! Effects: Constructs an empty multimap using the specified comparison and allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE multimap(const Compare& comp, const allocator_type& a) - : base_t(comp, a) - {} - - //! Effects: Constructs an empty multimap and - //! inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last) - : base_t(false, first, last) - {} - - //! Effects: Constructs an empty multimap using the specified - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last, const allocator_type& a) - : base_t(false, first, last, Compare(), a) - {} - - //! Effects: Constructs an empty multimap using the specified comparison object and - //! inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last, const Compare& comp) - : base_t(false, first, last, comp) - {} - - //! Effects: Constructs an empty multimap using the specified comparison object - //! and allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last, - const Compare& comp, const allocator_type& a) - : base_t(false, first, last, comp, a) - {} - - //! Effects: Constructs an empty multimap and - //! inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last) - : base_t(ordered_range, first, last) - {} - - //! Effects: Constructs an empty multimap using the specified comparison object and - //! inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp) - : base_t(ordered_range, first, last, comp) - {} - - //! Effects: Constructs an empty multimap using the specified comparison object and - //! allocator, and inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, - const allocator_type& a) - : base_t(ordered_range, first, last, comp, a) - {} - - //! Effects: Constructs an empty multimap using the specified allocator and - //! inserts elements from the ordered range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const allocator_type& a) - : base_t(ordered_range, first, last, Compare(), a) - {} - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs an empty multimap and - //! and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is il.first() - il.end(). - BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list il) - : base_t(false, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty multimap using the specified - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is il.first() - il.end(). - BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list il, const allocator_type& a) - : base_t(false, il.begin(), il.end(), Compare(), a) - {} - - //! Effects: Constructs an empty multimap using the specified comparison object and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is il.first() - il.end(). - BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list il, const Compare& comp) - : base_t(false, il.begin(), il.end(), comp) - {} - - //! Effects: Constructs an empty multimap using the specified comparison object and - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is il.first() - il.end(). - BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list il, const Compare& comp, const allocator_type& a) - : base_t(false, il.begin(), il.end(), comp, a) - {} - - - //! Effects: Constructs an empty map and - //! inserts elements from the ordered range [il.begin(), il.end()). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list il) - : base_t(ordered_range, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty map using the specified comparison object and - //! inserts elements from the ordered range [il.begin(), il.end()). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list il, const Compare& comp) - : base_t(ordered_range, il.begin(), il.end(), comp) - {} - - //! Effects: Constructs an empty map and - //! inserts elements from the ordered range [il.begin(), il.end()). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list il, const Compare& comp, const allocator_type& a) - : base_t(ordered_range, il.begin(), il.end(), comp, a) - {} - -#endif - - //! Effects: Copy constructs a multimap. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE multimap(const multimap& x) - : base_t(static_cast(x)) - {} - - //! Effects: Move constructs a multimap. Constructs *this using x's resources. - //! - //! Complexity: Constant. - //! - //! Postcondition: x is emptied. - BOOST_CONTAINER_FORCEINLINE multimap(BOOST_RV_REF(multimap) x) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : base_t(BOOST_MOVE_BASE(base_t, x)) - {} - - //! Effects: Copy constructs a multimap. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE multimap(const multimap& x, const allocator_type &a) - : base_t(static_cast(x), a) - {} - - //! Effects: Move constructs a multimap using the specified allocator. - //! Constructs *this using x's resources. - //! Complexity: Constant if a == x.get_allocator(), linear otherwise. - //! - //! Postcondition: x is emptied. - BOOST_CONTAINER_FORCEINLINE multimap(BOOST_RV_REF(multimap) x, const allocator_type &a) - : base_t(BOOST_MOVE_BASE(base_t, x), a) - {} - - //! Effects: Makes *this a copy of x. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x) - { return static_cast(this->base_t::operator=(static_cast(x))); } - - //! Effects: this->swap(x.get()). - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE multimap& operator=(BOOST_RV_REF(multimap) x) - BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value || - allocator_traits_type::is_always_equal::value) && - boost::container::dtl::is_nothrow_move_assignable::value) - { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Assign content of il to *this. - //! - BOOST_CONTAINER_FORCEINLINE multimap& operator=(std::initializer_list il) - { - this->clear(); - insert(il.begin(), il.end()); - return *this; - } -#endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! @copydoc ::boost::container::set::get_allocator() - allocator_type get_allocator() const; - - //! @copydoc ::boost::container::set::get_stored_allocator() - stored_allocator_type &get_stored_allocator(); - - //! @copydoc ::boost::container::set::get_stored_allocator() const - const stored_allocator_type &get_stored_allocator() const; - - //! @copydoc ::boost::container::set::begin() - iterator begin(); - - //! @copydoc ::boost::container::set::begin() const - const_iterator begin() const; - - //! @copydoc ::boost::container::set::cbegin() const - const_iterator cbegin() const; - - //! @copydoc ::boost::container::set::end() - iterator end() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::end() const - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::cend() const - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::rbegin() - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::rbegin() const - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::crbegin() const - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::rend() - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::rend() const - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::crend() const - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::empty() const - bool empty() const; - - //! @copydoc ::boost::container::set::size() const - size_type size() const; - - //! @copydoc ::boost::container::set::max_size() const - size_type max_size() const; - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args) - { return this->base_t::emplace_equal(boost::forward(args)...); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args) - { return this->base_t::emplace_hint_equal(p, boost::forward(args)...); } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\ - { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE) - #undef BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - //! Effects: Inserts x and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x) - { return this->base_t::insert_equal_convertible(x); } - - //! Effects: Inserts a new value move-constructed from x and returns - //! the iterator pointing to the newly inserted element. - //! - //! Complexity: Logarithmic. - BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(value_type) x) - { return this->base_t::insert_equal_convertible(boost::move(x)); } - - //! Effects: Inserts a new value constructed from x and returns - //! the iterator pointing to the newly inserted element. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST - ( iterator - , typename dtl::enable_if_c< - dtl::is_convertible::value || - dtl::is_convertible::value - BOOST_MOVE_I iterator >::type) - insert(BOOST_FWD_REF(Pair) x) - { return this->base_t::emplace_equal(boost::forward(x)); } - - //! Effects: Inserts a copy of x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x) - { return this->base_t::insert_equal_hint_convertible(p, x); } - - //! Effects: Inserts a new value move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x) - { return this->base_t::insert_equal_hint_convertible(p, boost::move(x)); } - - //! Effects: Inserts a new value constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST - ( iterator - , typename dtl::enable_if_c< - dtl::is_convertible::value || - dtl::is_convertible::value - BOOST_MOVE_I iterator>::type) - insert(const_iterator p, BOOST_FWD_REF(Pair) x) - { return this->base_t::emplace_hint_equal(p, boost::forward(x)); } - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) . - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - template - BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->base_t::insert_equal_range(first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: inserts each element from the range [il.begin(), il.end(). - //! - //! Complexity: At most N log(size()+N) (N is the distance from il.begin() to il.end()) - BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list il) - { this->base_t::insert_equal_range(il.begin(), il.end()); } -#endif - - //! Requires: nh is empty or this->get_allocator() == nh.get_allocator(). - //! - //! Effects/Returns: If nh is empty, has no effect and returns end(). Otherwise, inserts - //! the element owned by nh and returns an iterator pointing to the newly inserted element. - //! If a range containing elements with keys equivalent to nh.key() exists, - //! the element is inserted at the end of that range. nh is always emptied. - //! - //! Complexity: Logarithmic - iterator insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh) - { - typename base_t::node_type n(boost::move(nh)); - return this->base_t::insert_equal_node(boost::move(n)); - } - - //! Effects: Same as `insert(node_type && nh)` but the element is inserted as close as possible - //! to the position just prior to "hint". - //! - //! Complexity: logarithmic in general, but amortized constant if the element is inserted - //! right before "hint". - iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh) - { - typename base_t::node_type n(boost::move(nh)); - return this->base_t::insert_equal_node(hint, boost::move(n)); - } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! @copydoc ::boost::container::set::erase(const_iterator) - iterator erase(const_iterator p); - - //! @copydoc ::boost::container::set::erase(const key_type&) - size_type erase(const key_type& x); - - //! @copydoc ::boost::container::set::erase(const_iterator,const_iterator) - iterator erase(const_iterator first, const_iterator last); - #endif - - //! @copydoc ::boost::container::map::extract(const key_type&) - node_type extract(const key_type& k) - { - typename base_t::node_type base_nh(this->base_t::extract(k)); - return node_type(boost::move(base_nh)); - } - - //! @copydoc ::boost::container::map::extract(const_iterator) - node_type extract(const_iterator position) - { - typename base_t::node_type base_nh(this->base_t::extract(position)); - return node_type (boost::move(base_nh)); - } - - //! Requires: this->get_allocator() == source.get_allocator(). - //! - //! Effects: Extracts each element in source and insert it into a using - //! the comparison object of *this. - //! - //! Postcondition: 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. - //! - //! Throws: Nothing unless the comparison object throws. - //! - //! Complexity: N log(size() + N) (N has the value source.size()) - template - BOOST_CONTAINER_FORCEINLINE void merge(multimap& source) - { - typedef dtl::tree - base2_t; - this->base_t::merge_equal(static_cast(source)); - } - - //! @copydoc ::boost::container::multimap::merge(multimap&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multimap BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! @copydoc ::boost::container::multimap::merge(multimap&) - template - BOOST_CONTAINER_FORCEINLINE void merge(map& source) - { - typedef dtl::tree - base2_t; - this->base_t::merge_equal(static_cast(source)); - } - - //! @copydoc ::boost::container::multimap::merge(multimap&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG map BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! @copydoc ::boost::container::set::swap - void swap(multiset& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - //! @copydoc ::boost::container::set::clear - void clear() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::key_comp - key_compare key_comp() const; - - //! @copydoc ::boost::container::set::value_comp - value_compare value_comp() const; - - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - iterator find(const key_type& x); - - //! Returns: A const iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - const_iterator find(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - iterator find(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - const_iterator find(const K& x) const; - - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - size_type count(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - template - size_type count(const K& x) const; - - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - bool contains(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - template - bool contains(const K& x) const; - - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator lower_bound(const key_type& x); - - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator lower_bound(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - iterator lower_bound(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - const_iterator lower_bound(const K& x) const; - - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator upper_bound(const key_type& x); - - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator upper_bound(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - iterator upper_bound(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - const_iterator upper_bound(const K& x) const; - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - std::pair equal_range(const key_type& x); - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - std::pair equal_range(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - std::pair equal_range(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - std::pair equal_range(const K& x) const; - - //! Effects: Rebalances the tree. It's a no-op for Red-Black and AVL trees. - //! - //! Complexity: Linear - void rebalance(); - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const multimap& x, const multimap& y); - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const multimap& x, const multimap& y); - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const multimap& x, const multimap& y); - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const multimap& x, const multimap& y); - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<=(const multimap& x, const multimap& y); - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>=(const multimap& x, const multimap& y); - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - friend void swap(multimap& x, multimap& y) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -multimap(InputIterator, InputIterator) -> - multimap< it_based_non_const_first_type_t - , it_based_second_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> -multimap(InputIterator, InputIterator, AllocatorOrCompare const&) -> - multimap< it_based_non_const_first_type_t - , it_based_second_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator, it_based_second_type_t>> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> - multimap< it_based_non_const_first_type_t - , it_based_second_type_t - , Compare - , Allocator>; - -template -multimap(ordered_range_t, InputIterator, InputIterator) -> - multimap< it_based_non_const_first_type_t - , it_based_second_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> -multimap(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> - multimap< it_based_non_const_first_type_t - , it_based_second_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator, it_based_second_type_t>> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - multimap< it_based_non_const_first_type_t - , it_based_second_type_t - , Compare - , Allocator>; -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef ::boost::container::dtl::tree, int, Compare, Allocator, Options> tree; - static const bool value = ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -}} - -#include - -#endif // BOOST_CONTAINER_MAP_HPP - diff --git a/inst/i/b/container/node_allocator.hpp b/inst/i/b/container/node_allocator.hpp deleted file mode 100644 index fdf2e65e8..000000000 --- a/inst/i/b/container/node_allocator.hpp +++ /dev/null @@ -1,341 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2008-2013. 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_POOLED_NODE_ALLOCATOR_HPP -#define BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace boost { -namespace container { - -//!An STL node allocator that uses a modified DlMalloc as memory -//!source. -//! -//!This node allocator shares a segregated storage between all instances -//!of node_allocator with equal sizeof(T). -//! -//!NodesPerBlock is the number of nodes allocated at once when the allocator -//!runs out of nodes -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template - < class T - , std::size_t NodesPerBlock = NodeAlloc_nodes_per_block> -#else -template - < class T - , std::size_t NodesPerBlock - , std::size_t Version> -#endif -class node_allocator -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - //! If Version is 1, the allocator is a STL conforming allocator. If Version is 2, - //! the allocator offers advanced expand in place and burst allocation capabilities. - public: - typedef unsigned int allocation_type; - typedef node_allocator self_t; - - static const std::size_t nodes_per_block = NodesPerBlock; - - BOOST_STATIC_ASSERT((Version <=2)); - #endif - - public: - //------- - typedef T value_type; - typedef T * pointer; - typedef const T * const_pointer; - typedef typename ::boost::container:: - dtl::unvoid_ref::type reference; - typedef typename ::boost::container:: - dtl::unvoid_ref::type const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - typedef boost::container::dtl:: - version_type version; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef boost::container::dtl:: - basic_multiallocation_chain multiallocation_chain_void; - typedef boost::container::dtl:: - transform_multiallocation_chain - multiallocation_chain; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - //!Obtains node_allocator from - //!node_allocator - template - struct rebind - { - typedef node_allocator< T2, NodesPerBlock - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - , Version - #endif - > other; - }; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - //!Not assignable from related node_allocator - template - node_allocator& operator= - (const node_allocator&); - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - - //!Default constructor - node_allocator() BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Copy constructor from other node_allocator. - node_allocator(const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Copy constructor from related node_allocator. - template - node_allocator - (const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Destructor - ~node_allocator() BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!Returns the number of elements that could be allocated. - //!Never throws - size_type max_size() const - { return size_type(-1)/sizeof(T); } - - //!Allocate memory for an array of count elements. - //!Throws bad_alloc if there is no enough memory - pointer allocate(size_type count, const void * = 0) - { - if(BOOST_UNLIKELY(count > this->max_size())) - boost::container::throw_bad_alloc(); - - if(Version == 1 && count == 1){ - typedef dtl::shared_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - return pointer(static_cast(singleton_t::instance().allocate_node())); - } - else{ - void *ret = dlmalloc_malloc(count*sizeof(T)); - if(BOOST_UNLIKELY(!ret)) - boost::container::throw_bad_alloc(); - return static_cast(ret); - } - } - - //!Deallocate allocated memory. - //!Never throws - void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW - { - (void)count; - if(Version == 1 && count == 1){ - typedef dtl::shared_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - singleton_t::instance().deallocate_node(ptr); - } - else{ - dlmalloc_free(ptr); - } - } - - //!Deallocates all free blocks of the pool - static void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW - { - typedef dtl::shared_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - singleton_t::instance().deallocate_free_blocks(); - } - - pointer allocation_command - (allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) - { - BOOST_STATIC_ASSERT(( Version > 1 )); - pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); - if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))) - boost::container::throw_bad_alloc(); - return ret; - } - - //!Returns maximum the number of objects the previously allocated memory - //!pointed by p can hold. - size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_STATIC_ASSERT(( Version > 1 )); - return dlmalloc_size(p); - } - - //!Allocates just one object. Memory allocated with this function - //!must be deallocated only with deallocate_one(). - //!Throws bad_alloc if there is no enough memory - pointer allocate_one() - { - BOOST_STATIC_ASSERT(( Version > 1 )); - typedef dtl::shared_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - return (pointer)singleton_t::instance().allocate_node(); - } - - //!Allocates many elements of size == 1. - //!Elements must be individually deallocated with deallocate_one() - void allocate_individual(std::size_t num_elements, multiallocation_chain &chain) - { - BOOST_STATIC_ASSERT(( Version > 1 )); - typedef dtl::shared_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - typename shared_pool_t::multiallocation_chain ch; - singleton_t::instance().allocate_nodes(num_elements, ch); - chain.incorporate_after(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size()); - } - - //!Deallocates memory previously allocated with allocate_one(). - //!You should never use deallocate_one to deallocate memory allocated - //!with other functions different from allocate_one(). Never throws - void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_STATIC_ASSERT(( Version > 1 )); - typedef dtl::shared_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - singleton_t::instance().deallocate_node(p); - } - - void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_STATIC_ASSERT(( Version > 1 )); - typedef dtl::shared_node_pool - shared_pool_t; - typedef dtl::singleton_default singleton_t; - typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size()); - singleton_t::instance().deallocate_nodes(ch); - } - - //!Allocates many elements of size elem_size. - //!Elements must be individually deallocated with deallocate() - void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain) - { - BOOST_STATIC_ASSERT(( Version > 1 )); - dlmalloc_memchain ch; - BOOST_CONTAINER_MEMCHAIN_INIT(&ch); - if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){ - boost::container::throw_bad_alloc(); - } - chain.incorporate_after( chain.before_begin() - , (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) - , (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) - , BOOST_CONTAINER_MEMCHAIN_SIZE(&ch)); - } - - //!Allocates n_elements elements, each one of size elem_sizes[i] - //!Elements must be individually deallocated with deallocate() - void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain) - { - BOOST_STATIC_ASSERT(( Version > 1 )); - dlmalloc_memchain ch; - dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch); - if(BOOST_UNLIKELY(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch))){ - boost::container::throw_bad_alloc(); - } - chain.incorporate_after( chain.before_begin() - , (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) - , (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) - , BOOST_CONTAINER_MEMCHAIN_SIZE(&ch)); - } - - void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_STATIC_ASSERT(( Version > 1 )); - void *first = &*chain.begin(); - void *last = &*chain.last(); - size_t num = chain.size(); - dlmalloc_memchain ch; - BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, first, last, num); - dlmalloc_multidealloc(&ch); - } - - //!Swaps allocators. Does not throw. If each allocator is placed in a - //!different memory segment, the result is undefined. - friend void swap(self_t &, self_t &) BOOST_NOEXCEPT_OR_NOTHROW - {} - - //!An allocator always compares to true, as memory allocated with one - //!instance can be deallocated by another instance - friend bool operator==(const node_allocator &, const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW - { return true; } - - //!An allocator always compares to false, as memory allocated with one - //!instance can be deallocated by another instance - friend bool operator!=(const node_allocator &, const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW - { return false; } - - private: - pointer priv_allocation_command - (allocation_type command, std::size_t limit_size - ,size_type &prefer_in_recvd_out_size - ,pointer &reuse) - { - std::size_t const preferred_size = prefer_in_recvd_out_size; - dlmalloc_command_ret_t ret = {0 , 0}; - if((limit_size > this->max_size()) || (preferred_size > this->max_size())){ - return pointer(); - } - std::size_t l_size = limit_size*sizeof(T); - std::size_t p_size = preferred_size*sizeof(T); - std::size_t r_size; - { - void* reuse_ptr_void = reuse; - ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void); - reuse = static_cast(reuse_ptr_void); - } - prefer_in_recvd_out_size = r_size/sizeof(T); - return (pointer)ret.first; - } -}; - -} //namespace container { -} //namespace boost { - -#include - -#endif //#ifndef BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP diff --git a/inst/i/b/container/node_handle.hpp b/inst/i/b/container/node_handle.hpp deleted file mode 100644 index 74fac67ea..000000000 --- a/inst/i/b/container/node_handle.hpp +++ /dev/null @@ -1,445 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (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 -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - - -//!\file - -namespace boost { -namespace container { - -///@cond - -template -struct node_handle_keymapped_traits -{ - typedef typename KeyMapped::key_type key_type; - typedef typename KeyMapped::mapped_type mapped_type; -}; - -template -struct node_handle_keymapped_traits -{ - typedef Value key_type; - typedef Value mapped_type; -}; - -class node_handle_friend -{ - public: - - template - BOOST_CONTAINER_FORCEINLINE static void destroy_alloc(NH &nh) BOOST_NOEXCEPT - { nh.destroy_alloc(); } - - template - BOOST_CONTAINER_FORCEINLINE static typename NH::node_pointer &get_node_pointer(NH &nh) BOOST_NOEXCEPT - { return nh.get_node_pointer(); } -}; - - -///@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 <-> map -//! -//! map <-> multimap -//! -//! set <-> set -//! -//! set <-> multiset -//! -//! 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 node_handle -{ - typedef NodeAllocator nallocator_type; - typedef allocator_traits nator_traits; - typedef typename nator_traits::value_type priv_node_t; - typedef typename priv_node_t::value_type priv_value_t; - typedef node_handle_keymapped_traits keymapped_t; - - public: - typedef priv_value_t value_type; - typedef typename keymapped_t::key_type key_type; - typedef typename keymapped_t::mapped_type mapped_type; - typedef typename nator_traits::template portable_rebind_alloc - ::type allocator_type; - - typedef priv_node_t container_node_type; - friend class node_handle_friend; - - ///@cond - private: - BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle) - - typedef typename nator_traits::pointer node_pointer; - typedef typename dtl::aligned_storage - < sizeof(nallocator_type) - , dtl::alignment_of::value - >::type nalloc_storage_t; - - node_pointer m_ptr; - nalloc_storage_t m_nalloc_storage; - - void move_construct_alloc(nallocator_type &al) - { ::new((void*)m_nalloc_storage.data, boost_container_new_t()) nallocator_type(::boost::move(al)); } - - void destroy_deallocate_node() - { - boost::movelib::to_raw_pointer(m_ptr)->destructor(this->node_alloc()); - nator_traits::deallocate(this->node_alloc(), m_ptr, 1u); - } - - template - void move_construct_end(OtherNodeHandle &nh) - { - if(m_ptr){ - ::new ((void*)m_nalloc_storage.data, boost_container_new_t()) nallocator_type(::boost::move(nh.node_alloc())); - node_handle_friend::destroy_alloc(nh); - node_handle_friend::get_node_pointer(nh) = node_pointer(); - } - BOOST_ASSERT(nh.empty()); - } - - void destroy_alloc() BOOST_NOEXCEPT - { static_cast((void*)m_nalloc_storage.data)->~nallocator_type(); } - - node_pointer &get_node_pointer() BOOST_NOEXCEPT - { return m_ptr; } - - ///@endcond - - public: - //! Effects: Initializes m_ptr to nullptr. - //! - //! Postcondition: this->empty() - BOOST_CXX14_CONSTEXPR node_handle() BOOST_NOEXCEPT - : m_ptr() - { } - - //! Effects: Constructs a node_handle object initializing internal pointer with p. - //! If p != nullptr copy constructs internal allocator from al. - node_handle(node_pointer p, const nallocator_type &al) BOOST_NOEXCEPT - : m_ptr(p) - { - if(m_ptr){ - ::new ((void*)m_nalloc_storage.data, boost_container_new_t()) nallocator_type(al); - } - } - - //! Effects: 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. - //! - //! Postcondition: nh.empty() - //! - //! Note: Two node_handle's are related if only one of KeyMapped template parameter - //! of a node handle is void. - template - node_handle( BOOST_RV_REF_BEG node_handle BOOST_RV_REF_END nh - , typename dtl::enable_if_c - < ((unsigned)dtl::is_same::value + - (unsigned)dtl::is_same::value) == 1u - >::type* = 0) BOOST_NOEXCEPT - : m_ptr(nh.get()) - { this->move_construct_end(nh); } - - //! Effects: 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. - //! - //! Postcondition: nh.empty() - node_handle (BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT - : m_ptr(nh.m_ptr) - { this->move_construct_end(nh); } - - //! Effects: If !this->empty(), destroys the value_type subobject in the container_node_type object - //! pointed to by c by calling allocator_traits::destroy, then deallocates m_ptr by calling - //! nator_traits::rebind_traits::deallocate. - ~node_handle() BOOST_NOEXCEPT - { - if(!this->empty()){ - this->destroy_deallocate_node(); - this->destroy_alloc(); - } - } - - //! Requires: Either this->empty(), or nator_traits::propagate_on_container_move_assignment is true, or - //! node_alloc() == nh.node_alloc(). - //! - //! Effects: If m_ptr != nullptr, destroys the value_type subobject in the container_node_type object - //! pointed to by m_ptr by calling nator_traits::destroy, then deallocates m_ptr by calling - //! nator_traits::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty() - //! or nator_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(). - //! - //! Returns: *this. - //! - //! Throws: Nothing. - node_handle & operator=(BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT - { - BOOST_ASSERT(this->empty() || nator_traits::propagate_on_container_move_assignment::value - || nator_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_deallocate_node(); - if(nator_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_deallocate_node(); - this->destroy_alloc(); - m_ptr = node_pointer(); - } - return *this; - } - - //! Requires: empty() == false. - //! - //! Returns: A reference to the value_type subobject in the container_node_type object pointed to by m_ptr - //! - //! Throws: Nothing. - value_type& value() const BOOST_NOEXCEPT - { - BOOST_STATIC_ASSERT((dtl::is_same::value)); - BOOST_ASSERT(!empty()); - return m_ptr->get_data(); - } - - //! Requires: empty() == false. - //! - //! Returns: 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. - //! - //! Throws: Nothing. - //! - //! Requires: Modifying the key through the returned reference is permitted. - key_type& key() const BOOST_NOEXCEPT - { - BOOST_STATIC_ASSERT((!dtl::is_same::value)); - BOOST_ASSERT(!empty()); - return const_cast(KeyMapped().key_of_value(m_ptr->get_data())); - } - - //! Requires: empty() == false. - //! - //! Returns: A reference to the mapped_type member of the value_type subobject - //! in the container_node_type object pointed to by m_ptr - //! - //! Throws: Nothing. - mapped_type& mapped() const BOOST_NOEXCEPT - { - BOOST_STATIC_ASSERT((!dtl::is_same::value)); - BOOST_ASSERT(!empty()); - return KeyMapped().mapped_of_value(m_ptr->get_data()); - } - - //! Requires: empty() == false. - //! - //! Returns: A copy of the internally hold allocator. - //! - //! Throws: Nothing. - allocator_type get_allocator() const - { - BOOST_ASSERT(!empty()); - return this->node_alloc(); - } - - //! Returns: 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); } - - //! Returns: m_ptr == nullptr. - //! - bool empty() const BOOST_NOEXCEPT - { - return !this->m_ptr; - } - - //! Requires: this->empty(), or nh.empty(), or nator_traits::propagate_on_container_swap is true, or - //! node_alloc() == nh.node_alloc(). - //! - //! Effects: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or nator_traits::propagate_on_- - //! container_swap is true calls swap(node_alloc(), nh.node_alloc()). - void swap(node_handle &nh) - BOOST_NOEXCEPT_IF(nator_traits::propagate_on_container_swap::value || nator_traits::is_always_equal::value) - { - BOOST_ASSERT(this->empty() || nh.empty() || nator_traits::propagate_on_container_swap::value - || nator_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(nator_traits::propagate_on_container_swap::value){ - ::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()); - this->destroy_alloc(); - } - ::boost::adl_move_swap(m_ptr, nh.m_ptr); - } - - //! Effects: If this->empty() returns nullptr, otherwise returns m_ptr - //! resets m_ptr to nullptr and destroys the internal allocator. - //! - //! Postcondition: this->empty() - //! - //! Note: Non-standard extensions - node_pointer release() BOOST_NOEXCEPT - { - node_pointer p(m_ptr); - m_ptr = node_pointer(); - if(p) - this->destroy_alloc(); - return p; - } - - //! Effects: Returns m_ptr. - //! - //! Note: Non-standard extensions - node_pointer get() const BOOST_NOEXCEPT - { - return m_ptr; - } - - //! Effects: Returns a reference to the internal node allocator. - //! - //! Note: Non-standard extensions - nallocator_type &node_alloc() BOOST_NOEXCEPT - { - BOOST_ASSERT(!empty()); - return *static_cast((void*)m_nalloc_storage.data); - } - - - //! Effects: Returns a reference to the internal node allocator. - //! - //! Note: Non-standard extensions - const nallocator_type &node_alloc() const BOOST_NOEXCEPT - { - BOOST_ASSERT(!empty()); - return *static_cast((const void*)m_nalloc_storage.data); - } - - //! Effects: 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: -//! -//!
  • bool inserted
  • ; -//!
  • Iterator position
  • ; -//!
  • NodeType node
-//! -//! This type is MoveConstructible, MoveAssignable, DefaultConstructible, -//! Destructible, and lvalues of that type are swappable -template -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 - insert_return_type_base(bool insert, RelatedIt it, BOOST_RV_REF(RelatedNode) n) - : inserted(insert), position(it), node(boost::move(n)) - {} - - 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 - -#endif //BOOST_CONTAINER_NODE_HANDLE_HPP diff --git a/inst/i/b/container/scoped_allocator.hpp b/inst/i/b/container/scoped_allocator.hpp deleted file mode 100644 index b9a067366..000000000 --- a/inst/i/b/container/scoped_allocator.hpp +++ /dev/null @@ -1,905 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Pablo Halpern 2009. 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) -// -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2011-2013. 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_ALLOCATOR_SCOPED_ALLOCATOR_HPP -#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP - -#if defined (_MSC_VER) -# pragma once -#endif - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -#include - -namespace boost { namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -namespace dtl { - -template -struct is_scoped_allocator_imp -{ - typedef char yes_type; - struct no_type{ char dummy[2]; }; - - template - static yes_type test(typename T::outer_allocator_type*); - - template - static int test(...); - - static const bool value = (sizeof(yes_type) == sizeof(test(0))); -}; - -template::value > -struct outermost_allocator_type_impl -{ - typedef typename MaybeScopedAlloc::outer_allocator_type outer_type; - typedef typename outermost_allocator_type_impl::type type; -}; - -template -struct outermost_allocator_type_impl -{ - typedef MaybeScopedAlloc type; -}; - -template::value > -struct outermost_allocator_imp -{ - typedef MaybeScopedAlloc type; - - BOOST_CONTAINER_FORCEINLINE static type &get(MaybeScopedAlloc &a) - { return a; } - - BOOST_CONTAINER_FORCEINLINE static const type &get(const MaybeScopedAlloc &a) - { return a; } -}; - -template -struct outermost_allocator_imp -{ - typedef typename MaybeScopedAlloc::outer_allocator_type outer_type; - typedef typename outermost_allocator_type_impl::type type; - - BOOST_CONTAINER_FORCEINLINE static type &get(MaybeScopedAlloc &a) - { return outermost_allocator_imp::get(a.outer_allocator()); } - - BOOST_CONTAINER_FORCEINLINE static const type &get(const MaybeScopedAlloc &a) - { return outermost_allocator_imp::get(a.outer_allocator()); } -}; - -} //namespace dtl { - -template -struct is_scoped_allocator - : dtl::is_scoped_allocator_imp -{}; - -template -struct outermost_allocator - : dtl::outermost_allocator_imp -{}; - -template -BOOST_CONTAINER_FORCEINLINE typename outermost_allocator::type & - get_outermost_allocator(Allocator &a) -{ return outermost_allocator::get(a); } - -template -BOOST_CONTAINER_FORCEINLINE const typename outermost_allocator::type & - get_outermost_allocator(const Allocator &a) -{ return outermost_allocator::get(a); } - -namespace dtl { - -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -template -class scoped_allocator_adaptor_base - : public OuterAlloc -{ - typedef allocator_traits outer_traits_type; - BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) - - public: - template - struct rebind_base - { - typedef scoped_allocator_adaptor_base other; - }; - - typedef OuterAlloc outer_allocator_type; - typedef scoped_allocator_adaptor inner_allocator_type; - typedef allocator_traits inner_traits_type; - typedef scoped_allocator_adaptor - scoped_allocator_type; - typedef dtl::bool_< - outer_traits_type::propagate_on_container_copy_assignment::value || - inner_allocator_type::propagate_on_container_copy_assignment::value - > propagate_on_container_copy_assignment; - typedef dtl::bool_< - outer_traits_type::propagate_on_container_move_assignment::value || - inner_allocator_type::propagate_on_container_move_assignment::value - > propagate_on_container_move_assignment; - typedef dtl::bool_< - outer_traits_type::propagate_on_container_swap::value || - inner_allocator_type::propagate_on_container_swap::value - > propagate_on_container_swap; - typedef dtl::bool_< - outer_traits_type::is_always_equal::value && - inner_allocator_type::is_always_equal::value - > is_always_equal; - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base() - {} - - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args) - : outer_allocator_type(::boost::forward(outerAlloc)) - , m_inner(args...) - {} - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) - : outer_allocator_type(other.outer_allocator()) - , m_inner(other.inner_allocator()) - {} - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) - : outer_allocator_type(::boost::move(other.outer_allocator())) - , m_inner(::boost::move(other.inner_allocator())) - {} - - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base - (const scoped_allocator_adaptor_base& other) - : outer_allocator_type(other.outer_allocator()) - , m_inner(other.inner_allocator()) - {} - - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base - (BOOST_RV_REF_BEG scoped_allocator_adaptor_base - BOOST_RV_REF_END other) - : outer_allocator_type(other.outer_allocator()) - , m_inner(other.inner_allocator()) - {} - - public: - struct internal_type_t{}; - - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base - ( internal_type_t - , BOOST_FWD_REF(OuterA2) outerAlloc - , const inner_allocator_type &inner) - : outer_allocator_type(::boost::forward(outerAlloc)) - , m_inner(inner) - {} - - public: - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator= - (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) - { - outer_allocator_type::operator=(other.outer_allocator()); - m_inner = other.inner_allocator(); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) - { - outer_allocator_type::operator=(boost::move(other.outer_allocator())); - m_inner = ::boost::move(other.inner_allocator()); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r) - { - boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); - boost::adl_move_swap(this->m_inner, r.inner_allocator()); - } - - BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) - { l.swap(r); } - - BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW - { return m_inner; } - - BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return m_inner; } - - BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const - { - return scoped_allocator_type - (internal_type_t() - ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) - ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) - ); - } - - private: - inner_allocator_type m_inner; -}; - -#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -//Let's add a dummy first template parameter to allow creating -//specializations up to maximum InnerAlloc count -template -class scoped_allocator_adaptor_base; - -//Specializations for the adaptor with InnerAlloc allocators - -#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\ -template \ -class scoped_allocator_adaptor_base\ - : public OuterAlloc\ -{\ - typedef allocator_traits outer_traits_type;\ - BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\ - \ - public:\ - template \ - struct rebind_base\ - {\ - typedef scoped_allocator_adaptor_base other;\ - };\ - \ - typedef OuterAlloc outer_allocator_type;\ - typedef scoped_allocator_adaptor inner_allocator_type;\ - typedef scoped_allocator_adaptor scoped_allocator_type;\ - typedef allocator_traits inner_traits_type;\ - typedef dtl::bool_<\ - outer_traits_type::propagate_on_container_copy_assignment::value ||\ - inner_allocator_type::propagate_on_container_copy_assignment::value\ - > propagate_on_container_copy_assignment;\ - typedef dtl::bool_<\ - outer_traits_type::propagate_on_container_move_assignment::value ||\ - inner_allocator_type::propagate_on_container_move_assignment::value\ - > propagate_on_container_move_assignment;\ - typedef dtl::bool_<\ - outer_traits_type::propagate_on_container_swap::value ||\ - inner_allocator_type::propagate_on_container_swap::value\ - > propagate_on_container_swap;\ - \ - typedef dtl::bool_<\ - outer_traits_type::is_always_equal::value &&\ - inner_allocator_type::is_always_equal::value\ - > is_always_equal;\ - \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(){}\ - \ - template \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\ - : outer_allocator_type(::boost::forward(outerAlloc))\ - , m_inner(BOOST_MOVE_ARG##N)\ - {}\ - \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\ - : outer_allocator_type(other.outer_allocator())\ - , m_inner(other.inner_allocator())\ - {}\ - \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ - : outer_allocator_type(::boost::move(other.outer_allocator()))\ - , m_inner(::boost::move(other.inner_allocator()))\ - {}\ - \ - template \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\ - (const scoped_allocator_adaptor_base& other)\ - : outer_allocator_type(other.outer_allocator())\ - , m_inner(other.inner_allocator())\ - {}\ - \ - template \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\ - (BOOST_RV_REF_BEG scoped_allocator_adaptor_base BOOST_RV_REF_END other)\ - : outer_allocator_type(other.outer_allocator())\ - , m_inner(other.inner_allocator())\ - {}\ - \ - public:\ - struct internal_type_t{};\ - \ - template \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\ - ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\ - : outer_allocator_type(::boost::forward(outerAlloc))\ - , m_inner(inner)\ - {}\ - \ - public:\ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=\ - (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\ - {\ - outer_allocator_type::operator=(other.outer_allocator());\ - m_inner = other.inner_allocator();\ - return *this;\ - }\ - \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ - {\ - outer_allocator_type::operator=(boost::move(other.outer_allocator()));\ - m_inner = ::boost::move(other.inner_allocator());\ - return *this;\ - }\ - \ - BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r)\ - {\ - boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\ - boost::adl_move_swap(this->m_inner, r.inner_allocator());\ - }\ - \ - BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\ - { l.swap(r); }\ - \ - BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator()\ - { return m_inner; }\ - \ - BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const\ - { return m_inner; }\ - \ - BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator()\ - { return static_cast(*this); }\ - \ - BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const\ - { return static_cast(*this); }\ - \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const\ - {\ - return scoped_allocator_type\ - (internal_type_t()\ - ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\ - ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\ - );\ - }\ - private:\ - inner_allocator_type m_inner;\ -};\ -//! -BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE) -#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE - -#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true - #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9 - #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9 -#else - #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE - #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs... - #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs -#endif - -//Specialization for adaptor without any InnerAlloc -template -class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> - : public OuterAlloc -{ - BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) - public: - - template - struct rebind_base - { - typedef scoped_allocator_adaptor_base - ::template portable_rebind_alloc::type - BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other; - }; - - typedef OuterAlloc outer_allocator_type; - typedef allocator_traits outer_traits_type; - typedef scoped_allocator_adaptor inner_allocator_type; - typedef inner_allocator_type scoped_allocator_type; - typedef allocator_traits inner_traits_type; - typedef typename outer_traits_type:: - propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - typedef typename outer_traits_type:: - propagate_on_container_move_assignment propagate_on_container_move_assignment; - typedef typename outer_traits_type:: - propagate_on_container_swap propagate_on_container_swap; - typedef typename outer_traits_type:: - is_always_equal is_always_equal; - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base() - {} - - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc) - : outer_allocator_type(::boost::forward(outerAlloc)) - {} - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) - : outer_allocator_type(other.outer_allocator()) - {} - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) - : outer_allocator_type(::boost::move(other.outer_allocator())) - {} - - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base - (const scoped_allocator_adaptor_base& other) - : outer_allocator_type(other.outer_allocator()) - {} - - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base - (BOOST_RV_REF_BEG scoped_allocator_adaptor_base BOOST_RV_REF_END other) - : outer_allocator_type(other.outer_allocator()) - {} - - public: - struct internal_type_t{}; - - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &) - : outer_allocator_type(::boost::forward(outerAlloc)) - {} - - public: - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) - { - outer_allocator_type::operator=(other.outer_allocator()); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) - { - outer_allocator_type::operator=(boost::move(other.outer_allocator())); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r) - { - boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); - } - - BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) - { l.swap(r); } - - BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator() - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator() - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const - { - return scoped_allocator_type - (internal_type_t() - ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) - //Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) - //as inner_allocator() is equal to *this and that would trigger an infinite loop - , this->inner_allocator() - ); - } -}; - -} //namespace dtl { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//Scoped allocator -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - -#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - -//! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor. -//! The class template scoped_allocator_adaptor is an allocator template that specifies -//! the memory resource (the outer allocator) to be used by a container (as any other -//! allocator does) and also specifies an inner allocator resource to be passed to -//! the constructor of every element within the container. -//! -//! This adaptor is -//! instantiated with one outer and zero or more inner allocator types. If -//! instantiated with only one allocator type, the inner allocator becomes the -//! scoped_allocator_adaptor itself, thus using the same allocator resource for the -//! container and every element within the container and, if the elements themselves -//! are containers, each of their elements recursively. If instantiated with more than -//! one allocator, the first allocator is the outer allocator for use by the container, -//! the second allocator is passed to the constructors of the container's elements, -//! and, if the elements themselves are containers, the third allocator is passed to -//! the elements' elements, and so on. If containers are nested to a depth greater -//! than the number of allocators, the last allocator is used repeatedly, as in the -//! single-allocator case, for any remaining recursions. -//! -//! [Note: The -//! scoped_allocator_adaptor is derived from the outer allocator type so it can be -//! substituted for the outer allocator type in most expressions. -end note] -//! -//! In the construct member functions, OUTERMOST(x) is x if x does not have -//! an outer_allocator() member function and -//! OUTERMOST(x.outer_allocator()) otherwise; OUTERMOST_ALLOC_TRAITS(x) is -//! allocator_traits. -//! -//! [Note: OUTERMOST(x) and -//! OUTERMOST_ALLOC_TRAITS(x) are recursive operations. It is incumbent upon -//! the definition of outer_allocator() to ensure that the recursion terminates. -//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note] -template -class scoped_allocator_adaptor - -#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - -template -class scoped_allocator_adaptor - -#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - -#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - -template -class scoped_allocator_adaptor -#endif - - : public dtl::scoped_allocator_adaptor_base - -{ - BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor) - - public: - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef dtl::scoped_allocator_adaptor_base - base_type; - typedef typename base_type::internal_type_t internal_type_t; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef OuterAlloc outer_allocator_type; - //! Type: For exposition only - //! - typedef allocator_traits outer_traits_type; - //! Type: scoped_allocator_adaptor if sizeof...(InnerAllocs) is zero; otherwise, - //! scoped_allocator_adaptor. - typedef typename base_type::inner_allocator_type inner_allocator_type; - typedef allocator_traits inner_traits_type; - typedef typename outer_traits_type::value_type value_type; - typedef typename outer_traits_type::size_type size_type; - typedef typename outer_traits_type::difference_type difference_type; - typedef typename outer_traits_type::pointer pointer; - typedef typename outer_traits_type::const_pointer const_pointer; - typedef typename outer_traits_type::void_pointer void_pointer; - typedef typename outer_traits_type::const_void_pointer const_void_pointer; - //! Type: A type with a constant boolean value == true if - //!`allocator_traits:: propagate_on_container_copy_assignment::value` is - //! true for any Allocator in the set of OuterAlloc and InnerAllocs..., false otherwise. - typedef typename base_type:: - propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - //! Type: A type with a constant boolean value == true if - //!`allocator_traits:: propagate_on_container_move_assignment::value` is - //! true for any Allocator in the set of OuterAlloc and InnerAllocs..., false otherwise. - typedef typename base_type:: - propagate_on_container_move_assignment propagate_on_container_move_assignment; - - //! Type: A type with a constant boolean value == true if - //! `allocator_traits:: propagate_on_container_swap::value` is - //! true for any Allocator in the set of OuterAlloc and InnerAllocs..., false otherwise. - typedef typename base_type:: - propagate_on_container_swap propagate_on_container_swap; - - //! Type: A type with a constant boolean value == true if - //!`allocator_traits:: is_always_equal::value` is - //! true for all Allocator in the set of OuterAlloc and InnerAllocs..., false otherwise. - typedef typename base_type:: - is_always_equal is_always_equal; - - //! Type: Rebinds scoped allocator to - //! typedef scoped_allocator_adaptor - //! < typename outer_traits_type::template portable_rebind_alloc::type - //! , InnerAllocs... > - template - struct rebind - { - typedef scoped_allocator_adaptor - < typename outer_traits_type::template portable_rebind_alloc::type - , BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other; - }; - - //! Effects: value-initializes the OuterAlloc base class - //! and the inner allocator object. - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor() - {} - - BOOST_CONTAINER_FORCEINLINE ~scoped_allocator_adaptor() - {} - - //! Effects: initializes each allocator within the adaptor with - //! the corresponding allocator from other. - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor& other) - : base_type(other.base()) - {} - - //! Effects: move constructs each allocator within the adaptor with - //! the corresponding allocator from other. - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other) - : base_type(::boost::move(other.base())) - {} - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Requires: OuterAlloc shall be constructible from OuterA2. - //! - //! Effects: initializes the OuterAlloc base class with boost::forward(outerAlloc) and inner - //! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the - //! corresponding allocator from the argument list). - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs) - : base_type(::boost::forward(outerAlloc), innerAllocs...) - {} - #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\ - template \ - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\ - : base_type(::boost::forward(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\ - {}\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE) - #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE - - #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Requires: OuterAlloc shall be constructible from OuterA2. - //! - //! Effects: initializes each allocator within the adaptor with the corresponding allocator from other. - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor &other) - : base_type(other.base()) - {} - - //! Requires: OuterAlloc shall be constructible from OuterA2. - //! - //! Effects: initializes each allocator within the adaptor with the corresponding allocator - //! rvalue from other. - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor - BOOST_RV_REF_END other) - : base_type(::boost::move(other.base())) - {} - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other) - { return static_cast(base_type::operator=(static_cast(other))); } - - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) - { return static_cast(base_type::operator=(boost::move(other.base()))); } - - #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - //! Effects: swaps *this with r. - //! - void swap(scoped_allocator_adaptor &r); - - //! Effects: swaps *this with r. - //! - friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r); - - //! Returns: - //! static_cast(*this). - outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Returns: - //! static_cast(*this). - const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! Returns: - //! *this if sizeof...(InnerAllocs) is zero; otherwise, inner. - inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW; - - //! Returns: - //! *this if sizeof...(InnerAllocs) is zero; otherwise, inner. - inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; - - #endif //BOOST_CONTAINER_DOXYGEN_INVOKED - - //! Returns: - //! allocator_traits:: max_size(outer_allocator()). - BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return outer_traits_type::max_size(this->outer_allocator()); } - - //! Effects: - //! calls OUTERMOST_ALLOC_TRAITS(*this):: destroy(OUTERMOST(*this), p). - template - BOOST_CONTAINER_FORCEINLINE void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW - { - allocator_traits::type> - ::destroy(get_outermost_allocator(this->outer_allocator()), p); - } - - //! Returns: - //! allocator_traits::allocate(outer_allocator(), n). - BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n) - { return outer_traits_type::allocate(this->outer_allocator(), n); } - - //! Returns: - //! allocator_traits::allocate(outer_allocator(), n, hint). - BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n, const_void_pointer hint) - { return outer_traits_type::allocate(this->outer_allocator(), n, hint); } - - //! Effects: - //! allocator_traits::deallocate(outer_allocator(), p, n). - BOOST_CONTAINER_FORCEINLINE void deallocate(pointer p, size_type n) - { outer_traits_type::deallocate(this->outer_allocator(), p, n); } - - #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - //! Returns: A new scoped_allocator_adaptor object where each allocator - //! Allocator in the adaptor is initialized from the result of calling - //! allocator_traits::select_on_container_copy_construction() on - //! the corresponding allocator in *this. - scoped_allocator_adaptor select_on_container_copy_construction() const; - #endif //BOOST_CONTAINER_DOXYGEN_INVOKED - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - BOOST_CONTAINER_FORCEINLINE base_type &base() { return *this; } - - BOOST_CONTAINER_FORCEINLINE const base_type &base() const { return *this; } - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: - //! 1) If uses_allocator::value is false calls - //! OUTERMOST_ALLOC_TRAITS(*this):: - //! construct(OUTERMOST(*this), p, std::forward(args)...). - //! - //! 2) Otherwise, if uses_allocator::value is true and - //! is_constructible:: value is true, calls - //! OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p, allocator_arg, - //! inner_allocator(), std::forward(args)...). - //! - //! [Note: In compilers without advanced decltype SFINAE support, is_constructible can't - //! be implemented so that condition will be replaced by - //! constructible_with_allocator_prefix::value. -end note] - //! - //! 3) Otherwise, if uses_allocator::value is true and - //! is_constructible:: value is true, calls - //! OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p, - //! std::forward(args)..., inner_allocator()). - //! - //! [Note: In compilers without advanced decltype SFINAE support, is_constructible can't be - //! implemented so that condition will be replaced by - //! constructible_with_allocator_suffix:: value. -end note] - //! - //! 4) Otherwise, the program is ill-formed. - //! - //! [Note: An error will result if uses_allocator evaluates - //! to true but the specific constructor does not take an allocator. This definition prevents a silent - //! failure to pass an inner allocator to a contained element. -end note] - template < typename T, class ...Args> - BOOST_CONTAINER_FORCEINLINE void construct(T* p, BOOST_FWD_REF(Args)...args) - { - dtl::dispatch_uses_allocator - ( (get_outermost_allocator)(this->outer_allocator()) - , this->inner_allocator(), p, ::boost::forward(args)...); - } - - #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //Disable this overload if the first argument is pair as some compilers have - //overload selection problems when the first parameter is a pair. - #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \ - template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ - BOOST_CONTAINER_FORCEINLINE void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ - {\ - dtl::dispatch_uses_allocator\ - ( (get_outermost_allocator)(this->outer_allocator())\ - , this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE) - #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE - - #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - //Internal function - template - BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner) - : base_type(internal_type_t(), ::boost::forward(outer), inner) - {} - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -/// @cond - -template -struct scoped_allocator_operator_equal -{ - //Optimize equal outer allocator types with - //allocator_traits::equal which uses is_always_equal - template - BOOST_CONTAINER_FORCEINLINE static bool equal_outer(const IA &l, const IA &r) - { return allocator_traits::equal(l, r); } - - //Otherwise compare it normally - template - BOOST_CONTAINER_FORCEINLINE static bool equal_outer(const IA1 &l, const IA2 &r) - { return l == r; } - - //Otherwise compare it normally - template - BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA &l, const IA &r) - { return allocator_traits::equal(l, r); } -}; - -template<> -struct scoped_allocator_operator_equal - : scoped_allocator_operator_equal -{ - //when inner allocator count is zero, - //inner_allocator_type is the same as outer_allocator_type - //so both types can be different in operator== - template - BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA1 &, const IA2 &) - { return true; } -}; - -/// @endcond - -template -BOOST_CONTAINER_FORCEINLINE bool operator==(const scoped_allocator_adaptor& a - ,const scoped_allocator_adaptor& b) -{ - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - const bool has_zero_inner = sizeof...(InnerAllocs) == 0u; - #else - const bool has_zero_inner = boost::container::dtl::is_same::value; - #endif - typedef scoped_allocator_operator_equal equal_t; - return equal_t::equal_outer(a.outer_allocator(), b.outer_allocator()) && - equal_t::equal_inner(a.inner_allocator(), b.inner_allocator()); -} - -template -BOOST_CONTAINER_FORCEINLINE bool operator!=(const scoped_allocator_adaptor& a - ,const scoped_allocator_adaptor& b) -{ return !(a == b); } - -}} // namespace boost { namespace container { - -#include - -#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP diff --git a/inst/i/b/container/scoped_allocator_fwd.hpp b/inst/i/b/container/scoped_allocator_fwd.hpp deleted file mode 100644 index 23709f633..000000000 --- a/inst/i/b/container/scoped_allocator_fwd.hpp +++ /dev/null @@ -1,71 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2015-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) -// -// See http://www.boost.org/libs/container for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP -#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP - -//! \file -//! This header file forward declares boost::container::scoped_allocator_adaptor - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -#include -#include - -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif - -namespace boost { namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - - template - class scoped_allocator_adaptor; - - #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - - template - class scoped_allocator_adaptor; - - template - class scoped_allocator_adaptor; - - #endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - -#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - template - class scoped_allocator_adaptor; - -#endif - - -#else //BOOST_CONTAINER_DOXYGEN_INVOKED - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -}} // namespace boost { namespace container { - -#include - -#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP diff --git a/inst/i/b/container/set.hpp b/inst/i/b/container/set.hpp deleted file mode 100644 index e795d82b3..000000000 --- a/inst/i/b/container/set.hpp +++ /dev/null @@ -1,1695 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2005-2013. 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_SET_HPP -#define BOOST_CONTAINER_SET_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -// container -#include -// container/detail -#include -#include -#include //new_allocator -// intrusive/detail -#include //pair -#include //less, equal -// move -#include -#include -// move/detail -#include -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -// std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -namespace boost { -namespace container { - -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! A set is a kind of associative container that supports unique keys (contains at -//! most one of each key value) and provides for fast retrieval of the keys themselves. -//! Class set supports bidirectional iterators. -//! -//! A set satisfies all of the requirements of a container and of a reversible container -//! , and of an associative container. A set also provides most operations described in -//! for unique keys. -//! -//! \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 Options is an packed option type generated using using boost::container::tree_assoc_options. -template , class Allocator = new_allocator, class Options = void> -#else -template -#endif -class set - ///@cond - : public dtl::tree - < Key, void, Compare, Allocator, Options> - ///@endcond -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(set) - typedef dtl::tree - < Key, void, Compare, Allocator, Options> base_t; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef key_compare value_compare; - typedef typename base_t::allocator_type allocator_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - 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; - - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructs an empty set. - //! - //! Complexity: Constant. - - BOOST_CONTAINER_FORCEINLINE set() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value && - dtl::is_nothrow_default_constructible::value) - : base_t() - {} - - //! Effects: Constructs an empty set using the specified allocator object. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit set(const allocator_type& a) - : base_t(a) - {} - - //! Effects: Constructs an empty set using the specified comparison object. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit set(const Compare& comp) - : base_t(comp) - {} - - //! Effects: Constructs an empty set using the specified comparison object - //! and allocator. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE set(const Compare& comp, const allocator_type& a) - : base_t(comp, a) - {} - - //! Effects: Constructs an empty set using and - //! inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last) - : base_t(true, first, last) - {} - - //! Effects: Constructs an empty set using the specified - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const allocator_type& a) - : base_t(true, first, last, key_compare(), a) - {} - - //! Effects: Constructs an empty set using the specified comparison object and - //! inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp) - : base_t(true, first, last, comp) - {} - - //! Effects: Constructs an empty set using the specified comparison object and - //! allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! the predicate and otherwise N logN, where N is last - first. - template - BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : base_t(true, first, last, comp, a) - {} - - //! Effects: Constructs an empty set and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last) - : base_t(ordered_range, first, last) - {} - - //! Effects: Constructs an empty set using the specified comparison object and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp ) - : base_t(ordered_range, first, last, comp) - {} - - //! Effects: Constructs an empty set using the specified comparison object and - //! allocator, and inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last - , const Compare& comp, const allocator_type& a) - : base_t(ordered_range, first, last, comp, a) - {} - - //! Effects: Constructs an empty set using the specified allocator and - //! inserts elements from the ordered unique range [first ,last). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE set(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) - : base_t(ordered_range, first, last, Compare(), a) - {} - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs an empty set and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is il.begin() - il.end(). - BOOST_CONTAINER_FORCEINLINE set(std::initializer_list il) - : base_t(true, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty set using the specified - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is il.begin() - il.end(). - BOOST_CONTAINER_FORCEINLINE set(std::initializer_list il, const allocator_type& a) - : base_t(true, il.begin(), il.end(), Compare(), a) - {} - - //! Effects: Constructs an empty set using the specified comparison object and - //! inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is il.begin() - il.end(). - BOOST_CONTAINER_FORCEINLINE set(std::initializer_list il, const Compare& comp ) - : base_t(true, il.begin(), il.end(), comp) - {} - - //! Effects: Constructs an empty set using the specified comparison object and - //! allocator, and inserts elements from the range [il.begin(), il.end()). - //! - //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using - //! the predicate and otherwise N logN, where N is il.begin() - il.end(). - BOOST_CONTAINER_FORCEINLINE set(std::initializer_list il, const Compare& comp, const allocator_type& a) - : base_t(true, il.begin(), il.end(), comp, a) - {} - - //! Effects: Constructs an empty set 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list il) - : base_t(ordered_range, il.begin(), il.end()) - {} - - //! Effects: Constructs an empty set using the specified comparison object 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list il, const Compare& comp) - : base_t(ordered_range, il.begin(), il.end(), comp) - {} - - //! Effects: Constructs an empty set 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. - //! - //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be - //! unique values. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list il, const Compare& comp, const allocator_type& a) - : base_t(ordered_range, il.begin(), il.end(), comp, a) - {} -#endif - - //! Effects: Copy constructs a set. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE set(const set& x) - : base_t(static_cast(x)) - {} - - //! Effects: Move constructs a set. Constructs *this using x's resources. - //! - //! Complexity: Constant. - //! - //! Postcondition: x is emptied. - BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : base_t(BOOST_MOVE_BASE(base_t, x)) - {} - - //! Effects: Copy constructs a set using the specified allocator. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE set(const set& x, const allocator_type &a) - : base_t(static_cast(x), a) - {} - - //! Effects: Move constructs a set using the specified allocator. - //! Constructs *this using x's resources. - //! - //! Complexity: Constant if a == x.get_allocator(), linear otherwise. - BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x, const allocator_type &a) - : base_t(BOOST_MOVE_BASE(base_t, x), a) - {} - - //! Effects: Makes *this a copy of x. - //! - //! Complexity: Linear in x.size(). - BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_COPY_ASSIGN_REF(set) x) - { return static_cast(this->base_t::operator=(static_cast(x))); } - - //! Effects: this->swap(x.get()). - //! - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or value_type's move constructor throws) - //! - //! Complexity: Constant if allocator_traits_type:: - //! propagate_on_container_move_assignment is true or - //! this->get>allocator() == x.get_allocator(). Linear otherwise. - BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_RV_REF(set) x) - BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value || - allocator_traits_type::is_always_equal::value) && - boost::container::dtl::is_nothrow_move_assignable::value) - { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Copy all elements from il to *this. - //! - //! Complexity: Linear in il.size(). - set& operator=(std::initializer_list il) - { - this->clear(); - insert(il.begin(), il.end()); - return *this; - } -#endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Returns a copy of the allocator that - //! was passed to the object's constructor. - //! - //! Complexity: Constant. - allocator_type get_allocator() const; - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator(); - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const; - - //! Effects: Returns an iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant - iterator begin(); - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator begin() const; - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cbegin() const; - - //! Effects: Returns an iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator end(); - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator end() const; - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const; - - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rbegin(); - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator rbegin() const; - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crbegin() const; - - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rend(); - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator rend() const; - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crend() const; - - //! Effects: Returns true if the container contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - bool empty() const; - - //! Effects: Returns the number of the elements contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type size() const; - - //! Effects: Returns the largest possible size of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type max_size() const; - #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object x of type Key constructed with - //! std::forward(args)... if and only if there is - //! no element in the container with equivalent value. - //! and returns the iterator pointing to the - //! newly inserted element. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Throws: If memory allocation throws or - //! Key's in-place constructor throws. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_FORCEINLINE std::pair emplace(BOOST_FWD_REF(Args)... args) - { return this->base_t::emplace_unique(boost::forward(args)...); } - - //! Effects: Inserts an object of type Key constructed with - //! std::forward(args)... if and only if there is - //! no element in the container with equivalent value. - //! p is a hint pointing to where the insert - //! should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args) - { return this->base_t::emplace_hint_unique(p, boost::forward(args)...); } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_SET_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE std::pair emplace(BOOST_MOVE_UREF##N)\ - { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SET_EMPLACE_CODE) - #undef BOOST_CONTAINER_SET_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts x if and only if there is no element in the container - //! with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - std::pair insert(const value_type &x); - - //! Effects: Move constructs a new value from x if and only if there is - //! no element in the container with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - std::pair insert(value_type &&x); - #else - private: - typedef std::pair insert_return_pair; - public: - BOOST_MOVE_CONVERSION_AWARE_CATCH - (insert, value_type, insert_return_pair, this->base_t::insert_unique_convertible) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(const_iterator p, const value_type &x); - - //! Effects: Inserts an element move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - iterator insert(const_iterator p, value_type &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG - (insert, value_type, iterator, this->base_t::insert_unique_hint_convertible, const_iterator, const_iterator) - #endif - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - template - BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->base_t::insert_unique_range(first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: inserts each element from the range [il.begin(),il.end()) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: At most N log(size()+N) (N is the distance from il.begin() to il.end()) - BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list il) - { this->base_t::insert_unique_range(il.begin(), il.end()); } -#endif - - //! @copydoc ::boost::container::map::insert(node_type&&) - BOOST_CONTAINER_FORCEINLINE 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&&) - BOOST_CONTAINER_FORCEINLINE 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&) - template - BOOST_CONTAINER_FORCEINLINE void merge(set& source) - { - typedef dtl::tree - base2_t; - this->base_t::merge_unique(static_cast(source)); - } - - //! @copydoc ::boost::container::set::merge(set&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! @copydoc ::boost::container::map::merge(multimap&) - template - BOOST_CONTAINER_FORCEINLINE void merge(multiset& source) - { - typedef dtl::tree - base2_t; - this->base_t::merge_unique(static_cast(source)); - } - - //! @copydoc ::boost::container::set::merge(multiset&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! Effects: If present, erases the element in the container with key equivalent to x. - //! - //! Returns: Returns the number of erased elements (0/1). - //! - //! Complexity: log(size()) + count(k) - BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x) - { return this->base_t::erase_unique(x); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Erases the element pointed to by p. - //! - //! Returns: Returns an iterator pointing to the element immediately - //! following q prior to the element being erased. If no such element exists, - //! returns end(). - //! - //! Complexity: Amortized constant time - iterator erase(const_iterator p); - - //! Effects: Erases all the elements in the range [first, last). - //! - //! Returns: Returns last. - //! - //! Complexity: log(size())+N where N is the distance from first to last. - iterator erase(const_iterator first, const_iterator last); - - //! @copydoc ::boost::container::map::extract(const_iterator) - node_type extract(const_iterator p); - - //! @copydoc ::boost::container::map::extract(const key_type&) - node_type extract(const key_type& x); - - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(set& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - //! Effects: erase(begin(),end()). - //! - //! Postcondition: size() == 0. - //! - //! Complexity: linear in size(). - void clear(); - - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const; - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const; - - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - iterator find(const key_type& x); - - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - const_iterator find(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - iterator find(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - template - const_iterator find(const K& x) const; - - #else - using base_t::erase; - #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type count(const key_type& x) const - { return static_cast(this->base_t::find(x) != this->base_t::cend()); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - template - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type count(const K& x) const - { return static_cast(this->find(x) != this->cend()); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - bool contains(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: Returns true if there is an element with key - //! equivalent to key in the container, otherwise false. - //! - //! Complexity: log(size()). - template - bool contains(const K& x) const; - - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator lower_bound(const key_type& x); - - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator lower_bound(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - iterator lower_bound(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - const_iterator lower_bound(const K& x) const; - - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator upper_bound(const key_type& x); - - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator upper_bound(const key_type& x) const; - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: An iterator pointing to the first element with key greater - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - iterator upper_bound(const K& x); - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Returns: A const iterator pointing to the first element with key - //! greater than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - template - const_iterator upper_bound(const K& x) const; - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_FORCEINLINE std::pair equal_range(const key_type& x) - { return this->base_t::lower_bound_range(x); } - - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - BOOST_CONTAINER_FORCEINLINE std::pair equal_range(const key_type& x) const - { return this->base_t::lower_bound_range(x); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - BOOST_CONTAINER_FORCEINLINE std::pair equal_range(const K& x) - { return this->base_t::lower_bound_range(x); } - - //! Requires: This overload is available only if - //! key_compare::is_transparent exists. - //! - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - template - BOOST_CONTAINER_FORCEINLINE std::pair equal_range(const K& x) const - { return this->base_t::lower_bound_range(x); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Rebalances the tree. It's a no-op for Red-Black and AVL trees. - //! - //! Complexity: Linear - void rebalance(); - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const set& x, const set& y); - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const set& x, const set& y); - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const set& x, const set& y); - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const set& x, const set& y); - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<=(const set& x, const set& y); - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>=(const set& x, const set& y); - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - friend void swap(set& x, set& y) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -set(InputIterator, InputIterator) -> - set< it_based_value_type_t >; - -template < typename InputIterator, typename AllocatorOrCompare> - set(InputIterator, InputIterator, AllocatorOrCompare const&) -> - set< it_based_value_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -set(InputIterator, InputIterator, Compare const&, Allocator const&) -> - set< it_based_value_type_t - , Compare - , Allocator>; - -template -set(ordered_unique_range_t, InputIterator, InputIterator) -> - set< it_based_value_type_t>; - - -template < typename InputIterator, typename AllocatorOrCompare> - set(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> - set< it_based_value_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - set< it_based_value_type_t - , Compare - , Allocator>; - -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef ::boost::container::dtl::tree tree; - static const bool value = ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! A multiset is a kind of associative container that supports equivalent keys -//! (possibly contains multiple copies of the same key value) and provides for -//! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators. -//! -//! A multiset satisfies all of the requirements of a container and of a reversible -//! container, and of an associative container). multiset also provides most operations -//! described for duplicate keys. -//! -//! \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 Options is an packed option type generated using using boost::container::tree_assoc_options. -template , class Allocator = new_allocator, class Options = tree_assoc_defaults > -#else -template -#endif -class multiset - /// @cond - : public dtl::tree - - /// @endcond -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(multiset) - typedef dtl::tree - base_t; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef key_compare value_compare; - typedef typename base_t::allocator_type allocator_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - 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; - - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! @copydoc ::boost::container::set::set() - BOOST_CONTAINER_FORCEINLINE multiset() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value && - dtl::is_nothrow_default_constructible::value) - : base_t() - {} - - //! @copydoc ::boost::container::set::set(const allocator_type&) - BOOST_CONTAINER_FORCEINLINE explicit multiset(const allocator_type& a) - : base_t(a) - {} - - //! @copydoc ::boost::container::set::set(const Compare&) - BOOST_CONTAINER_FORCEINLINE explicit multiset(const Compare& comp) - : base_t(comp) - {} - - //! @copydoc ::boost::container::set::set(const Compare&, const allocator_type&) - BOOST_CONTAINER_FORCEINLINE multiset(const Compare& comp, const allocator_type& a) - : base_t(comp, a) - {} - - //! @copydoc ::boost::container::set::set(InputIterator, InputIterator) - template - BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last) - : base_t(false, first, last) - {} - - //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const allocator_type&) - template - BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const allocator_type& a) - : base_t(false, first, last, key_compare(), a) - {} - - //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare&) - template - BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp) - : base_t(false, first, last, comp) - {} - - //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare&, const allocator_type&) - template - BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : base_t(false, first, last, comp, a) - {} - - //! Effects: Constructs an empty multiset and - //! and inserts elements from the ordered range [first ,last ). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last ) - : base_t(ordered_range, first, last) - {} - - //! Effects: Constructs an empty multiset using the specified comparison object and - //! inserts elements from the ordered range [first ,last ). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp) - : base_t(ordered_range, first, last, comp) - {} - - //! Effects: Constructs an empty multiset using the specified comparison object and - //! allocator, and inserts elements from the ordered range [first ,last ). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a) - : base_t(ordered_range, first, last, comp, a) - {} - - //! Effects: Constructs an empty multiset using the specified allocator and - //! inserts elements from the ordered range [first ,last ). This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Requires: [first ,last) must be ordered according to the predicate. - //! - //! Complexity: Linear in N. - //! - //! Note: Non-standard extension. - template - BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a) - : base_t(ordered_range, first, last, Compare(), a) - {} - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! @copydoc ::boost::container::set::set(std::initializer_list) - BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list il) - : base_t(false, il.begin(), il.end()) - {} - - //! @copydoc ::boost::container::set::set(std::initializer_list, const allocator_type&) - BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list il, const allocator_type& a) - : base_t(false, il.begin(), il.end(), Compare(), a) - {} - - //! @copydoc ::boost::container::set::set(std::initializer_list, const Compare&) - BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list il, const Compare& comp) - : base_t(false, il.begin(), il.end(), comp) - {} - - //! @copydoc ::boost::container::set::set(std::initializer_list, const Compare&, const allocator_type&) - BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list il, const Compare& comp, const allocator_type& a) - : base_t(false, il.begin(), il.end(), comp, a) - {} - - //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list) - BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list il) - : base_t(ordered_range, il.begin(), il.end()) - {} - - //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list, const Compare&) - BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list il, const Compare& comp) - : base_t(ordered_range, il.begin(), il.end(), comp) - {} - - //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list, const Compare&, const allocator_type&) - BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list il, const Compare& comp, const allocator_type& a) - : base_t(ordered_range, il.begin(), il.end(), comp, a) - {} -#endif - - //! @copydoc ::boost::container::set::set(const set &) - BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x) - : base_t(static_cast(x)) - {} - - //! @copydoc ::boost::container::set::set(set &&) - BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : base_t(BOOST_MOVE_BASE(base_t, x)) - {} - - //! @copydoc ::boost::container::set::set(const set &, const allocator_type &) - BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x, const allocator_type &a) - : base_t(static_cast(x), a) - {} - - //! @copydoc ::boost::container::set::set(set &&, const allocator_type &) - BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x, const allocator_type &a) - : base_t(BOOST_MOVE_BASE(base_t, x), a) - {} - - //! @copydoc ::boost::container::set::operator=(const set &) - BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x) - { return static_cast(this->base_t::operator=(static_cast(x))); } - - //! @copydoc ::boost::container::set::operator=(set &&) - BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_RV_REF(multiset) x) - BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value || - allocator_traits_type::is_always_equal::value) && - boost::container::dtl::is_nothrow_move_assignable::value) - { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! @copydoc ::boost::container::set::operator=(std::initializer_list) - multiset& operator=(std::initializer_list il) - { - this->clear(); - insert(il.begin(), il.end()); - return *this; - } -#endif - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! @copydoc ::boost::container::set::get_allocator() - allocator_type get_allocator() const; - - //! @copydoc ::boost::container::set::get_stored_allocator() - stored_allocator_type &get_stored_allocator(); - - //! @copydoc ::boost::container::set::get_stored_allocator() const - const stored_allocator_type &get_stored_allocator() const; - - //! @copydoc ::boost::container::set::begin() - iterator begin(); - - //! @copydoc ::boost::container::set::begin() const - const_iterator begin() const; - - //! @copydoc ::boost::container::set::cbegin() const - const_iterator cbegin() const; - - //! @copydoc ::boost::container::set::end() - iterator end() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::end() const - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::cend() const - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::rbegin() - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::rbegin() const - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::crbegin() const - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::rend() - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::rend() const - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::crend() const - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::empty() const - bool empty() const; - - //! @copydoc ::boost::container::set::size() const - size_type size() const; - - //! @copydoc ::boost::container::set::max_size() const - size_type max_size() const; - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type Key constructed with - //! std::forward(args)... and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args) - { return this->base_t::emplace_equal(boost::forward(args)...); } - - //! Effects: Inserts an object of type Key constructed with - //! std::forward(args)... - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - template - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args) - { return this->base_t::emplace_hint_equal(p, boost::forward(args)...); } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_MULTISET_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\ - { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTISET_EMPLACE_CODE) - #undef BOOST_CONTAINER_MULTISET_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts x and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic. - iterator insert(const value_type &x); - - //! Effects: Inserts a copy of x in the container. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(value_type &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->base_t::insert_equal_convertible) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(const_iterator p, const value_type &x); - - //! Effects: Inserts a value move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(const_iterator p, value_type &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG - (insert, value_type, iterator, this->base_t::insert_equal_hint_convertible, const_iterator, const_iterator) - #endif - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) . - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - template - BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->base_t::insert_equal_range(first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! @copydoc ::boost::container::set::insert(std::initializer_list) - BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list il) - { this->base_t::insert_equal_range(il.begin(), il.end()); } -#endif - - //! @copydoc ::boost::container::multimap::insert(node_type&&) - BOOST_CONTAINER_FORCEINLINE 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&&) - BOOST_CONTAINER_FORCEINLINE 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&) - template - BOOST_CONTAINER_FORCEINLINE void merge(multiset& source) - { - typedef dtl::tree - base2_t; - this->base_t::merge_equal(static_cast(source)); - } - - //! @copydoc ::boost::container::multiset::merge(multiset&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - //! @copydoc ::boost::container::multimap::merge(map&) - template - BOOST_CONTAINER_FORCEINLINE void merge(set& source) - { - typedef dtl::tree - base2_t; - this->base_t::merge_equal(static_cast(source)); - } - - //! @copydoc ::boost::container::multiset::merge(set&) - template - BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set BOOST_RV_REF_END source) - { return this->merge(static_cast&>(source)); } - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! @copydoc ::boost::container::set::erase(const_iterator) - iterator erase(const_iterator p); - - //! @copydoc ::boost::container::set::erase(const key_type&) - size_type erase(const key_type& x); - - //! @copydoc ::boost::container::set::erase(const_iterator,const_iterator) - iterator erase(const_iterator first, const_iterator last); - - //! @copydoc ::boost::container::multimap::extract(const_iterator) - node_type extract(const_iterator p); - - //! @copydoc ::boost::container::multimap::extract(const key_type&) - node_type extract(const key_type& x); - - //! @copydoc ::boost::container::set::swap - void swap(multiset& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - //! @copydoc ::boost::container::set::clear - void clear() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @copydoc ::boost::container::set::key_comp - key_compare key_comp() const; - - //! @copydoc ::boost::container::set::value_comp - value_compare value_comp() const; - - //! @copydoc ::boost::container::set::find(const key_type& ) - iterator find(const key_type& x); - - //! @copydoc ::boost::container::set::find(const key_type& ) const - const_iterator find(const key_type& x) const; - - //! @copydoc ::boost::container::set::find(const K& ) - template - iterator find(const K& x); - - //! @copydoc ::boost::container::set::find(const K& ) - template - const_iterator find(const K& x) const; - - //! @copydoc ::boost::container::set::count(const key_type& ) const - size_type count(const key_type& x) const; - - //! @copydoc ::boost::container::set::count(const K& ) const - template - size_type count(const K& x) const; - - //! @copydoc ::boost::container::set::contains(const key_type& ) const - bool contains(const key_type& x) const; - - //! @copydoc ::boost::container::set::contains(const K& ) const - template - bool contains(const K& x) const; - - //! @copydoc ::boost::container::set::lower_bound(const key_type& ) - iterator lower_bound(const key_type& x); - - //! @copydoc ::boost::container::set::lower_bound(const key_type& ) const - const_iterator lower_bound(const key_type& x) const; - - //! @copydoc ::boost::container::set::lower_bound(const K& ) - template - iterator lower_bound(const K& x); - - //! @copydoc ::boost::container::set::lower_bound(const K& ) const - template - const_iterator lower_bound(const K& x) const; - - //! @copydoc ::boost::container::set::upper_bound(const key_type& ) - iterator upper_bound(const key_type& x); - - //! @copydoc ::boost::container::set::upper_bound(const key_type& ) const - const_iterator upper_bound(const key_type& x) const; - - //! @copydoc ::boost::container::set::upper_bound(const K& ) - template - iterator upper_bound(const K& x); - - //! @copydoc ::boost::container::set::upper_bound(const K& ) const - template - const_iterator upper_bound(const K& x) const; - - //! @copydoc ::boost::container::set::equal_range(const key_type& ) const - std::pair equal_range(const key_type& x) const; - - //! @copydoc ::boost::container::set::equal_range(const key_type& ) - std::pair equal_range(const key_type& x); - - //! @copydoc ::boost::container::set::equal_range(const K& ) const - template - std::pair equal_range(const K& x) const; - - //! @copydoc ::boost::container::set::equal_range(const K& ) - template - std::pair equal_range(const K& x); - - //! @copydoc ::boost::container::set::rebalance() - void rebalance(); - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const multiset& x, const multiset& y); - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const multiset& x, const multiset& y); - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const multiset& x, const multiset& y); - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const multiset& x, const multiset& y); - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator<=(const multiset& x, const multiset& y); - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator>=(const multiset& x, const multiset& y); - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - friend void swap(multiset& x, multiset& y) - BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable::value ); - - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -multiset(InputIterator, InputIterator) -> - multiset< it_based_value_type_t >; - - -template < typename InputIterator, typename AllocatorOrCompare> -multiset(InputIterator, InputIterator, AllocatorOrCompare const&) -> - multiset < it_based_value_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> - multiset< it_based_value_type_t - , Compare - , Allocator>; - -template -multiset(ordered_range_t, InputIterator, InputIterator) -> - multiset< it_based_value_type_t>; - -template < typename InputIterator, typename AllocatorOrCompare> -multiset(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> - multiset < it_based_value_type_t - , typename dtl::if_c< // Compare - dtl::is_allocator::value - , std::less> - , AllocatorOrCompare - >::type - , typename dtl::if_c< // Allocator - dtl::is_allocator::value - , AllocatorOrCompare - , new_allocator> - >::type - >; - -template < typename InputIterator, typename Compare, typename Allocator - , typename = dtl::require_nonallocator_t - , typename = dtl::require_allocator_t> -multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> - multiset< it_based_value_type_t - , Compare - , Allocator>; - -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef ::boost::container::dtl::tree tree; - static const bool value = ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -}} - -#include - -#endif // BOOST_CONTAINER_SET_HPP diff --git a/inst/i/b/container/slist.hpp b/inst/i/b/container/slist.hpp deleted file mode 100644 index 519698886..000000000 --- a/inst/i/b/container/slist.hpp +++ /dev/null @@ -1,1724 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2004-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) -// -// See http://www.boost.org/libs/container for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_CONTAINER_SLIST_HPP -#define BOOST_CONTAINER_SLIST_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include - -// container -#include -#include //new_allocator -#include -// container/detail -#include //algo_equal(), algo_lexicographical_compare -#include -#include -#include -#include -#include -#include -#include -// intrusive -#include -#include -// move -#include -#include -#include -// move/detail -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -#include -#include -// std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -namespace boost { -namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -template -class slist; - -namespace dtl { - -template -struct slist_hook -{ - typedef typename dtl::bi::make_slist_base_hook - , dtl::bi::link_mode >::type type; -}; - -template -struct iiterator_node_value_type< base_node > > -{ - typedef T type; -}; - -template -struct intrusive_slist_type -{ - typedef boost::container::allocator_traits allocator_traits_type; - typedef typename allocator_traits_type::value_type value_type; - typedef typename boost::intrusive::pointer_traits - ::template - rebind_pointer::type - void_pointer; - typedef base_node > node_type; - - typedef typename dtl::bi::make_slist - ::type> - ,dtl::bi::constant_time_size - , dtl::bi::size_type - - >::type container_type; - typedef container_type type ; -}; - -} //namespace dtl { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! An slist is a singly linked list: a list where each element is linked to the next -//! element, but not to the previous element. That is, it is a Sequence that -//! supports forward but not backward traversal, and (amortized) constant time -//! insertion and removal of elements. Slists, like lists, have the important -//! property that insertion and splicing do not invalidate iterators to list elements, -//! and that even removal invalidates only the iterators that point to the elements -//! that are removed. The ordering of iterators may be changed (that is, -//! slist::iterator might have a different predecessor or successor after a list -//! operation than it did before), but the iterators themselves will not be invalidated -//! or made to point to different elements unless that invalidation or mutation is explicit. -//! -//! The main difference between slist and list is that list's iterators are bidirectional -//! iterators, while slist's iterators are forward iterators. This means that slist is -//! less versatile than list; frequently, however, bidirectional iterators are -//! unnecessary. You should usually use slist unless you actually need the extra -//! functionality of list, because singly linked lists are smaller and faster than double -//! linked lists. -//! -//! Important performance note: like every other Sequence, slist defines the member -//! functions insert and erase. Using these member functions carelessly, however, can -//! result in disastrously slow programs. The problem is that insert's first argument is -//! an iterator p, and that it inserts the new element(s) before p. This means that -//! insert must find the iterator just before p; this is a constant-time operation -//! for list, since list has bidirectional iterators, but for slist it must find that -//! iterator by traversing the list from the beginning up to p. In other words: -//! insert and erase are slow operations anywhere but near the beginning of the slist. -//! -//! Slist provides the member functions insert_after and erase_after, which are constant -//! time operations: you should always use insert_after and erase_after whenever -//! possible. If you find that insert_after and erase_after aren't adequate for your -//! needs, and that you often need to use insert and erase in the middle of the list, -//! then you should probably use list instead of slist. -//! -//! \tparam T The type of object that is stored in the list -//! \tparam Allocator The allocator used for all internal memory management, use void -//! for the default allocator -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template -#else -template -#endif -class slist - : protected dtl::node_alloc_holder - < typename real_allocator::type - , typename dtl::intrusive_slist_type::type>::type> -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef typename real_allocator::type ValueAllocator; - typedef typename - dtl::intrusive_slist_type::type Icont; - typedef dtl::node_alloc_holder AllocHolder; - typedef typename AllocHolder::NodePtr NodePtr; - typedef typename AllocHolder::NodeAlloc NodeAlloc; - typedef typename AllocHolder::ValAlloc ValAlloc; - typedef typename AllocHolder::Node Node; - typedef dtl::allocator_node_destroyer Destroyer; - typedef typename AllocHolder::alloc_version alloc_version; - typedef boost::container:: - allocator_traits allocator_traits_type; - typedef boost::container::equal_to_value - equal_to_value_type; - - BOOST_COPYABLE_AND_MOVABLE(slist) - typedef dtl::iterator_from_iiterator iterator_impl; - typedef dtl::iterator_from_iiterator const_iterator_impl; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - - typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef ValueAllocator allocator_type; - typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - - public: - - ////////////////////////////////////////////// - // - // constructFr/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Constructs a list taking the allocator as parameter. - //! - //! Throws: If allocator_type's copy constructor throws. - //! - //! Complexity: Constant. - slist() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) - : AllocHolder() - {} - - //! Effects: Constructs a list taking the allocator as parameter. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - explicit slist(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW - : AllocHolder(a) - {} - - //! Effects: Constructs a list - //! and inserts n value-initialized value_types. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - explicit slist(size_type n) - : AllocHolder(allocator_type()) - { this->resize(n); } - - //! Effects: Constructs a list that will use a copy of allocator a - //! and inserts n copies of value. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - slist(size_type n, const allocator_type &a) - : AllocHolder(a) - { this->resize(n); } - - //! Effects: Constructs a list that will use a copy of allocator a - //! and inserts n copies of value. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type()) - : AllocHolder(a) - { this->insert_after(this->cbefore_begin(), n, x); } - - //! Effects: Constructs a list that will use a copy of allocator a - //! and inserts a copy of the range [first, last) in the list. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced InIt throws. - //! - //! Complexity: Linear to the range [first, last). - template - slist(InpIt first, InpIt last, const allocator_type& a = allocator_type()) - : AllocHolder(a) - { this->insert_after(this->cbefore_begin(), first, last); } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs a list that will use a copy of allocator a - //! and inserts a copy of the range [il.begin(), il.end()) in the list. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced std::initializer_list iterator throws. - //! - //! Complexity: Linear to the range [il.begin(), il.end()). - slist(std::initializer_list il, const allocator_type& a = allocator_type()) - : AllocHolder(a) - { this->insert_after(this->cbefore_begin(), il.begin(), il.end()); } -#endif - - //! Effects: Copy constructs a list. - //! - //! Postcondition: x == *this. - //! - //! Throws: If allocator_type's default constructor - //! - //! Complexity: Linear to the elements x contains. - slist(const slist& x) - : AllocHolder(x) - { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); } - - //! Effects: Move constructor. Moves x's resources to *this. - //! - //! Throws: If allocator_type's copy constructor throws. - //! - //! Complexity: Constant. - slist(BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW - : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x)) - {} - - //! Effects: Copy constructs a list using the specified allocator. - //! - //! Postcondition: x == *this. - //! - //! Throws: If allocator_type's default constructor - //! - //! Complexity: Linear to the elements x contains. - slist(const slist& x, const allocator_type &a) - : AllocHolder(a) - { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); } - - //! Effects: Move constructor using the specified allocator. - //! Moves x's resources to *this. - //! - //! Throws: If allocation or value_type's copy constructor throws. - //! - //! Complexity: Constant if a == x.get_allocator(), linear otherwise. - slist(BOOST_RV_REF(slist) x, const allocator_type &a) - : AllocHolder(a) - { - slist & sr = x; - if(this->node_alloc() == sr.node_alloc()){ - this->icont().swap(sr.icont()); - } - else{ - this->insert_after(this->cbefore_begin(), boost::make_move_iterator(sr.begin()), boost::make_move_iterator(sr.end())); - } - } - - //! Effects: Destroys the list. All stored values are destroyed - //! and used memory is deallocated. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements. - ~slist() BOOST_NOEXCEPT_OR_NOTHROW - {} //AllocHolder clears the slist - - //! Effects: Makes *this contain the same elements as x. - //! - //! Postcondition: this->size() == x.size(). *this contains a copy - //! of each of x's elements. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to the number of elements in x. - slist& operator= (BOOST_COPY_ASSIGN_REF(slist) x) - { - if (BOOST_LIKELY(this != &x)) { - NodeAlloc &this_alloc = this->node_alloc(); - const NodeAlloc &x_alloc = x.node_alloc(); - dtl::bool_ flag; - if(flag && this_alloc != x_alloc){ - this->clear(); - } - this->AllocHolder::copy_assign_alloc(x); - this->assign(x.begin(), x.end()); - } - return *this; - } - - //! Effects: Makes *this contain the same elements as x. - //! - //! Postcondition: this->size() == x.size(). *this contains a copy - //! of each of x's elements. - //! - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or value_type's move constructor throws) - //! - //! Complexity: Constant if allocator_traits_type:: - //! propagate_on_container_move_assignment is true or - //! this->get>allocator() == x.get_allocator(). Linear otherwise. - slist& operator=(BOOST_RV_REF(slist) x) - BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value - || allocator_traits_type::is_always_equal::value) - { - slist & sr = x; - if (BOOST_LIKELY(this != &sr)) { - NodeAlloc &this_alloc = this->node_alloc(); - NodeAlloc &x_alloc = sr.node_alloc(); - const bool propagate_alloc = allocator_traits_type:: - propagate_on_container_move_assignment::value; - const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; - //Resources can be transferred if both allocators are - //going to be equal after this function (either propagated or already equal) - if(propagate_alloc || allocators_equal){ - //Destroy - this->clear(); - //Move allocator if needed - this->AllocHolder::move_assign_alloc(sr); - //Obtain resources - this->icont() = boost::move(sr.icont()); - } - //Else do a one by one move - else{ - this->assign( boost::make_move_iterator(sr.begin()) - , boost::make_move_iterator(sr.end())); - } - } - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Makes *this contain the same elements as in il. - //! - //! Postcondition: this->size() == il.size(). *this contains a copy - //! of each of il's elements. - //! - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or value_type's move constructor throws) - slist& operator=(std::initializer_list il) - { - assign(il.begin(), il.end()); - return *this; - } -#endif - - //! Effects: Assigns the n copies of val to *this. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - void assign(size_type n, const T& val) - { - typedef constant_iterator cvalue_iterator; - return this->assign(cvalue_iterator(val, n), cvalue_iterator()); - } - - //! Effects: Assigns the range [first, last) to *this. - //! - //! Throws: If memory allocation throws or - //! T's constructor from dereferencing InpIt throws. - //! - //! Complexity: Linear to n. - template - void assign(InpIt first, InpIt last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::disable_if_convertible::type * = 0 - #endif - ) - { - iterator end_n(this->end()); - iterator prev(this->before_begin()); - iterator node(this->begin()); - while (node != end_n && first != last){ - *node = *first; - prev = node; - ++node; - ++first; - } - if (first != last) - this->insert_after(prev, first, last); - else - this->erase_after(prev, end_n); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Assigns the range [il.begin(), il.end()) to *this. - //! - //! Throws: If memory allocation throws or - //! T's constructor from dereferencing std::initializer_list iterator throws. - //! - //! Complexity: Linear to range [il.begin(), il.end()). - - void assign(std::initializer_list il) - { - assign(il.begin(), il.end()); - } -#endif - //! Effects: Returns a copy of the internal allocator. - //! - //! Throws: If allocator's copy constructor throws. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return allocator_type(this->node_alloc()); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW - { return this->node_alloc(); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->node_alloc(); } - - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// - - //! Effects: Returns a non-dereferenceable iterator that, - //! when incremented, yields begin(). This iterator may be used - //! as the argument to insert_after, erase_after, etc. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator before_begin() BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(end()); } - - //! Effects: Returns a non-dereferenceable const_iterator - //! that, when incremented, yields begin(). This iterator may be used - //! as the argument to insert_after, erase_after, etc. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator before_begin() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->cbefore_begin(); } - - //! Effects: Returns an iterator to the first element contained in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->icont().begin()); } - - //! Effects: Returns a const_iterator to the first element contained in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->cbegin(); } - - //! Effects: Returns an iterator to the end of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator end() BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->icont().end()); } - - //! Effects: Returns a const_iterator to the end of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->cend(); } - - //! Effects: Returns a non-dereferenceable const_iterator - //! that, when incremented, yields begin(). This iterator may be used - //! as the argument to insert_after, erase_after, etc. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cbefore_begin() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_iterator(end()); } - - //! Effects: Returns a const_iterator to the first element contained in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_iterator(this->non_const_icont().begin()); } - - //! Effects: Returns a const_iterator to the end of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_iterator(this->non_const_icont().end()); } - - //! Returns: The iterator to the element before i in the sequence. - //! Returns the end-iterator, if either i is the begin-iterator or the - //! sequence is empty. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements before i. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator previous(iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->icont().previous(p.get())); } - - //! Returns: The const_iterator to the element before i in the sequence. - //! Returns the end-const_iterator, if either i is the begin-const_iterator or - //! the sequence is empty. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements before i. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator previous(const_iterator p) - { return const_iterator(this->icont().previous(p.get())); } - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// - - //! Effects: Returns true if the list contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool empty() const - { return !this->size(); } - - //! Effects: Returns the number of the elements contained in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type size() const - { return this->icont().size(); } - - //! Effects: Returns the largest possible size of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type max_size() const - { return AllocHolder::max_size(); } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are value initialized. - //! - //! Throws: If memory allocation throws, or T's copy constructor throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - void resize(size_type new_size) - { - const_iterator last_pos; - if(!priv_try_shrink(new_size, last_pos)){ - typedef value_init_construct_iterator value_init_iterator; - this->insert_after(last_pos, value_init_iterator(new_size - this->size()), value_init_iterator()); - } - } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are copy constructed from x. - //! - //! Throws: If memory allocation throws, or T's copy constructor throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - void resize(size_type new_size, const T& x) - { - const_iterator last_pos; - if(!priv_try_shrink(new_size, last_pos)){ - this->insert_after(last_pos, new_size, x); - } - } - - ////////////////////////////////////////////// - // - // element access - // - ////////////////////////////////////////////// - - //! Requires: !empty() - //! - //! Effects: Returns a reference to the first element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference front() - { - BOOST_ASSERT(!this->empty()); - return *this->begin(); - } - - //! Requires: !empty() - //! - //! Effects: Returns a const reference to the first element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference front() const - { - BOOST_ASSERT(!this->empty()); - return *this->begin(); - } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the front of the list - //! - //! Returns: A reference to the created object. - //! - //! Throws: If memory allocation throws or - //! T's copy constructor throws. - //! - //! Complexity: Amortized constant time. - template - reference emplace_front(BOOST_FWD_REF(Args)... args) - { return *this->emplace_after(this->cbefore_begin(), boost::forward(args)...); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... after prev - //! - //! Throws: If memory allocation throws or - //! T's in-place constructor throws. - //! - //! Complexity: Constant - template - iterator emplace_after(const_iterator prev, BOOST_FWD_REF(Args)... args) - { - NodePtr pnode(AllocHolder::create_node(boost::forward(args)...)); - return iterator(this->icont().insert_after(prev.get(), *pnode)); - } - - #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - reference emplace_front(BOOST_MOVE_UREF##N)\ - { return *this->emplace_after(this->cbefore_begin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - iterator emplace_after(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\ - return iterator(this->icont().insert_after(p.get(), *pnode));\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE) - #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x at the beginning of the list. - //! - //! Throws: If memory allocation throws or - //! T's copy constructor throws. - //! - //! Complexity: Amortized constant time. - void push_front(const T &x); - - //! Effects: Constructs a new element in the beginning of the list - //! and moves the resources of x to this new element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Amortized constant time. - void push_front(T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front) - #endif - - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Inserts a copy of the value after prev_p. - //! - //! Returns: An iterator to the inserted element. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Amortized constant time. - //! - //! Note: Does not affect the validity of iterators and references of - //! previous values. - iterator insert_after(const_iterator prev_p, const T &x); - - //! Requires: prev_p must be a valid iterator of *this. - //! - //! Effects: Inserts a move constructed copy object from the value after the - //! element pointed by prev_p. - //! - //! Returns: An iterator to the inserted element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Amortized constant time. - //! - //! Note: Does not affect the validity of iterators and references of - //! previous values. - iterator insert_after(const_iterator prev_p, T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_after, T, iterator, priv_insert_after, const_iterator, const_iterator) - #endif - - //! Requires: prev_p must be a valid iterator of *this. - //! - //! Effects: Inserts n copies of x after prev_p. - //! - //! Returns: an iterator to the last inserted element or prev_p if n is 0. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! - //! Complexity: Linear to n. - //! - //! Note: Does not affect the validity of iterators and references of - //! previous values. - iterator insert_after(const_iterator prev_p, size_type n, const value_type& x) - { - typedef constant_iterator cvalue_iterator; - return this->insert_after(prev_p, cvalue_iterator(x, n), cvalue_iterator()); - } - - //! Requires: prev_p must be a valid iterator of *this. - //! - //! Effects: Inserts the range pointed by [first, last) after prev_p. - //! - //! Returns: an iterator to the last inserted element or prev_p if first == last. - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced InpIt throws. - //! - //! Complexity: Linear to the number of elements inserted. - //! - //! Note: Does not affect the validity of iterators and references of - //! previous values. - template - iterator insert_after(const_iterator prev_p, InpIt first, InpIt last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename dtl::enable_if_c - < !dtl::is_convertible::value - && (dtl::is_input_iterator::value - || dtl::is_same::value - ) - >::type * = 0 - #endif - ) - { - iterator ret_it(prev_p.get()); - for (; first != last; ++first){ - ret_it = iterator(this->icont().insert_after(ret_it.get(), *this->create_node_from_it(first))); - } - return ret_it; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Requires: prev_p must be a valid iterator of *this. - //! - //! Effects: Inserts the range pointed by [il.begin(), il.end()) after prev_p. - //! - //! Returns: an iterator to the last inserted element or prev_p if il.begin() == il.end(). - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced std::initializer_list iterator throws. - //! - //! Complexity: Linear to the number of elements inserted. - //! - //! Note: Does not affect the validity of iterators and references of - //! previous values. - iterator insert_after(const_iterator prev_p, std::initializer_list il) - { - return insert_after(prev_p, il.begin(), il.end()); - } -#endif - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - iterator insert_after(const_iterator prev, FwdIt first, FwdIt last - , typename dtl::enable_if_c - < !dtl::is_convertible::value - && !(dtl::is_input_iterator::value - || dtl::is_same::value - ) - >::type * = 0 - ) - { - //Optimized allocation and construction - insertion_functor func(this->icont(), prev.get()); - this->allocate_many_and_construct(first, boost::container::iterator_udistance(first, last), func); - return iterator(func.inserted_first()); - } - #endif - - //! Effects: Removes the first element from the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Amortized constant time. - void pop_front() - { - BOOST_ASSERT(!this->empty()); - this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); - } - - //! Effects: Erases the element after the element pointed by prev_p - //! of the list. - //! - //! Returns: the first element remaining beyond the removed elements, - //! or end() if no such element exists. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Does not invalidate iterators or references to non erased elements. - iterator erase_after(const_iterator prev_p) - { - return iterator(this->icont().erase_after_and_dispose(prev_p.get(), Destroyer(this->node_alloc()))); - } - - //! Effects: Erases the range (before_first, last) from - //! the list. - //! - //! Returns: the first element remaining beyond the removed elements, - //! or end() if no such element exists. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of erased elements. - //! - //! Note: Does not invalidate iterators or references to non erased elements. - iterator erase_after(const_iterator before_first, const_iterator last) - { - return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc()))); - } - - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements on *this and x. - void swap(slist& x) - BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value - || allocator_traits_type::is_always_equal::value) - { - BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value || - allocator_traits_type::is_always_equal::value || - this->get_stored_allocator() == x.get_stored_allocator()); - AllocHolder::swap(x); - } - - //! Effects: Erases all the elements of the list. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements in the list. - void clear() - { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); } - - ////////////////////////////////////////////// - // - // slist operations - // - ////////////////////////////////////////////// - - //! Requires: p must point to an element contained - //! by the list. x != *this - //! - //! Effects: Transfers all the elements of list x to this list, after the - //! the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: runtime_error if this' allocator and x's allocator - //! are not equal. - //! - //! Complexity: Linear to the elements in x. - //! - //! Note: Iterators of values obtained from list x now point to elements of - //! this list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this != &x); - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().splice_after(prev_p.get(), x.icont()); - } - - //! Requires: p must point to an element contained - //! by the list. x != *this - //! - //! Effects: Transfers all the elements of list x to this list, after the - //! the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: runtime_error if this' allocator and x's allocator - //! are not equal. - //! - //! Complexity: Linear to the elements in x. - //! - //! Note: Iterators of values obtained from list x now point to elements of - //! this list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice_after(prev_p, BOOST_MOVE_TO_LV(x)); } - - //! Requires: prev_p must be a valid iterator of this. - //! i must point to an element contained in list x. - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the value pointed by i, from list x to this list, - //! after the element pointed by prev_p. - //! If prev_p == prev or prev_p == ++prev, this function is a null operation. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_p, slist& x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().splice_after(prev_p.get(), x.icont(), prev.get()); - } - - //! Requires: prev_p must be a valid iterator of this. - //! i must point to an element contained in list x. - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the value pointed by i, from list x to this list, - //! after the element pointed by prev_p. - //! If prev_p == prev or prev_p == ++prev, this function is a null operation. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice_after(prev_p, BOOST_MOVE_TO_LV(x), prev); } - - //! Requires: prev_p must be a valid iterator of this. - //! before_first and before_last must be valid iterators of x. - //! prev_p must not be contained in [before_first, before_last) range. - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the range [before_first + 1, before_last + 1) - //! from list x to this list, after the element pointed by prev_p. - //! - //! Throws: Nothing - //! - //! Complexity: Linear to the number of transferred elements. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_p, slist& x, - const_iterator before_first, const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().splice_after - (prev_p.get(), x.icont(), before_first.get(), before_last.get()); - } - - //! Requires: prev_p must be a valid iterator of this. - //! before_first and before_last must be valid iterators of x. - //! prev_p must not be contained in [before_first, before_last) range. - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the range [before_first + 1, before_last + 1) - //! from list x to this list, after the element pointed by prev_p. - //! - //! Throws: Nothing - //! - //! Complexity: Linear to the number of transferred elements. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, - const_iterator before_first, const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice_after(prev_p, BOOST_MOVE_TO_LV(x), before_first, before_last); } - - //! Requires: prev_p must be a valid iterator of this. - //! before_first and before_last must be valid iterators of x. - //! prev_p must not be contained in [before_first, before_last) range. - //! n == distance(before_first, before_last). - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the range [before_first + 1, before_last + 1) - //! from list x to this list, after the element pointed by prev_p. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_p, slist& x, - const_iterator before_first, const_iterator before_last, - size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().splice_after - (prev_p.get(), x.icont(), before_first.get(), before_last.get(), n); - } - - //! Requires: prev_p must be a valid iterator of this. - //! before_first and before_last must be valid iterators of x. - //! prev_p must not be contained in [before_first, before_last) range. - //! n == distance(before_first, before_last). - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the range [before_first + 1, before_last + 1) - //! from list x to this list, after the element pointed by prev_p. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, - const_iterator before_first, const_iterator before_last, - size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice_after(prev_p, BOOST_MOVE_TO_LV(x), before_first, before_last, n); } - - //! Effects: Removes all the elements that compare equal to value. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear time. It performs exactly size() comparisons for equality. - //! - //! Note: The relative order of elements that are not removed is unchanged, - //! and iterators to elements that are not removed remain valid. - void remove(const T& value) - { this->remove_if(equal_to_value_type(value)); } - - //! Effects: Removes all the elements for which a specified - //! predicate is satisfied. - //! - //! Throws: If pred throws. - //! - //! Complexity: Linear time. It performs exactly size() calls to the predicate. - //! - //! Note: The relative order of elements that are not removed is unchanged, - //! and iterators to elements that are not removed remain valid. - template - void remove_if(Pred pred) - { - typedef value_to_node_compare value_to_node_compare_type; - this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc())); - } - - //! Effects: Removes adjacent duplicate elements or adjacent - //! elements that are equal from the list. - //! - //! Throws: If comparison throws. - //! - //! Complexity: Linear time (size()-1 comparisons equality comparisons). - //! - //! Note: The relative order of elements that are not removed is unchanged, - //! and iterators to elements that are not removed remain valid. - void unique() - { this->unique(value_equal_t()); } - - //! Effects: Removes adjacent duplicate elements or adjacent - //! elements that satisfy some binary predicate from the list. - //! - //! Throws: If pred throws. - //! - //! Complexity: Linear time (size()-1 comparisons calls to pred()). - //! - //! Note: The relative order of elements that are not removed is unchanged, - //! and iterators to elements that are not removed remain valid. - template - void unique(Pred pred) - { - typedef value_to_node_compare value_to_node_compare_type; - this->icont().unique_and_dispose(value_to_node_compare_type(pred), Destroyer(this->node_alloc())); - } - - //! Requires: The lists x and *this must be distinct. - //! - //! Effects: This function removes all of x's elements and inserts them - //! in order into *this according to std::less. The merge is stable; - //! that is, if an element from *this is equivalent to one from x, then the element - //! from *this will precede the one from x. - //! - //! Throws: If comparison throws. - //! - //! Complexity: This function is linear time: it performs at most - //! size() + x.size() - 1 comparisons. - void merge(slist & x) - { this->merge(x, value_less_t()); } - - //! Requires: The lists x and *this must be distinct. - //! - //! Effects: This function removes all of x's elements and inserts them - //! in order into *this according to std::less. The merge is stable; - //! that is, if an element from *this is equivalent to one from x, then the element - //! from *this will precede the one from x. - //! - //! Throws: If comparison throws. - //! - //! Complexity: This function is linear time: it performs at most - //! size() + x.size() - 1 comparisons. - void merge(BOOST_RV_REF(slist) x) - { this->merge(BOOST_MOVE_TO_LV(x)); } - - //! Requires: p must be a comparison function that induces a strict weak - //! ordering and both *this and x must be sorted according to that ordering - //! The lists x and *this must be distinct. - //! - //! Effects: This function removes all of x's elements and inserts them - //! in order into *this. The merge is stable; that is, if an element from *this is - //! equivalent to one from x, then the element from *this will precede the one from x. - //! - //! Throws: If comp throws. - //! - //! Complexity: This function is linear time: it performs at most - //! size() + x.size() - 1 comparisons. - //! - //! Note: Iterators and references to *this are not invalidated. - template - void merge(slist& x, StrictWeakOrdering comp) - { - typedef value_to_node_compare value_to_node_compare_type; - BOOST_ASSERT(this->node_alloc() == x.node_alloc()); - this->icont().merge(x.icont(), value_to_node_compare_type(comp)); - } - - //! Requires: p must be a comparison function that induces a strict weak - //! ordering and both *this and x must be sorted according to that ordering - //! The lists x and *this must be distinct. - //! - //! Effects: This function removes all of x's elements and inserts them - //! in order into *this. The merge is stable; that is, if an element from *this is - //! equivalent to one from x, then the element from *this will precede the one from x. - //! - //! Throws: If comp throws. - //! - //! Complexity: This function is linear time: it performs at most - //! size() + x.size() - 1 comparisons. - //! - //! Note: Iterators and references to *this are not invalidated. - template - void merge(BOOST_RV_REF(slist) x, StrictWeakOrdering comp) - { this->merge(BOOST_MOVE_TO_LV(x), comp); } - - //! Effects: This function sorts the list *this according to std::less. - //! The sort is stable, that is, the relative order of equivalent elements is preserved. - //! - //! Throws: If comparison throws. - //! - //! Notes: Iterators and references are not invalidated. - //! - //! Complexity: The number of comparisons is approximately N log N, where N - //! is the list's size. - void sort() - { this->sort(value_less_t()); } - - //! Effects: This function sorts the list *this according to std::less. - //! The sort is stable, that is, the relative order of equivalent elements is preserved. - //! - //! Throws: If comp throws. - //! - //! Notes: Iterators and references are not invalidated. - //! - //! Complexity: The number of comparisons is approximately N log N, where N - //! is the list's size. - template - void sort(StrictWeakOrdering comp) - { - typedef value_to_node_compare value_to_node_compare_type; - // nothing if the slist has length 0 or 1. - if (this->size() < 2) - return; - this->icont().sort(value_to_node_compare_type(comp)); - } - - //! Effects: Reverses the order of elements in the list. - //! - //! Throws: Nothing. - //! - //! Complexity: This function is linear time. - //! - //! Note: Iterators and references are not invalidated - void reverse() BOOST_NOEXCEPT_OR_NOTHROW - { this->icont().reverse(); } - - ////////////////////////////////////////////// - // - // list compatibility interface - // - ////////////////////////////////////////////// - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... before p - //! - //! Throws: If memory allocation throws or - //! T's in-place constructor throws. - //! - //! Complexity: Linear to the elements before p - template - iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args) - { return this->emplace_after(this->previous(p), boost::forward(args)...); } - - #else - - #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - return this->emplace_after(this->previous(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE) - #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of x before p. - //! - //! Returns: an iterator to the inserted element. - //! - //! Throws: If memory allocation throws or x's copy constructor throws. - //! - //! Complexity: Linear to the elements before p. - iterator insert(const_iterator p, const T &x); - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a new element before p with x's resources. - //! - //! Returns: an iterator to the inserted element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Linear to the elements before p. - iterator insert(const_iterator prev_p, T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) - #endif - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Inserts n copies of x before p. - //! - //! Returns: an iterator to the first inserted element or p if n == 0. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to n plus linear to the elements before p. - iterator insert(const_iterator p, size_type n, const value_type& x) - { - const_iterator prev(this->previous(p)); - this->insert_after(prev, n, x); - return ++iterator(prev.get()); - } - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of the [first, last) range before p. - //! - //! Returns: an iterator to the first inserted element or p if first == last. - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced InpIt throws. - //! - //! Complexity: Linear to distance [first, last) plus - //! linear to the elements before p. - template - iterator insert(const_iterator p, InIter first, InIter last) - { - const_iterator prev(this->previous(p)); - this->insert_after(prev, first, last); - return ++iterator(prev.get()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of the [il.begin(), il.end()) range before p. - //! - //! Returns: an iterator to the first inserted element or p if il.begin() == il.end(). - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced std::initializer_list iterator throws. - //! - //! Complexity: Linear to the range [il.begin(), il.end()) plus - //! linear to the elements before p. - iterator insert(const_iterator p, std::initializer_list il) - { - return insert(p, il.begin(), il.end()); - } -#endif - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Erases the element at p. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements before p. - iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->erase_after(previous(p))); } - - //! Requires: first and last must be valid iterator to elements in *this. - //! - //! Effects: Erases the elements pointed by [first, last). - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the distance between first and last plus - //! linear to the elements before first. - iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->erase_after(previous(first), last)); } - - //! Requires: p must point to an element contained - //! by the list. x != *this. this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers all the elements of list x to this list, before the - //! the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Linear in distance(begin(), p), and linear in x.size(). - //! - //! Note: Iterators of values obtained from list x now point to elements of - //! this list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice_after(this->previous(p), x); } - - //! Requires: p must point to an element contained - //! by the list. x != *this. this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers all the elements of list x to this list, before the - //! the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Linear in distance(begin(), p), and linear in x.size(). - //! - //! Note: Iterators of values obtained from list x now point to elements of - //! this list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice(p, BOOST_MOVE_TO_LV(x)); } - - //! Requires: p must point to an element contained - //! by this list. i must point to an element contained in list x. - //! this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers the value pointed by i, from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! If p == i or p == ++i, this function is a null operation. - //! - //! Throws: Nothing - //! - //! Complexity: Linear in distance(begin(), p), and in distance(x.begin(), i). - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, slist& x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice_after(this->previous(p), x, x.previous(i)); } - - //! Requires: p must point to an element contained - //! by this list. i must point to an element contained in list x. - //! this' allocator and x's allocator shall compare equal. - //! - //! Effects: Transfers the value pointed by i, from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! If p == i or p == ++i, this function is a null operation. - //! - //! Throws: Nothing - //! - //! Complexity: Linear in distance(begin(), p), and in distance(x.begin(), i). - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice(p, BOOST_MOVE_TO_LV(x), i); } - - //! Requires: p must point to an element contained - //! by this list. first and last must point to elements contained in list x. - //! - //! Effects: Transfers the range pointed by first and last from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! this' allocator and x's allocator shall compare equal. - //! - //! Throws: Nothing - //! - //! Complexity: Linear in distance(begin(), p), in distance(x.begin(), first), - //! and in distance(first, last). - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice_after(this->previous(p), x, x.previous(first), x.previous(last)); } - - //! Requires: p must point to an element contained - //! by this list. first and last must point to elements contained in list x. - //! this' allocator and x's allocator shall compare equal - //! - //! Effects: Transfers the range pointed by first and last from list x to this list, - //! before the element pointed by p. No destructors or copy constructors are called. - //! - //! Throws: Nothing - //! - //! Complexity: Linear in distance(begin(), p), in distance(x.begin(), first), - //! and in distance(first, last). - //! - //! Note: Iterators of values obtained from list x now point to elements of this - //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW - { this->splice(p, BOOST_MOVE_TO_LV(x), first, last); } - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const slist& x, const slist& y) - { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const slist& x, const slist& y) - { return !(x == y); } - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const slist& x, const slist& y) - { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const slist& x, const slist& y) - { return y < x; } - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const slist& x, const slist& y) - { return !(y < x); } - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const slist& x, const slist& y) - { return !(x < y); } - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - friend void swap(slist& x, slist& y) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) - { x.swap(y); } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - - template - void priv_push_front(BOOST_FWD_REF(U) x) - { this->icont().push_front(*this->create_node(::boost::forward(x))); } - - bool priv_try_shrink(size_type new_size, const_iterator &last_pos) - { - typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next; - while (++(cur_next = cur) != end_n && new_size > 0){ - --new_size; - cur = cur_next; - } - last_pos = const_iterator(cur); - if (cur_next != end_n){ - this->erase_after(last_pos, const_iterator(end_n)); - return true; - } - else{ - return false; - } - } - - template - iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x) - { return this->insert_after(previous(p), ::boost::forward(x)); } - - template - iterator priv_insert_after(const_iterator prev_p, BOOST_FWD_REF(U) x) - { return iterator(this->icont().insert_after(prev_p.get(), *this->create_node(::boost::forward(x)))); } - - class insertion_functor; - friend class insertion_functor; - - class insertion_functor - { - Icont &icont_; - typedef typename Icont::iterator iiterator; - typedef typename Icont::const_iterator iconst_iterator; - const iconst_iterator prev_; - iiterator ret_; - - public: - insertion_functor(Icont &icont, typename Icont::const_iterator prev) - : icont_(icont), prev_(prev), ret_(prev.unconst()) - {} - - void operator()(Node &n) - { - ret_ = this->icont_.insert_after(prev_, n); - } - - iiterator inserted_first() const - { return ret_; } - }; - - //Functors for member algorithm defaults - typedef value_less value_less_t; - typedef value_equal value_equal_t; - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -slist(InpIt, InpIt) -> - slist::value_type>; - -template -slist(InpIt, InpIt, Allocator const&) -> - slist::value_type, Allocator>; - -#endif - -}} - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -namespace boost { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef typename boost::container::slist::allocator_type allocator_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -}} //namespace boost{ namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -// Specialization of insert_iterator so that insertions will be constant -// time rather than linear time. - -#include -BOOST_CONTAINER_DOC1ST(namespace std {, BOOST_MOVE_STD_NS_BEG) - -//! A specialization of insert_iterator -//! that works with slist -template -class insert_iterator > -{ - private: - typedef boost::container::slist Container; - Container* container; - typename Container::iterator iter; - - public: - typedef Container container_type; - typedef output_iterator_tag iterator_category; - typedef void value_type; - typedef void difference_type; - typedef void pointer; - typedef void reference; - - insert_iterator(Container& x, - typename Container::iterator i, - bool is_previous = false) - : container(&x), iter(is_previous ? i : x.previous(i)){ } - - insert_iterator& - operator=(const typename Container::value_type& value) - { - iter = container->insert_after(iter, value); - return *this; - } - insert_iterator& operator*(){ return *this; } - insert_iterator& operator++(){ return *this; } - insert_iterator& operator++(int){ return *this; } -}; - -BOOST_CONTAINER_DOC1ST( }, BOOST_MOVE_STD_NS_END) -#include - -#include - -#endif // BOOST_CONTAINER_SLIST_HPP diff --git a/inst/i/b/container/small_vector.hpp b/inst/i/b/container/small_vector.hpp deleted file mode 100644 index b6cf247d2..000000000 --- a/inst/i/b/container/small_vector.hpp +++ /dev/null @@ -1,685 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2015-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) -// -// See http://www.boost.org/libs/container for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP -#define BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include - -// container -#include -#include -#include -#include //new_allocator -// container/detail -#include -#include - -//move -#include -#include - -//move/detail -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif -#include - -//std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include //for std::initializer_list -#endif - -namespace boost { -namespace container { - -namespace dtl{ - -template -struct get_small_vector_opt -{ - typedef Options type; -}; - -template<> -struct get_small_vector_opt -{ - typedef small_vector_null_opt type; -}; - -template -struct get_vopt_from_svopt - : get_small_vector_opt::type -{ - typedef typename get_small_vector_opt::type options_t; - typedef vector_opt< typename options_t::growth_factor_type, void> type; -}; - -template<> -struct get_vopt_from_svopt -{ - typedef void type; -}; - -template -struct vector_for_small_vector -{ - typedef vector - < T - , small_vector_allocator - < T - , typename allocator_traits::type>::template portable_rebind_alloc::type - , Options> - , typename dtl::get_vopt_from_svopt::type - > type; -}; - -} //namespace dtl - -//! A non-standard allocator used to implement `small_vector`. -//! Users should never use it directly. It is described here -//! for documentation purposes. -//! -//! This allocator inherits from a standard-conforming allocator -//! and forwards member functions to the standard allocator except -//! when internal storage is being used as memory source. -//! -//! This allocator is a "partially_propagable" allocator and -//! defines `is_partially_propagable` as true_type. -//! -//! A partially propagable allocator means that not all storage -//! allocatod by an instance of `small_vector_allocator` can be -//! deallocated by another instance of this type, even if both -//! instances compare equal or an instance is propagated to another -//! one using the copy/move constructor or assignment. The storage that -//! can never be propagated is identified by `storage_is_unpropagable(p)`. -//! -//! `boost::container::vector` supports partially propagable allocators -//! fallbacking to deep copy/swap/move operations when internal storage -//! is being used to store vector elements. -//! -//! `small_vector_allocator` assumes that will be instantiated as -//! `boost::container::vector< T, small_vector_allocator >` -//! and internal storage can be obtained downcasting that vector -//! to `small_vector_base`. -template -class small_vector_allocator - : public allocator_traits::template portable_rebind_alloc::type -{ - typedef unsigned int allocation_type; - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - - typedef typename allocator_traits::template portable_rebind_alloc::type allocator_type; - - BOOST_COPYABLE_AND_MOVABLE(small_vector_allocator) - - BOOST_CONTAINER_FORCEINLINE const allocator_type &as_base() const BOOST_NOEXCEPT - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE allocator_type &as_base() BOOST_NOEXCEPT - { return static_cast(*this); } - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef allocator_traits allocator_traits_type; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - typedef typename allocator_traits::value_type value_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef typename allocator_traits::reference reference; - typedef typename allocator_traits::const_reference const_reference; - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::difference_type difference_type; - typedef typename allocator_traits::void_pointer void_pointer; - typedef typename allocator_traits::const_void_pointer const_void_pointer; - - typedef typename allocator_traits::propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - typedef typename allocator_traits::propagate_on_container_move_assignment propagate_on_container_move_assignment; - typedef typename allocator_traits::propagate_on_container_swap propagate_on_container_swap; - //! An integral constant with member `value == false` - typedef BOOST_CONTAINER_IMPDEF(dtl::bool_) is_always_equal; - //! An integral constant with member `value == true` - typedef BOOST_CONTAINER_IMPDEF(dtl::bool_) is_partially_propagable; - - BOOST_CONTAINER_DOCIGN(typedef dtl::version_type version;) - - //!Obtains an small_vector_allocator that allocates - //!objects of type T2 - template - struct rebind - { - typedef typename allocator_traits::template portable_rebind_alloc::type other; - }; - - BOOST_CONTAINER_FORCEINLINE small_vector_allocator() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) - {} - - //!Constructor from other small_vector_allocator. - //!Never throws - BOOST_CONTAINER_FORCEINLINE small_vector_allocator - (const small_vector_allocator &other) BOOST_NOEXCEPT_OR_NOTHROW - : allocator_type(other.as_base()) - {} - - //!Move constructor from small_vector_allocator. - //!Never throws - BOOST_CONTAINER_FORCEINLINE small_vector_allocator - (BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - : allocator_type(::boost::move(other.as_base())) - {} - - //!Constructor from related small_vector_allocator. - //!Never throws - template - BOOST_CONTAINER_FORCEINLINE small_vector_allocator - (const small_vector_allocator &other) BOOST_NOEXCEPT_OR_NOTHROW - : allocator_type(other.as_base()) - {} - - //!Move constructor from related small_vector_allocator. - //!Never throws - template - BOOST_CONTAINER_FORCEINLINE small_vector_allocator - (BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - : allocator_type(::boost::move(other.as_base())) - {} - - //!Constructor from allocator_type. - //!Never throws - BOOST_CONTAINER_FORCEINLINE explicit small_vector_allocator - (const allocator_type &other) BOOST_NOEXCEPT_OR_NOTHROW - : allocator_type(other) - {} - - //!Assignment from other small_vector_allocator. - //!Never throws - BOOST_CONTAINER_FORCEINLINE small_vector_allocator & - operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast(this->allocator_type::operator=(other.as_base())); } - - //!Move assignment from other small_vector_allocator. - //!Never throws - BOOST_CONTAINER_FORCEINLINE small_vector_allocator & - operator=(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast(this->allocator_type::operator=(::boost::move(other.as_base()))); } - - //!Assignment from related small_vector_allocator. - //!Never throws - template - BOOST_CONTAINER_FORCEINLINE small_vector_allocator & - operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast(this->allocator_type::operator=(other.as_base())); } - - //!Move assignment from related small_vector_allocator. - //!Never throws - template - BOOST_CONTAINER_FORCEINLINE small_vector_allocator & - operator=(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast(this->allocator_type::operator=(::boost::move(other.as_base()))); } - - //!Move assignment from allocator_type. - //!Never throws - BOOST_CONTAINER_FORCEINLINE small_vector_allocator & - operator=(const allocator_type &other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast(this->allocator_type::operator=(other)); } - - //!Allocates storage from the standard-conforming allocator - BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type count, const_void_pointer hint = const_void_pointer()) - { return allocator_traits_type::allocate(this->as_base(), count, hint); } - - //!Deallocates previously allocated memory. - //!Never throws - void deallocate(pointer ptr, size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { - if(!this->is_internal_storage(ptr)) - allocator_traits_type::deallocate(this->as_base(), ptr, n); - } - - //!Returns the maximum number of elements that could be allocated. - //!Never throws - BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return allocator_traits_type::max_size(this->as_base()); } - - small_vector_allocator select_on_container_copy_construction() const - { return small_vector_allocator(allocator_traits_type::select_on_container_copy_construction(this->as_base())); } - - bool storage_is_unpropagable(pointer p) const - { return this->is_internal_storage(p) || allocator_traits_type::storage_is_unpropagable(this->as_base(), p); } - - //!Swaps two allocators, does nothing - //!because this small_vector_allocator is stateless - BOOST_CONTAINER_FORCEINLINE friend void swap(small_vector_allocator &l, small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW - { boost::adl_move_swap(l.as_base(), r.as_base()); } - - //!An small_vector_allocator always compares to true, as memory allocated with one - //!instance can be deallocated by another instance (except for unpropagable storage) - BOOST_CONTAINER_FORCEINLINE friend bool operator==(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW - { return allocator_traits_type::equal(l.as_base(), r.as_base()); } - - //!An small_vector_allocator always compares to false, as memory allocated with one - //!instance can be deallocated by another instance - BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW - { return !(l == r); } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - - typedef small_vector_base derived_type; - typedef typename dtl::vector_for_small_vector - ::type vector_type; - - BOOST_CONTAINER_FORCEINLINE bool is_internal_storage(const_pointer p) const - { return this->internal_storage() == p; } - - public: - BOOST_CONTAINER_FORCEINLINE const_pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW; - BOOST_CONTAINER_FORCEINLINE pointer internal_storage() BOOST_NOEXCEPT_OR_NOTHROW; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -template -struct small_vector_storage -{ - typedef typename dtl::aligned_storage - ::type storage_type; - storage_type m_storage; - static const std::size_t sms_size = sizeof(storage_type)/sizeof(T); -}; - -template -struct small_vector_storage -{ - static const std::size_t sms_size = 0u; -}; - -//! This class consists of common code from all small_vector types that don't depend on the -//! "N" template parameter. This class is non-copyable and non-destructible, so this class typically -//! used as reference argument to functions that read or write small vectors. Since `small_vector` -//! derives from `small_vector_base`, the conversion to `small_vector_base` is implicit -//!
-//!
-//! //Clients can pass any small_vector.
-//! void read_any_small_vector_of_foo(const small_vector_base &in_parameter);
-//!
-//! void modify_any_small_vector_of_foo(small_vector_base &in_out_parameter);
-//!
-//! void some_function()
-//! {
-//! 
-//!    small_vector myvector;
-//!
-//!    read_any_small_vector_of_foo(myvector);   // Reads myvector
-//!
-//!    modify_any_small_vector_of_foo(myvector); // Modifies myvector
-//! 
-//! }
-//! 
-//! -//! All `boost::container:vector` member functions are inherited. See `vector` documentation for details. -//! -template -class small_vector_base - : public dtl::vector_for_small_vector::type -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKEDVECTOR - public: - //Make it public as it will be inherited by small_vector and container - //must have this public member - typedef typename real_allocator::type secondary_allocator_t; - typedef typename allocator_traits:: - template portable_rebind_alloc::type void_allocator_t; - typedef typename dtl::get_small_vector_opt::type options_t; - typedef typename dtl::vector_for_small_vector - ::type base_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef typename allocator_traits::void_pointer void_pointer; - typedef typename allocator_traits::const_void_pointer const_void_pointer; - typedef small_vector_allocator allocator_type; - - private: - BOOST_COPYABLE_AND_MOVABLE(small_vector_base) - - friend class small_vector_allocator; - - BOOST_CONTAINER_FORCEINLINE - const_pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->base_type::get_stored_allocator().internal_storage(); } - - BOOST_CONTAINER_FORCEINLINE - pointer internal_storage() BOOST_NOEXCEPT_OR_NOTHROW - { return this->base_type::get_stored_allocator().internal_storage(); } - - private: - base_type &as_base() { return static_cast(*this); } - const base_type &as_base() const { return static_cast(*this); } - - public: - - protected: - - BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(initial_capacity_t, std::size_t initial_capacity) - : base_type(initial_capacity_t(), this->internal_storage(), initial_capacity) - {} - - template - BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(initial_capacity_t, std::size_t capacity, BOOST_FWD_REF(AllocFwd) a) - : base_type(initial_capacity_t(), this->internal_storage(), capacity, ::boost::forward(a)) - {} - - BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(maybe_initial_capacity_t, std::size_t initial_capacity, std::size_t initial_size) - : base_type( maybe_initial_capacity_t() - , (initial_capacity >= initial_size) ? this->internal_storage() : pointer() - , (initial_capacity >= initial_size) ? initial_capacity : initial_size - ) - {} - - template - BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(maybe_initial_capacity_t, std::size_t initial_capacity, std::size_t initial_size, BOOST_FWD_REF(AllocFwd) a) - : base_type(maybe_initial_capacity_t() - , (initial_capacity >= initial_size) ? this->internal_storage() : pointer() - , (initial_capacity >= initial_size) ? initial_capacity : initial_size - , ::boost::forward(a) - ) - {} - - using base_type::protected_set_size; - - //~small_vector_base(){} - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - BOOST_CONTAINER_FORCEINLINE small_vector_base& operator=(BOOST_COPY_ASSIGN_REF(small_vector_base) other) - { return static_cast(this->base_type::operator=(static_cast(other))); } - - BOOST_CONTAINER_FORCEINLINE small_vector_base& operator=(BOOST_RV_REF(small_vector_base) other) - { return static_cast(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); } - - BOOST_CONTAINER_FORCEINLINE void swap(small_vector_base &other) - { return this->base_type::swap(other); } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - protected: - void move_construct_impl(base_type &x, const allocator_type &a) - { - if(base_type::is_propagable_from(x.get_stored_allocator(), x.data(), a, true)){ - this->steal_resources(x); - } - else{ - const typename base_type::size_type sz = x.size(); - ::boost::container::uninitialized_move_alloc_n_source - (this->base_type::get_stored_allocator(), x.begin(), sz, this->begin()); - this->protected_set_size(sz); - x.clear(); - } - } - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -///////////////////////////////////////////////////// -// -// small_vector_storage_definer -// -///////////////////////////////////////////////////// -template -struct small_vector_storage_definer -{ - typedef typename dtl::get_small_vector_opt::type options_t; - static const std::size_t final_alignment = - options_t::inplace_alignment ? options_t::inplace_alignment : dtl::alignment_of::value; - typedef small_vector_storage type; -}; - -template -struct small_vector_storage_strawman - : public small_vector_base - , public small_vector_storage_definer::type -{ - typedef typename small_vector_storage_definer::type sm_storage_t; -}; - -//Internal storage hack -template -BOOST_CONTAINER_FORCEINLINE typename small_vector_allocator::const_pointer - small_vector_allocator::internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW -{ - typedef small_vector_storage_strawman strawman_t; - typedef typename strawman_t::sm_storage_t sm_storage_t; - - //These warnings are false positives, as we know the alignment is correct - //and aligned storage is allowed to hold any type - #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) - #pragma GCC diagnostic push - // #pragma GCC diagnostic ignored "-Wcast-align" - // #pragma GCC diagnostic ignored "-Wstrict-aliasing" - #endif - const vector_type& v = reinterpret_cast(*this); - BOOST_ASSERT((std::size_t(this) % dtl::alignment_of::value) == 0); - const strawman_t &straw = static_cast(v); - const sm_storage_t& stor = static_cast(straw); - return boost::intrusive::pointer_traits::pointer_to(*((const T*)stor.m_storage.data)); - #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) - #pragma GCC diagnostic pop - #endif -} - -template -BOOST_CONTAINER_FORCEINLINE typename small_vector_allocator::pointer - small_vector_allocator::internal_storage() BOOST_NOEXCEPT_OR_NOTHROW -{ - typedef small_vector_storage_strawman strawman_t; - typedef typename strawman_t::sm_storage_t sm_storage_t; - - #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) - #pragma GCC diagnostic push - // #pragma GCC diagnostic ignored "-Wcast-align" - // #pragma GCC diagnostic ignored "-Wstrict-aliasing" - #endif - vector_type& v = reinterpret_cast(*this); - BOOST_ASSERT((std::size_t(this) % dtl::alignment_of::value) == 0); - strawman_t &straw = static_cast(v); - sm_storage_t& stor = static_cast(straw); - return boost::intrusive::pointer_traits::pointer_to(*((T*)stor.m_storage.data)); - #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) - #pragma GCC diagnostic pop - #endif -} - - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! small_vector is a vector-like container optimized for the case when it contains few elements. -//! It contains some preallocated elements in-place, which can avoid the use of dynamic storage allocation -//! when the actual number of elements is below that preallocated threshold. -//! -//! `small_vector` is convertible to `small_vector_base` that is independent -//! from the preallocated element capacity, so client code does not need to be templated on that N argument. -//! -//! All `boost::container::vector` member functions are inherited. See `vector` documentation for details. -//! -//! Any change to the capacity of the vector, including decreasing its size such as with the shrink_to_fit method, will -//! cause the vector to permanently switch to dynamically allocated storage. -//! -//! \tparam T The type of object that is stored in the small_vector -//! \tparam N The number of preallocated elements stored inside small_vector. It shall be less than Allocator::max_size(); -//! \tparam Allocator The allocator used for memory management when the number of elements exceeds N. Use void -//! for the default allocator -//! \tparam Options A type produced from \c boost::container::small_vector_options. -template -class small_vector - : public small_vector_base - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - , private small_vector_storage_definer::type - #endif -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - BOOST_COPYABLE_AND_MOVABLE(small_vector) - - public: - typedef small_vector_base base_type; - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::size_type size_type; - typedef typename base_type::value_type value_type; - - BOOST_CONTAINER_FORCEINLINE static std::size_t internal_capacity() - { return static_capacity; } - - typedef allocator_traits allocator_traits_type; - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - //! @brief The capacity/max size of the container - static const size_type static_capacity = small_vector_storage_definer::type::sms_size; - - public: - BOOST_CONTAINER_FORCEINLINE small_vector() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) - : base_type(initial_capacity_t(), internal_capacity()) - {} - - BOOST_CONTAINER_FORCEINLINE explicit small_vector(const allocator_type &a) - : base_type(initial_capacity_t(), internal_capacity(), a) - {} - - BOOST_CONTAINER_FORCEINLINE explicit small_vector(size_type n) - : base_type(maybe_initial_capacity_t(), internal_capacity(), n) - { this->protected_init_n(n, value_init); } - - BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const allocator_type &a) - : base_type(maybe_initial_capacity_t(), internal_capacity(), n, a) - { this->protected_init_n(n, value_init); } - - BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, default_init_t) - : base_type(maybe_initial_capacity_t(), internal_capacity(), n) - { this->protected_init_n(n, default_init_t()); } - - BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, default_init_t, const allocator_type &a) - : base_type(maybe_initial_capacity_t(), internal_capacity(), n, a) - { this->protected_init_n(n, default_init_t()); } - - BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const value_type &v) - : base_type(maybe_initial_capacity_t(), internal_capacity(), n) - { this->protected_init_n(n, v); } - - BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const value_type &v, const allocator_type &a) - : base_type(maybe_initial_capacity_t(), internal_capacity(), n, a) - { this->protected_init_n(n, v); } - - template - BOOST_CONTAINER_FORCEINLINE small_vector(InIt first, InIt last - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c - < dtl::is_convertible::value - BOOST_MOVE_I dtl::nat >::type * = 0) - ) - : base_type(initial_capacity_t(), internal_capacity()) - { this->assign(first, last); } - - template - BOOST_CONTAINER_FORCEINLINE small_vector(InIt first, InIt last, const allocator_type& a - BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c - < dtl::is_convertible::value - BOOST_MOVE_I dtl::nat >::type * = 0) - ) - : base_type(initial_capacity_t(), internal_capacity(), a) - { this->assign(first, last); } - - BOOST_CONTAINER_FORCEINLINE small_vector(const small_vector &other) - : base_type( initial_capacity_t(), internal_capacity() - , allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator())) - { this->assign(other.cbegin(), other.cend()); } - - BOOST_CONTAINER_FORCEINLINE small_vector(const small_vector &other, const allocator_type &a) - : base_type(initial_capacity_t(), internal_capacity(), a) - { this->assign(other.cbegin(), other.cend()); } - - BOOST_CONTAINER_FORCEINLINE explicit small_vector(const base_type &other) - : base_type( initial_capacity_t(), internal_capacity() - , allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator())) - { this->assign(other.cbegin(), other.cend()); } - - BOOST_CONTAINER_FORCEINLINE explicit small_vector(BOOST_RV_REF(base_type) other) - : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator())) - { this->move_construct_impl(other, other.get_stored_allocator()); } - - BOOST_CONTAINER_FORCEINLINE small_vector(BOOST_RV_REF(small_vector) other) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator())) - { this->move_construct_impl(other, other.get_stored_allocator()); } - - BOOST_CONTAINER_FORCEINLINE small_vector(BOOST_RV_REF(small_vector) other, const allocator_type &a) - : base_type(initial_capacity_t(), internal_capacity(), a) - { this->move_construct_impl(other, a); } - - #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - BOOST_CONTAINER_FORCEINLINE small_vector(std::initializer_list il, const allocator_type& a = allocator_type()) - : base_type(initial_capacity_t(), internal_capacity(), a) - { - this->assign(il.begin(), il.end()); - } - #endif - - BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_COPY_ASSIGN_REF(small_vector) other) - { return static_cast(this->base_type::operator=(static_cast(other))); } - - BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_RV_REF(small_vector) other) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_assignable::value - && (allocator_traits_type::propagate_on_container_move_assignment::value - || allocator_traits_type::is_always_equal::value)) - { return static_cast(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); } - - BOOST_CONTAINER_FORCEINLINE small_vector& operator=(const base_type &other) - { return static_cast(this->base_type::operator=(other)); } - - BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_RV_REF(base_type) other) - { return static_cast(this->base_type::operator=(boost::move(other))); } - - BOOST_CONTAINER_FORCEINLINE void swap(small_vector &other) - { return this->base_type::swap(other); } -}; - -}} - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -/* -namespace boost { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; -}; - -} -*/ -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#include - -#endif // #ifndef BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP diff --git a/inst/i/b/container/stable_vector.hpp b/inst/i/b/container/stable_vector.hpp deleted file mode 100644 index ac8807950..000000000 --- a/inst/i/b/container/stable_vector.hpp +++ /dev/null @@ -1,2258 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2008-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) -// -// See http://www.boost.org/libs/container for documentation. -// -////////////////////////////////////////////////////////////////////////////// -// Stable vector. -// -// Copyright 2008 Joaquin M Lopez Munoz. -// 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) -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP -#define BOOST_CONTAINER_STABLE_VECTOR_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include - -// container -#include -#include -#include //new_allocator -#include -// container/detail -#include -#include //algo_equal(), algo_lexicographical_compare -#include -#include -#include -#include -#include -#include -#include -#include -// intrusive -#include -// intrusive/detail -#include //pair -// move -#include -#include -#include -#include -// move/detail -#include -#include -// other -#include -// std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - #include - //#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -namespace boost { -namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -namespace stable_vector_detail{ - -template -class clear_on_destroy -{ - public: - BOOST_CONTAINER_FORCEINLINE clear_on_destroy(C &c) - : c_(c), do_clear_(true) - {} - - BOOST_CONTAINER_FORCEINLINE void release() - { do_clear_ = false; } - - BOOST_CONTAINER_FORCEINLINE ~clear_on_destroy() - { - if(do_clear_){ - c_.clear(); - c_.priv_clear_pool(); - } - } - - private: - clear_on_destroy(const clear_on_destroy &); - clear_on_destroy &operator=(const clear_on_destroy &); - C &c_; - bool do_clear_; -}; - -template -struct node; - -template -struct node_base -{ - private: - typedef typename boost::intrusive:: - pointer_traits void_ptr_traits; - typedef typename void_ptr_traits:: - template rebind_pointer - ::type node_base_ptr; - - public: - typedef typename void_ptr_traits:: - template rebind_pointer - ::type node_base_ptr_ptr; - - public: - BOOST_CONTAINER_FORCEINLINE explicit node_base(const node_base_ptr_ptr &n) - : up(n) - {} - - BOOST_CONTAINER_FORCEINLINE node_base() - : up() - {} - - node_base_ptr_ptr up; -}; - - -template -struct node - : public node_base - ::template - rebind_pointer::type - > -{ - public: - typedef typename ::boost::intrusive::pointer_traits::element_type T; - typedef node_base - ::template - rebind_pointer::type - > hook_type; - - typedef typename boost::container::dtl::aligned_storage - ::value>::type storage_t; - storage_t m_storage; - - BOOST_CONTAINER_FORCEINLINE explicit node(const typename hook_type::node_base_ptr_ptr &n) - : hook_type(n) - {} - - BOOST_CONTAINER_FORCEINLINE node() - {} - - #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) && (BOOST_GCC < 80000) - #pragma GCC diagnostic push - // #pragma GCC diagnostic ignored "-Wstrict-aliasing" - #define BOOST_CONTAINER_DISABLE_ALIASING_WARNING - # endif - - BOOST_CONTAINER_FORCEINLINE T &get_data() - { return *boost::move_detail::force_ptr(this->m_storage.data); } - - BOOST_CONTAINER_FORCEINLINE const T &get_data() const - { return *boost::move_detail::force_ptr(this->m_storage.data); } - - BOOST_CONTAINER_FORCEINLINE T *get_data_ptr() - { return boost::move_detail::force_ptr(this->m_storage.data); } - - BOOST_CONTAINER_FORCEINLINE const T *get_data_ptr() const - { return boost::move_detail::force_ptr(this->m_storage.data); } - - BOOST_CONTAINER_FORCEINLINE ~node() - { boost::move_detail::force_ptr(this->m_storage.data)->~T(); } - - #if defined(BOOST_CONTAINER_DISABLE_ALIASING_WARNING) - #pragma GCC diagnostic pop - #undef BOOST_CONTAINER_DISABLE_ALIASING_WARNING - # endif - - BOOST_CONTAINER_FORCEINLINE void destroy_header() - { static_cast(this)->~hook_type(); } -}; - -template -struct index_traits -{ - typedef boost::intrusive:: - pointer_traits - void_ptr_traits; - typedef stable_vector_detail:: - node_base node_base_type; - typedef typename void_ptr_traits::template - rebind_pointer::type node_base_ptr; - typedef typename void_ptr_traits::template - rebind_pointer::type node_base_ptr_ptr; - typedef boost::intrusive:: - pointer_traits node_base_ptr_traits; - typedef boost::intrusive:: - pointer_traits node_base_ptr_ptr_traits; - typedef typename allocator_traits:: - template portable_rebind_alloc - ::type node_base_ptr_allocator; - typedef ::boost::container::vector - index_type; - typedef typename index_type::iterator index_iterator; - typedef typename index_type::const_iterator const_index_iterator; - typedef typename index_type::size_type size_type; - - static const size_type ExtraPointers = 3; - //Stable vector stores metadata at the end of the index (node_base_ptr vector) with additional 3 pointers: - // back() is this->index.back() - ExtraPointers; - // end node index is *(this->index.end() - 3) - // Node cache first is *(this->index.end() - 2); - // Node cache last is this->index.back(); - - BOOST_CONTAINER_FORCEINLINE static node_base_ptr_ptr ptr_to_node_base_ptr(node_base_ptr &n) - { return node_base_ptr_ptr_traits::pointer_to(n); } - - static void fix_up_pointers(index_iterator first, index_iterator last) - { - while(first != last){ - typedef typename index_type::reference node_base_ptr_ref; - node_base_ptr_ref nbp = *first; - nbp->up = index_traits::ptr_to_node_base_ptr(nbp); - ++first; - } - } - - BOOST_CONTAINER_FORCEINLINE static index_iterator get_fix_up_end(index_type &index) - { return index.end() - (ExtraPointers - 1); } - - BOOST_CONTAINER_FORCEINLINE static void fix_up_pointers_from(index_type & index, index_iterator first) - { index_traits::fix_up_pointers(first, index_traits::get_fix_up_end(index)); } - - static void readjust_end_node(index_type &index, node_base_type &end_node) - { - if(!index.empty()){ - index_iterator end_node_it(index_traits::get_fix_up_end(index)); - node_base_ptr &end_node_idx_ref = *(--end_node_it); - end_node_idx_ref = node_base_ptr_traits::pointer_to(end_node); - end_node.up = node_base_ptr_ptr_traits::pointer_to(end_node_idx_ref); - } - else{ - end_node.up = node_base_ptr_ptr(); - } - } - - static void initialize_end_node(index_type &index, node_base_type &end_node, const size_type index_capacity_if_empty) - { - if(index.empty()){ - index.reserve(index_capacity_if_empty + ExtraPointers); - index.resize(ExtraPointers); - node_base_ptr &end_node_ref = *index.data(); - end_node_ref = node_base_ptr_traits::pointer_to(end_node); - end_node.up = index_traits::ptr_to_node_base_ptr(end_node_ref); - } - } - - #ifdef STABLE_VECTOR_ENABLE_INVARIANT_CHECKING - static bool invariants(index_type &index) - { - for( index_iterator it = index.begin() - , it_end = index_traits::get_fix_up_end(index) - ; it != it_end - ; ++it){ - if((*it)->up != index_traits::ptr_to_node_base_ptr(*it)){ - return false; - } - } - return true; - } - #endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING -}; - -} //namespace stable_vector_detail - -template -class stable_vector_iterator -{ - typedef boost::intrusive::pointer_traits non_const_ptr_traits; - public: - typedef std::random_access_iterator_tag iterator_category; - typedef typename non_const_ptr_traits::element_type value_type; - typedef typename non_const_ptr_traits::difference_type difference_type; - typedef typename non_const_ptr_traits::size_type size_type; - typedef typename ::boost::container::dtl::if_c - < IsConst - , typename non_const_ptr_traits::template - rebind_pointer::type - , Pointer - >::type pointer; - typedef boost::intrusive::pointer_traits ptr_traits; - typedef typename ptr_traits::reference reference; - - typedef typename non_const_ptr_traits::template - rebind_pointer::type void_ptr; - typedef stable_vector_detail::node node_type; - typedef stable_vector_detail::node_base node_base_type; - typedef typename non_const_ptr_traits::template - rebind_pointer::type node_ptr; - typedef boost::intrusive:: - pointer_traits node_ptr_traits; - typedef typename non_const_ptr_traits::template - rebind_pointer::type node_base_ptr; - typedef typename non_const_ptr_traits::template - rebind_pointer::type node_base_ptr_ptr; - - class nat - { - public: - node_base_ptr node_pointer() const - { return node_base_ptr(); } - }; - typedef typename dtl::if_c< IsConst - , stable_vector_iterator - , nat>::type nonconst_iterator; - - node_base_ptr m_pn; - - public: - - BOOST_CONTAINER_FORCEINLINE explicit stable_vector_iterator(node_base_ptr p) BOOST_NOEXCEPT_OR_NOTHROW - : m_pn(p) - {} - - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator() BOOST_NOEXCEPT_OR_NOTHROW - : m_pn() //Value initialization to achieve "null iterators" (N3644) - {} - - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator(const stable_vector_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW - : m_pn(other.node_pointer()) - {} - - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator(const nonconst_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW - : m_pn(other.node_pointer()) - {} - - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator & operator=(const stable_vector_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW - { m_pn = other.node_pointer(); return *this; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - node_ptr node_pointer() const BOOST_NOEXCEPT_OR_NOTHROW - { return node_ptr_traits::static_cast_from(m_pn); } - - public: - //Pointer like operators - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW - { return node_pointer()->get_data(); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW - { return ptr_traits::pointer_to(this->operator*()); } - - //Increment / Decrement - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW - { - node_base_ptr_ptr p(this->m_pn->up); - this->m_pn = *(++p); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW - { stable_vector_iterator tmp(*this); ++*this; return stable_vector_iterator(tmp); } - - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW - { - node_base_ptr_ptr p(this->m_pn->up); - this->m_pn = *(--p); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW - { stable_vector_iterator tmp(*this); --*this; return stable_vector_iterator(tmp); } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW - { return node_ptr_traits::static_cast_from(this->m_pn->up[off])->get_data(); } - - //Arithmetic - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW - { - if(off) this->m_pn = this->m_pn->up[off]; - return *this; - } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend stable_vector_iterator operator+(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW - { - stable_vector_iterator tmp(left); - tmp += off; - return tmp; - } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend stable_vector_iterator operator+(difference_type off, const stable_vector_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW - { - stable_vector_iterator tmp(right); - tmp += off; - return tmp; - } - - BOOST_CONTAINER_FORCEINLINE stable_vector_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW - { *this += -off; return *this; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend stable_vector_iterator operator-(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW - { - stable_vector_iterator tmp(left); - tmp -= off; - return tmp; - } - - //Difference - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend difference_type operator-(const stable_vector_iterator &left, const stable_vector_iterator &right) BOOST_NOEXCEPT_OR_NOTHROW - { return left.m_pn->up - right.m_pn->up; } - - //Comparison operators - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator== (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return l.m_pn == r.m_pn; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return l.m_pn != r.m_pn; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator< (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return l.m_pn->up < r.m_pn->up; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return l.m_pn->up <= r.m_pn->up; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator> (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return l.m_pn->up > r.m_pn->up; } - - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return l.m_pn->up >= r.m_pn->up; } -}; - - #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING) - - #define BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT \ - invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); - - #else //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING - - #define BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT - - #endif //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING) - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector -//! drop-in replacement implemented as a node container, offering iterator and reference -//! stability. -//! -//! Here are the details taken from the author's blog -//! ( -//! Introducing stable_vector): -//! -//! We present stable_vector, a fully STL-compliant stable container that provides -//! most of the features of std::vector except element contiguity. -//! -//! General properties: stable_vector satisfies all the requirements of a container, -//! a reversible container and a sequence and provides all the optional operations -//! present in std::vector. Like std::vector, iterators are random access. -//! stable_vector does not provide element contiguity; in exchange for this absence, -//! the container is stable, i.e. references and iterators to an element of a stable_vector -//! remain valid as long as the element is not erased, and an iterator that has been -//! assigned the return value of end() always remain valid until the destruction of -//! the associated stable_vector. -//! -//! Operation complexity: The big-O complexities of stable_vector operations match -//! exactly those of std::vector. In general, insertion/deletion is constant time at -//! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector -//! does not internally perform any value_type destruction, copy or assignment -//! operations other than those exactly corresponding to the insertion of new -//! elements or deletion of stored elements, which can sometimes compensate in terms -//! of performance for the extra burden of doing more pointer manipulation and an -//! additional allocation per element. -//! -//! Exception safety: As stable_vector does not internally copy elements around, some -//! operations provide stronger exception safety guarantees than in std::vector. -//! -//! \tparam T The type of object that is stored in the stable_vector -//! \tparam Allocator The allocator used for all internal memory management -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template -#else -template -#endif -class stable_vector -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef typename real_allocator::type ValueAllocator; - typedef allocator_traits allocator_traits_type; - typedef boost::intrusive:: - pointer_traits - ptr_traits; - typedef typename ptr_traits:: - template rebind_pointer::type void_ptr; - typedef typename allocator_traits_type:: - template portable_rebind_alloc - ::type void_allocator_type; - typedef stable_vector_detail::index_traits - index_traits_type; - typedef typename index_traits_type::node_base_type node_base_type; - typedef typename index_traits_type::node_base_ptr node_base_ptr; - typedef typename index_traits_type:: - node_base_ptr_ptr node_base_ptr_ptr; - typedef typename index_traits_type:: - node_base_ptr_traits node_base_ptr_traits; - typedef typename index_traits_type:: - node_base_ptr_ptr_traits node_base_ptr_ptr_traits; - typedef typename index_traits_type::index_type index_type; - typedef typename index_traits_type::index_iterator index_iterator; - typedef typename index_traits_type:: - const_index_iterator const_index_iterator; - typedef stable_vector_detail::node - node_type; - typedef typename ptr_traits::template - rebind_pointer::type node_ptr; - typedef boost::intrusive:: - pointer_traits node_ptr_traits; - typedef typename ptr_traits::template - rebind_pointer::type const_node_ptr; - typedef boost::intrusive:: - pointer_traits const_node_ptr_traits; - typedef typename node_ptr_traits::reference node_reference; - typedef typename const_node_ptr_traits::reference const_node_reference; - - typedef ::boost::container::dtl::integral_constant - ::value> alloc_version; - typedef typename allocator_traits_type:: - template portable_rebind_alloc - ::type node_allocator_type; - - typedef ::boost::container::dtl:: - allocator_version_traits allocator_version_traits_t; - typedef typename allocator_version_traits_t::multiallocation_chain multiallocation_chain; - - BOOST_CONTAINER_FORCEINLINE node_ptr allocate_one() - { return allocator_version_traits_t::allocate_one(this->priv_node_alloc()); } - - BOOST_CONTAINER_FORCEINLINE void deallocate_one(const node_ptr &p) - { allocator_version_traits_t::deallocate_one(this->priv_node_alloc(), p); } - - BOOST_CONTAINER_FORCEINLINE void allocate_individual(typename allocator_traits_type::size_type n, multiallocation_chain &m) - { allocator_version_traits_t::allocate_individual(this->priv_node_alloc(), n, m); } - - BOOST_CONTAINER_FORCEINLINE void deallocate_individual(multiallocation_chain &holder) - { allocator_version_traits_t::deallocate_individual(this->priv_node_alloc(), holder); } - - friend class stable_vector_detail::clear_on_destroy; - typedef stable_vector_iterator - < typename allocator_traits::pointer - , false> iterator_impl; - typedef stable_vector_iterator - < typename allocator_traits::pointer - , true> const_iterator_impl; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - public: - - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef ValueAllocator allocator_type; - typedef node_allocator_type stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(stable_vector) - static const size_type ExtraPointers = index_traits_type::ExtraPointers; - - class insert_rollback; - friend class insert_rollback; - - class push_back_rollback; - friend class push_back_rollback; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - - //! Effects: Default constructs a stable_vector. - //! - //! Throws: If allocator_type's default constructor throws. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE stable_vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) - : internal_data(), index() - { - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - } - - //! Effects: Constructs a stable_vector taking the allocator as parameter. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE explicit stable_vector(const allocator_type& al) BOOST_NOEXCEPT_OR_NOTHROW - : internal_data(al), index(al) - { - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - } - - //! Effects: Constructs a stable_vector - //! and inserts n value initialized values. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - explicit stable_vector(size_type n) - : internal_data(), index() - { - stable_vector_detail::clear_on_destroy cod(*this); - this->resize(n); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - - //! Effects: Constructs a stable_vector - //! and inserts n default initialized values. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - //! - //! Note: Non-standard extension - stable_vector(size_type n, default_init_t) - : internal_data(), index() - { - stable_vector_detail::clear_on_destroy cod(*this); - this->resize(n, default_init); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - - //! Effects: Constructs a stable_vector that will use a copy of allocator a - //! and inserts n value initialized values. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - explicit stable_vector(size_type n, const allocator_type &a) - : internal_data(), index(a) - { - stable_vector_detail::clear_on_destroy cod(*this); - this->resize(n); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - - //! Effects: Constructs a stable_vector that will use a copy of allocator a - //! and inserts n default initialized values. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - //! - //! Note: Non-standard extension - stable_vector(size_type n, default_init_t, const allocator_type &a) - : internal_data(), index(a) - { - stable_vector_detail::clear_on_destroy cod(*this); - this->resize(n, default_init); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - - //! Effects: Constructs a stable_vector that will use a copy of allocator a - //! and inserts n copies of value. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's default or copy constructor throws. - //! - //! Complexity: Linear to n. - stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type()) - : internal_data(al), index(al) - { - stable_vector_detail::clear_on_destroy cod(*this); - this->insert(this->cend(), n, t); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - - //! Effects: Constructs a stable_vector that will use a copy of allocator a - //! and inserts a copy of the range [first, last) in the stable_vector. - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced InIt throws. - //! - //! Complexity: Linear to the range [first, last). - template - stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type()) - : internal_data(al), index(al) - { - stable_vector_detail::clear_on_destroy cod(*this); - this->insert(this->cend(), first, last); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - - //! Effects: Copy constructs a stable_vector. - //! - //! Postcondition: x == *this. - //! - //! Complexity: Linear to the elements x contains. - stable_vector(const stable_vector& x) - : internal_data(allocator_traits:: - select_on_container_copy_construction(x.priv_node_alloc())) - , index(allocator_traits:: - select_on_container_copy_construction(x.index.get_stored_allocator())) - { - stable_vector_detail::clear_on_destroy cod(*this); - this->insert(this->cend(), x.begin(), x.end()); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Constructs a stable_vector that will use a copy of allocator a - //! and inserts a copy of the range [il.begin(), il.last()) in the stable_vector - //! - //! Throws: If allocator_type's default constructor - //! throws or T's constructor taking a dereferenced initializer_list iterator throws. - //! - //! Complexity: Linear to the range [il.begin(), il.end()). - stable_vector(std::initializer_list il, const allocator_type& l = allocator_type()) - : internal_data(l), index(l) - { - stable_vector_detail::clear_on_destroy cod(*this); - insert(cend(), il.begin(), il.end()); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } -#endif - - //! Effects: Move constructor. Moves x's resources to *this. - //! - //! Throws: If allocator_type's copy constructor throws. - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE stable_vector(BOOST_RV_REF(stable_vector) x) BOOST_NOEXCEPT_OR_NOTHROW - : internal_data(boost::move(x.priv_node_alloc())), index(boost::move(x.index)) - { - this->priv_swap_members(x); - } - - //! Effects: Copy constructs a stable_vector using the specified allocator. - //! - //! Postcondition: x == *this. - //! - //! Complexity: Linear to the elements x contains. - stable_vector(const stable_vector& x, const allocator_type &a) - : internal_data(a), index(a) - { - stable_vector_detail::clear_on_destroy cod(*this); - this->insert(this->cend(), x.begin(), x.end()); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - - //! Effects: Move constructor using the specified allocator. - //! Moves x's resources to *this. - //! - //! Throws: If allocator_type's copy constructor throws. - //! - //! Complexity: Constant if a == x.get_allocator(), linear otherwise - stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a) - : internal_data(a), index(a) - { - if(this->priv_node_alloc() == x.priv_node_alloc()){ - this->index.swap(x.index); - this->priv_swap_members(x); - } - else{ - stable_vector_detail::clear_on_destroy cod(*this); - this->insert(this->cend(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end())); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - cod.release(); - } - } - - //! Effects: Destroys the stable_vector. All stored values are destroyed - //! and used memory is deallocated. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements. - ~stable_vector() - { - this->clear(); - this->priv_clear_pool(); - } - - //! Effects: Makes *this contain the same elements as x. - //! - //! Postcondition: this->size() == x.size(). *this contains a copy - //! of each of x's elements. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to the number of elements in x. - stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x) - { - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - if (BOOST_LIKELY(this != &x)) { - node_allocator_type &this_alloc = this->priv_node_alloc(); - const node_allocator_type &x_alloc = x.priv_node_alloc(); - dtl::bool_ flag; - if(flag && this_alloc != x_alloc){ - this->clear(); - this->shrink_to_fit(); - } - dtl::assign_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag); - dtl::assign_alloc(this->index.get_stored_allocator(), x.index.get_stored_allocator(), flag); - this->assign(x.begin(), x.end()); - } - return *this; - } - - //! Effects: Move assignment. All x's values are transferred to *this. - //! - //! Postcondition: x.empty(). *this contains a the elements x had - //! before the function. - //! - //! Throws: If allocator_traits_type::propagate_on_container_move_assignment - //! is false and (allocation throws or T's move constructor throws) - //! - //! Complexity: Constant if allocator_traits_type:: - //! propagate_on_container_move_assignment is true or - //! this->get>allocator() == x.get_allocator(). Linear otherwise. - stable_vector& operator=(BOOST_RV_REF(stable_vector) x) - BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value - || allocator_traits_type::is_always_equal::value) - { - //for move constructor, no aliasing (&x != this) is assumed. - if (BOOST_LIKELY(this != &x)) { - node_allocator_type &this_alloc = this->priv_node_alloc(); - node_allocator_type &x_alloc = x.priv_node_alloc(); - const bool propagate_alloc = allocator_traits_type:: - propagate_on_container_move_assignment::value; - dtl::bool_ flag; - const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; - //Resources can be transferred if both allocators are - //going to be equal after this function (either propagated or already equal) - if(propagate_alloc || allocators_equal){ - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT - //Destroy objects but retain memory in case x reuses it in the future - this->clear(); - //Move allocator if needed - dtl::move_alloc(this_alloc, x_alloc, flag); - //Take resources - this->index.swap(x.index); - this->priv_swap_members(x); - } - //Else do a one by one move - else{ - this->assign( boost::make_move_iterator(x.begin()) - , boost::make_move_iterator(x.end())); - } - } - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Make *this container contains elements from il. - //! - //! Complexity: Linear to the range [il.begin(), il.end()). - stable_vector& operator=(std::initializer_list il) - { - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - assign(il.begin(), il.end()); - return *this; - } -#endif - - //! Effects: Assigns the n copies of val to *this. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& t) - { - typedef constant_iterator cvalue_iterator; - this->assign(cvalue_iterator(t, n), cvalue_iterator()); - } - - //! Effects: Assigns the the range [first, last) to *this. - //! - //! Throws: If memory allocation throws or - //! T's constructor from dereferencing InpIt throws. - //! - //! Complexity: Linear to n. - template - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - typename dtl::disable_if_convertible::type - #else - void - #endif - assign(InputIterator first,InputIterator last) - { - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - iterator first1 = this->begin(); - iterator last1 = this->end(); - for ( ; first1 != last1 && first != last; ++first1, ++first) - *first1 = *first; - if (first == last){ - this->erase(first1, last1); - } - else{ - this->insert(last1, first, last); - } - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Effects: Assigns the the range [il.begin(), il.end()) to *this. - //! - //! Throws: If memory allocation throws or - //! T's constructor from dereferencing initializer_list iterator throws. - //! - BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list il) - { - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - assign(il.begin(), il.end()); - } -#endif - - //! Effects: Returns a copy of the internal allocator. - //! - //! Throws: If allocator's copy constructor throws. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - allocator_type get_allocator() const - { return this->priv_node_alloc(); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->priv_node_alloc(); } - - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW - { return this->priv_node_alloc(); } - - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// - - //! Effects: Returns an iterator to the first element contained in the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW - { return (this->index.empty()) ? this->end(): iterator(node_ptr_traits::static_cast_from(this->index.front())); } - - //! Effects: Returns a const_iterator to the first element contained in the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW - { return (this->index.empty()) ? this->cend() : const_iterator(node_ptr_traits::static_cast_from(this->index.front())) ; } - - //! Effects: Returns an iterator to the end of the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator end() BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->priv_get_end_node()); } - - //! Effects: Returns a const_iterator to the end of the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_iterator(this->priv_get_end_node()); } - - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW - { return reverse_iterator(this->end()); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_reverse_iterator(this->end()); } - - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW - { return reverse_iterator(this->begin()); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_reverse_iterator(this->begin()); } - - //! Effects: Returns a const_iterator to the first element contained in the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->begin(); } - - //! Effects: Returns a const_iterator to the end of the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->end(); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->rbegin(); } - - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reverse_iterator crend()const BOOST_NOEXCEPT_OR_NOTHROW - { return this->rend(); } - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// - - //! Effects: Returns true if the stable_vector contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->index.size() <= ExtraPointers; } - - //! Effects: Returns the number of the elements contained in the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW - { - const size_type index_size = this->index.size(); - return (index_size - ExtraPointers) & (size_type(0u) -size_type(index_size != 0)); - } - - //! Effects: Returns the largest possible size of the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return this->index.max_size() - ExtraPointers; } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are value initialized. - //! - //! Throws: If memory allocation throws, or T's value initialization throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - void resize(size_type n) - { - typedef value_init_construct_iterator value_init_iterator; - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - if(n > this->size()) - this->insert( this->cend() - , value_init_iterator(n - this->size()), value_init_iterator()); - else if(n < this->size()) - this->erase(this->cbegin() + difference_type(n), this->cend()); - } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are default initialized. - //! - //! Throws: If memory allocation throws, or T's default initialization throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - //! - //! Note: Non-standard extension - void resize(size_type n, default_init_t) - { - typedef default_init_construct_iterator default_init_iterator; - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - if(n > this->size()) - this->insert(this->cend(), default_init_iterator(n - this->size()), default_init_iterator()); - else if(n < this->size()) - this->erase(this->cbegin() + difference_type(n), this->cend()); - } - - //! Effects: Inserts or erases elements at the end such that - //! the size becomes n. New elements are copy constructed from x. - //! - //! Throws: If memory allocation throws, or T's copy constructor throws. - //! - //! Complexity: Linear to the difference between size() and new_size. - void resize(size_type n, const T& t) - { - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - if(n > this->size()) - this->insert(this->cend(), n - this->size(), t); - else if(n < this->size()) - this->erase(this->cbegin() + difference_type(n), this->cend()); - } - - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW - { - const size_type index_size = this->index.size(); - BOOST_ASSERT(!index_size || index_size >= ExtraPointers); - const size_type node_extra_capacity = this->internal_data.pool_size; - //Pool count must be less than index capacity, as index is a vector - BOOST_ASSERT(node_extra_capacity <= (this->index.capacity()- index_size)); - const size_type index_offset = - (node_extra_capacity - ExtraPointers) & (size_type(0u) - size_type(index_size != 0)); - return index_size + index_offset; - } - - //! Effects: If n is less than or equal to capacity(), this call has no - //! effect. Otherwise, it is a request for allocation of additional memory. - //! If the request is successful, then capacity() is greater than or equal to - //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. - //! - //! Throws: If memory allocation allocation throws. - void reserve(size_type n) - { - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - if(n > this->max_size()){ - throw_length_error("stable_vector::reserve max_size() exceeded"); - } - - size_type sz = this->size(); - size_type old_capacity = this->capacity(); - if(n > old_capacity){ - index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, n); - const void * old_ptr = &index[0]; - this->index.reserve(n + ExtraPointers); - bool realloced = &index[0] != old_ptr; - //Fix the pointers for the newly allocated buffer - if(realloced){ - index_traits_type::fix_up_pointers_from(this->index, this->index.begin()); - } - //Now fill pool if data is not enough - if((n - sz) > this->internal_data.pool_size){ - this->priv_increase_pool((n - sz) - this->internal_data.pool_size); - } - } - } - - //! Effects: Tries to deallocate the excess of memory created - //! with previous allocations. The size of the stable_vector is unchanged - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Linear to size(). - void shrink_to_fit() - { - if(this->capacity()){ - //First empty allocated node pool - this->priv_clear_pool(); - //If empty completely destroy the index, let's recover default-constructed state - if(this->empty()){ - this->index.clear(); - this->index.shrink_to_fit(); - this->internal_data.end_node.up = node_base_ptr_ptr(); - } - //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary - else{ - const void* old_ptr = &index[0]; - this->index.shrink_to_fit(); - bool realloced = &index[0] != old_ptr; - //Fix the pointers for the newly allocated buffer - if(realloced){ - index_traits_type::fix_up_pointers_from(this->index, this->index.begin()); - } - } - } - } - - ////////////////////////////////////////////// - // - // element access - // - ////////////////////////////////////////////// - - //! Requires: !empty() - //! - //! Effects: Returns a reference to the first - //! element of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference front() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return static_cast(*this->index.front()).get_data(); - } - - //! Requires: !empty() - //! - //! Effects: Returns a const reference to the first - //! element of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return static_cast(*this->index.front()).get_data(); - } - - //! Requires: !empty() - //! - //! Effects: Returns a reference to the last - //! element of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference back() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return static_cast(*this->index[this->size()-1u]).get_data(); - } - - //! Requires: !empty() - //! - //! Effects: Returns a const reference to the last - //! element of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - return static_cast(*this->index[this->size()-1u]).get_data(); - } - - //! Requires: size() > n. - //! - //! Effects: Returns a reference to the nth element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->size() > n); - return static_cast(*this->index[n]).get_data(); - } - - //! Requires: size() > n. - //! - //! Effects: Returns a const reference to the nth element - //! from the beginning of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->size() > n); - return static_cast(*this->index[n]).get_data(); - } - - //! Requires: size() >= n. - //! - //! Effects: Returns an iterator to the nth element - //! from the beginning of the container. Returns end() - //! if n == size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->size() >= n); - return (this->index.empty()) ? this->end() : iterator(node_ptr_traits::static_cast_from(this->index[n])); - } - - //! Requires: size() >= n. - //! - //! Effects: Returns a const_iterator to the nth element - //! from the beginning of the container. Returns end() - //! if n == size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->size() >= n); - return (this->index.empty()) ? this->cend() : iterator(node_ptr_traits::static_cast_from(this->index[n])); - } - - //! Requires: begin() <= p <= end(). - //! - //! Effects: Returns the index of the element pointed by p - //! and size() if p == end(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { return this->priv_index_of(p.node_pointer()); } - - //! Requires: begin() <= p <= end(). - //! - //! Effects: Returns the index of the element pointed by p - //! and size() if p == end(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW - { return this->priv_index_of(p.node_pointer()); } - - //! Requires: size() > n. - //! - //! Effects: Returns a reference to the nth element - //! from the beginning of the container. - //! - //! Throws: range_error if n >= size() - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - reference at(size_type n) - { - if(n >= this->size()){ - throw_out_of_range("vector::at invalid subscript"); - } - return operator[](n); - } - - //! Requires: size() > n. - //! - //! Effects: Returns a const reference to the nth element - //! from the beginning of the container. - //! - //! Throws: range_error if n >= size() - //! - //! Complexity: Constant. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - const_reference at(size_type n)const - { - if(n >= this->size()){ - throw_out_of_range("vector::at invalid subscript"); - } - return operator[](n); - } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// - - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the end of the stable_vector. - //! - //! Returns: A reference to the created object. - //! - //! Throws: If memory allocation throws or the in-place constructor throws. - //! - //! Complexity: Amortized constant time. - template - reference emplace_back(Args &&...args) - { - typedef emplace_functor EmplaceFunctor; - typedef emplace_iterator EmplaceIterator; - EmplaceFunctor &&ef = EmplaceFunctor(boost::forward(args)...); - return *this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator()); - } - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... before p - //! - //! Throws: If memory allocation throws or the in-place constructor throws. - //! - //! Complexity: If p is end(), amortized constant time - //! Linear time otherwise. - template - iterator emplace(const_iterator p, Args && ...args) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - difference_type pos_n = p - cbegin(); - typedef emplace_functor EmplaceFunctor; - typedef emplace_iterator EmplaceIterator; - EmplaceFunctor &&ef = EmplaceFunctor(boost::forward(args)...); - this->insert(p, EmplaceIterator(ef), EmplaceIterator()); - return iterator(this->begin() + pos_n); - } - - #else - - #define BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - reference emplace_back(BOOST_MOVE_UREF##N)\ - {\ - typedef emplace_functor##N\ - BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\ - typedef emplace_iterator EmplaceIterator;\ - EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\ - return *this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());\ - }\ - \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - BOOST_ASSERT(this->priv_in_range_or_end(p));\ - typedef emplace_functor##N\ - BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\ - typedef emplace_iterator EmplaceIterator;\ - EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\ - const size_type pos_n = size_type(p - this->cbegin());\ - this->insert(p, EmplaceIterator(ef), EmplaceIterator());\ - return this->begin() += difference_type(pos_n);\ - }\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE) - #undef BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE - - #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts a copy of x at the end of the stable_vector. - //! - //! Throws: If memory allocation throws or - //! T's copy constructor throws. - //! - //! Complexity: Amortized constant time. - void push_back(const T &x); - - //! Effects: Constructs a new element in the end of the stable_vector - //! and moves the resources of x to this new element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: Amortized constant time. - void push_back(T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) - #endif - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of x before p. - //! - //! Returns: An iterator to the inserted element. - //! - //! Throws: If memory allocation throws or x's copy constructor throws. - //! - //! Complexity: If p is end(), amortized constant time - //! Linear time otherwise. - iterator insert(const_iterator p, const T &x); - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a new element before p with x's resources. - //! - //! Returns: an iterator to the inserted element. - //! - //! Throws: If memory allocation throws. - //! - //! Complexity: If p is end(), amortized constant time - //! Linear time otherwise. - iterator insert(const_iterator p, T &&x); - #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) - #endif - - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert n copies of x before p. - //! - //! Returns: an iterator to the first inserted element or p if n is 0. - //! - //! Throws: If memory allocation throws or T's copy constructor throws. - //! - //! Complexity: Linear to n. - iterator insert(const_iterator p, size_type n, const T& t) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - typedef constant_iterator cvalue_iterator; - return this->insert(p, cvalue_iterator(t, n), cvalue_iterator()); - } - - //! Requires: p must be a valid iterator of *this. -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! Requires: p must be a valid iterator of *this. - //! - //! Effects: Insert a copy of the [il.begin(), il.end()) range before p. - //! - //! Returns: an iterator to the first inserted element or p if first == last. - //! - //! Complexity: Linear to distance [il.begin(), il.end()). - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, std::initializer_list il) - { - //Position checks done by insert() - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - return insert(p, il.begin(), il.end()); - } -#endif - - //! Requires: pos must be a valid iterator of *this. - //! - //! Effects: Insert a copy of the [first, last) range before p. - //! - //! Returns: an iterator to the first inserted element or p if first == last. - //! - //! Throws: If memory allocation throws, T's constructor from a - //! dereferenced InpIt throws or T's copy constructor throws. - //! - //! Complexity: Linear to distance [first, last). - template - iterator insert(const_iterator p, InputIterator first, InputIterator last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //Put this as argument instead of the return type as old GCC's like 3.4 - //detect this and the next disable_if_or as overloads - , typename dtl::disable_if_or - < void - , dtl::is_convertible - , dtl::is_not_input_iterator - >::type* = 0 - #endif - ) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - const difference_type pos_n = p - this->cbegin(); - for(; first != last; ++first){ - this->emplace(p, *first); - } - return this->begin() + difference_type(pos_n); - } - - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - template - typename dtl::disable_if_or - < iterator - , dtl::is_convertible - , dtl::is_input_iterator - >::type - insert(const_iterator p, FwdIt first, FwdIt last) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - const size_type num_new = boost::container::iterator_udistance(first, last); - const size_type idx = static_cast(p - this->cbegin()); - if(num_new){ - //Fills the node pool and inserts num_new null pointers in idx. - //If a new buffer was needed fixes up pointers up to idx so - //past-new nodes are not aligned until the end of this function - //or in a rollback in case of exception - index_iterator it_past_newly_constructed(this->priv_insert_forward_non_templated(idx, num_new)); - const index_iterator it_past_new(it_past_newly_constructed + difference_type(num_new)); - { - //Prepare rollback - insert_rollback rollback(*this, it_past_newly_constructed, it_past_new); - while(first != last){ - const node_ptr n = this->priv_get_from_pool(); - BOOST_ASSERT(!!n); - //Put it in the index so rollback can return it in pool if construct_in_place throws - *it_past_newly_constructed = n; - //Constructs and fixes up pointers This can throw - this->priv_build_node_from_it(n, it_past_newly_constructed, first); - ++first; - ++it_past_newly_constructed; - } - //rollback.~insert_rollback() called in case of exception - } - //Fix up pointers for past-new nodes (new nodes were fixed during construction) and - //nodes before insertion p in priv_insert_forward_non_templated(...) - index_traits_type::fix_up_pointers_from(this->index, it_past_newly_constructed); - } - return this->begin() + static_cast(idx); - } - #endif - - //! Effects: Removes the last element from the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant time. - BOOST_CONTAINER_FORCEINLINE void pop_back() BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(!this->empty()); - this->erase(--this->cend()); - } - - //! Effects: Erases the element at p. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the elements between p and the - //! last element. Constant if p is the last element. - BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(this->priv_in_range(p)); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - const difference_type d = p - this->cbegin(); - index_iterator it = this->index.begin() + d; - this->priv_delete_node(p.node_pointer()); - it = this->index.erase(it); - index_traits_type::fix_up_pointers_from(this->index, it); - return iterator(node_ptr_traits::static_cast_from(*it)); - } - - //! Effects: Erases the elements pointed by [first, last). - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the distance between first and last - //! plus linear to the elements between p and the last element. - iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW - { - BOOST_ASSERT(first == last || - (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last))); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - const const_iterator cbeg(this->cbegin()); - const size_type d1 = static_cast(first - cbeg), - d2 = static_cast(last - cbeg); - size_type d_dif = d2 - d1; - if(d_dif){ - multiallocation_chain holder; - const index_iterator it1(this->index.begin() + difference_type(d1)); - const index_iterator it2(it1 + difference_type(d_dif)); - index_iterator it(it1); - while(d_dif){ - --d_dif; - node_base_ptr &nb = *it; - ++it; - node_type &n = *node_ptr_traits::static_cast_from(nb); - this->priv_destroy_node(n); - holder.push_back(node_ptr_traits::pointer_to(n)); - } - this->priv_put_in_pool(holder); - const index_iterator e = this->index.erase(it1, it2); - index_traits_type::fix_up_pointers_from(this->index, e); - } - return iterator(last.node_pointer()); - } - - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(stable_vector & x) - BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value - || allocator_traits_type::is_always_equal::value) - { - BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value || - allocator_traits_type::is_always_equal::value || - this->get_stored_allocator() == x.get_stored_allocator()); - BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; - dtl::bool_ flag; - dtl::swap_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag); - //vector's allocator is swapped here - this->index.swap(x.index); - this->priv_swap_members(x); - } - - //! Effects: Erases all the elements of the stable_vector. - //! - //! Throws: Nothing. - //! - //! Complexity: Linear to the number of elements in the stable_vector. - BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW - { this->erase(this->cbegin(),this->cend()); } - - //! Effects: Returns true if x and y are equal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const stable_vector& x, const stable_vector& y) - { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } - - //! Effects: Returns true if x and y are unequal - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const stable_vector& x, const stable_vector& y) - { return !(x == y); } - - //! Effects: Returns true if x is less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const stable_vector& x, const stable_vector& y) - { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - - //! Effects: Returns true if x is greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const stable_vector& x, const stable_vector& y) - { return y < x; } - - //! Effects: Returns true if x is equal or less than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const stable_vector& x, const stable_vector& y) - { return !(y < x); } - - //! Effects: Returns true if x is equal or greater than y - //! - //! Complexity: Linear to the number of elements in the container. - BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const stable_vector& x, const stable_vector& y) - { return !(x < y); } - - //! Effects: x.swap(y) - //! - //! Complexity: Constant. - BOOST_CONTAINER_FORCEINLINE friend void swap(stable_vector& x, stable_vector& y) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) - { x.swap(y); } - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - - bool priv_in_range(const_iterator pos) const - { - return (this->begin() <= pos) && (pos < this->end()); - } - - BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const - { - return (this->begin() <= pos) && (pos <= this->end()); - } - - BOOST_CONTAINER_FORCEINLINE size_type priv_index_of(node_ptr p) const - { - //Check range - BOOST_ASSERT(this->index.empty() || (this->index.data() <= p->up)); - BOOST_ASSERT(this->index.empty() || p->up <= (this->index.data() + this->index.size())); - return this->index.empty() ? 0u : size_type(p->up - this->index.data()); - } - - class insert_rollback - { - public: - - insert_rollback(stable_vector &sv, index_iterator &it_past_constructed, const index_iterator &it_past_new) - : m_sv(sv), m_it_past_constructed(it_past_constructed), m_it_past_new(it_past_new) - {} - - ~insert_rollback() - { - if(m_it_past_constructed != m_it_past_new){ - m_sv.priv_put_in_pool(node_ptr_traits::static_cast_from(*m_it_past_constructed)); - index_iterator e = m_sv.index.erase(m_it_past_constructed, m_it_past_new); - index_traits_type::fix_up_pointers_from(m_sv.index, e); - } - } - - private: - stable_vector &m_sv; - index_iterator &m_it_past_constructed; - const index_iterator &m_it_past_new; - }; - - class push_back_rollback - { - public: - BOOST_CONTAINER_FORCEINLINE push_back_rollback(stable_vector &sv, const node_ptr &p) - : m_sv(sv), m_p(p) - {} - - BOOST_CONTAINER_FORCEINLINE ~push_back_rollback() - { - if(m_p){ - m_sv.priv_put_in_pool(m_p); - } - } - - BOOST_CONTAINER_FORCEINLINE void release() - { m_p = node_ptr(); } - - private: - stable_vector &m_sv; - node_ptr m_p; - }; - - index_iterator priv_insert_forward_non_templated(size_type idx, size_type num_new) - { - index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, num_new); - - //Now try to fill the pool with new data - if(this->internal_data.pool_size < num_new){ - this->priv_increase_pool(num_new - this->internal_data.pool_size); - } - - //Now try to make room in the vector - const node_base_ptr_ptr old_buffer = this->index.data(); - this->index.insert(this->index.begin() + (difference_type)idx, num_new, node_ptr()); - bool new_buffer = this->index.data() != old_buffer; - - //Fix the pointers for the newly allocated buffer - const index_iterator index_beg = this->index.begin(); - if(new_buffer){ - index_traits_type::fix_up_pointers(index_beg, index_beg + (difference_type)idx); - } - return index_beg + (difference_type)idx; - } - - BOOST_CONTAINER_FORCEINLINE bool priv_capacity_bigger_than_size() const - { - return this->index.capacity() > this->index.size() && - this->internal_data.pool_size > 0; - } - - template - void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x) - { - if(BOOST_LIKELY(this->priv_capacity_bigger_than_size())){ - //Enough memory in the pool and in the index - const node_ptr p = this->priv_get_from_pool(); - BOOST_ASSERT(!!p); - { - push_back_rollback rollback(*this, p); - //This might throw - this->priv_build_node_from_convertible(p, ::boost::forward(x)); - rollback.release(); - } - //This can't throw as there is room for a new elements in the index - index_iterator new_index = this->index.insert(this->index.end() - ExtraPointers, p); - index_traits_type::fix_up_pointers_from(this->index, new_index); - } - else{ - this->insert(this->cend(), ::boost::forward(x)); - } - } - - iterator priv_insert(const_iterator p, const value_type &t) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - typedef constant_iterator cvalue_iterator; - return this->insert(p, cvalue_iterator(t, 1), cvalue_iterator()); - } - - iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x) - { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - typedef repeat_iterator repeat_it; - typedef boost::move_iterator repeat_move_it; - //Just call more general insert(p, size, value) and return iterator - return this->insert(p, repeat_move_it(repeat_it(x, 1)), repeat_move_it(repeat_it())); - } - - void priv_clear_pool() - { - if(!this->index.empty() && this->index.back()){ - node_base_ptr &pool_first_ref = *(this->index.end() - 2); - node_base_ptr &pool_last_ref = this->index.back(); - - multiallocation_chain holder; - holder.incorporate_after( holder.before_begin() - , node_ptr_traits::static_cast_from(pool_first_ref) - , node_ptr_traits::static_cast_from(pool_last_ref) - , internal_data.pool_size); - this->deallocate_individual(holder); - pool_first_ref = pool_last_ref = 0; - this->internal_data.pool_size = 0; - } - } - - void priv_increase_pool(size_type n) - { - node_base_ptr &pool_first_ref = *(this->index.end() - 2); - node_base_ptr &pool_last_ref = this->index.back(); - multiallocation_chain holder; - holder.incorporate_after( holder.before_begin() - , node_ptr_traits::static_cast_from(pool_first_ref) - , node_ptr_traits::static_cast_from(pool_last_ref) - , internal_data.pool_size); - multiallocation_chain m; - this->allocate_individual(n, m); - holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n); - this->internal_data.pool_size += n; - typename multiallocation_chain::pointer_pair data(holder.extract_data()); - pool_first_ref = data.first; - pool_last_ref = data.second; - } - - void priv_put_in_pool(const node_ptr &p) - { - node_base_ptr &pool_first_ref = *(this->index.end()-2); - node_base_ptr &pool_last_ref = this->index.back(); - multiallocation_chain holder; - holder.incorporate_after( holder.before_begin() - , node_ptr_traits::static_cast_from(pool_first_ref) - , node_ptr_traits::static_cast_from(pool_last_ref) - , internal_data.pool_size); - holder.push_front(p); - ++this->internal_data.pool_size; - typename multiallocation_chain::pointer_pair ret(holder.extract_data()); - pool_first_ref = ret.first; - pool_last_ref = ret.second; - } - - void priv_put_in_pool(multiallocation_chain &ch) - { - node_base_ptr &pool_first_ref = *(this->index.end()-(ExtraPointers-1)); - node_base_ptr &pool_last_ref = this->index.back(); - ch.incorporate_after( ch.before_begin() - , node_ptr_traits::static_cast_from(pool_first_ref) - , node_ptr_traits::static_cast_from(pool_last_ref) - , internal_data.pool_size); - this->internal_data.pool_size = ch.size(); - const typename multiallocation_chain::pointer_pair ret(ch.extract_data()); - pool_first_ref = ret.first; - pool_last_ref = ret.second; - } - - node_ptr priv_get_from_pool() - { - //Precondition: index is not empty - BOOST_ASSERT(!this->index.empty()); - node_base_ptr &pool_first_ref = *(this->index.end() - (ExtraPointers-1)); - node_base_ptr &pool_last_ref = this->index.back(); - multiallocation_chain holder; - holder.incorporate_after( holder.before_begin() - , node_ptr_traits::static_cast_from(pool_first_ref) - , node_ptr_traits::static_cast_from(pool_last_ref) - , internal_data.pool_size); - node_ptr ret = holder.pop_front(); - --this->internal_data.pool_size; - if(!internal_data.pool_size){ - pool_first_ref = pool_last_ref = node_ptr(); - } - else{ - const typename multiallocation_chain::pointer_pair data(holder.extract_data()); - pool_first_ref = data.first; - pool_last_ref = data.second; - } - return ret; - } - - BOOST_CONTAINER_FORCEINLINE node_base_ptr priv_get_end_node() const - { return node_base_ptr_traits::pointer_to(const_cast(this->internal_data.end_node)); } - - BOOST_CONTAINER_FORCEINLINE void priv_destroy_node(const node_type &n) - { - allocator_traits:: - destroy(this->priv_node_alloc(), &n); - } - - BOOST_CONTAINER_FORCEINLINE void priv_delete_node(const node_ptr &n) - { - this->priv_destroy_node(*n); - this->priv_put_in_pool(n); - } - - template - void priv_build_node_from_it(const node_ptr &p, const index_iterator &up_index, const Iterator &it) - { - node_type *praw = ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) - node_type(index_traits_type::ptr_to_node_base_ptr(*up_index)); - BOOST_CONTAINER_TRY{ - //This can throw - boost::container::construct_in_place - ( this->priv_node_alloc() - , praw->get_data_ptr() - , it); - } - BOOST_CONTAINER_CATCH(...) { - praw->destroy_header(); - this->priv_node_alloc().deallocate(p, 1); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - } - - template - void priv_build_node_from_convertible(const node_ptr &p, BOOST_FWD_REF(ValueConvertible) value_convertible) - { - node_type *praw = ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) node_type; - BOOST_CONTAINER_TRY{ - //This can throw - boost::container::allocator_traits::construct - ( this->priv_node_alloc() - , p->get_data_ptr() - , ::boost::forward(value_convertible)); - } - BOOST_CONTAINER_CATCH(...) { - praw->destroy_header(); - this->priv_node_alloc().deallocate(p, 1); - BOOST_CONTAINER_RETHROW - } - BOOST_CONTAINER_CATCH_END - } - - void priv_swap_members(stable_vector &x) - { - boost::adl_move_swap(this->internal_data.pool_size, x.internal_data.pool_size); - index_traits_type::readjust_end_node(this->index, this->internal_data.end_node); - index_traits_type::readjust_end_node(x.index, x.internal_data.end_node); - } - - #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING) - bool priv_invariant()const - { - index_type & index_ref = const_cast(this->index); - - const size_type index_size = this->index.size(); - if(!index_size) - return !this->capacity() && !this->size(); - - if(index_size < ExtraPointers) - return false; - - const size_type bucket_extra_capacity = this->index.capacity()- index_size; - const size_type node_extra_capacity = this->internal_data.pool_size; - if(bucket_extra_capacity < node_extra_capacity){ - return false; - } - - if(this->priv_get_end_node() != *(index.end() - ExtraPointers)){ - return false; - } - - if(!index_traits_type::invariants(index_ref)){ - return false; - } - - size_type n = this->capacity() - this->size(); - node_base_ptr &pool_first_ref = *(index_ref.end() - (ExtraPointers-1)); - node_base_ptr &pool_last_ref = index_ref.back(); - multiallocation_chain holder; - holder.incorporate_after( holder.before_begin() - , node_ptr_traits::static_cast_from(pool_first_ref) - , node_ptr_traits::static_cast_from(pool_last_ref) - , internal_data.pool_size); - typename multiallocation_chain::iterator beg(holder.begin()), end(holder.end()); - size_type num_pool = 0; - while(beg != end){ - ++num_pool; - ++beg; - } - return n >= num_pool && num_pool == internal_data.pool_size; - } - - class invariant_checker - { - invariant_checker(const invariant_checker &); - invariant_checker & operator=(const invariant_checker &); - const stable_vector* p; - - public: - invariant_checker(const stable_vector& v):p(&v){} - ~invariant_checker(){BOOST_ASSERT(p->priv_invariant());} - void touch(){} - }; - #endif - - class ebo_holder - : public node_allocator_type - { - private: - BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder) - - public: - template - explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a) - : node_allocator_type(boost::forward(a)) - , pool_size(0) - , end_node() - {} - - ebo_holder() - : node_allocator_type() - , pool_size(0) - , end_node() - {} - - size_type pool_size; - node_base_type end_node; - } internal_data; - - node_allocator_type &priv_node_alloc() { return internal_data; } - const node_allocator_type &priv_node_alloc() const { return internal_data; } - - index_type index; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; - -#ifndef BOOST_CONTAINER_NO_CXX17_CTAD - -template -stable_vector(InputIterator, InputIterator) -> - stable_vector::value_type>; - -template -stable_vector(InputIterator, InputIterator, Allocator const&) -> - stable_vector::value_type, Allocator>; - -#endif - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -#undef BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT - -} //namespace container { - -//!has_trivial_destructor_after_move<> == true_type -//!specialization for optimizations -template -struct has_trivial_destructor_after_move > -{ - typedef typename boost::container::stable_vector::allocator_type allocator_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move::value && - ::boost::has_trivial_destructor_after_move::value; -}; - -namespace container { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -}} //namespace boost{ namespace container { - -#include - -#endif //BOOST_CONTAINER_STABLE_VECTOR_HPP diff --git a/inst/i/b/container/static_vector.hpp b/inst/i/b/container/static_vector.hpp deleted file mode 100644 index 27eeadf46..000000000 --- a/inst/i/b/container/static_vector.hpp +++ /dev/null @@ -1,1326 +0,0 @@ -// Boost.Container static_vector -// -// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland. -// Copyright (c) 2011-2013 Andrew Hundt. -// Copyright (c) 2013-2014 Ion Gaztanaga -// -// Use, modification and distribution is subject to 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) - -#ifndef BOOST_CONTAINER_STATIC_VECTOR_HPP -#define BOOST_CONTAINER_STATIC_VECTOR_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -#include -#include - -#include -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -namespace boost { namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -namespace dtl { - -template -class static_storage_allocator -{ - typedef bool_ throw_on_overflow_t; - - static BOOST_NORETURN BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow(true_type) - { - (throw_bad_alloc)(); - } - - static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow(false_type) - { - BOOST_ASSERT_MSG(false, "ERROR: static vector capacity overflow"); - } - - public: - typedef T value_type; - - BOOST_CONTAINER_FORCEINLINE static_storage_allocator() BOOST_NOEXCEPT_OR_NOTHROW - {} - - BOOST_CONTAINER_FORCEINLINE static_storage_allocator(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; } - - BOOST_CONTAINER_FORCEINLINE T* internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_cast(static_cast(static_cast(storage.data))); } - - BOOST_CONTAINER_FORCEINLINE T* internal_storage() BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast(static_cast(storage.data)); } - - static const std::size_t internal_capacity = N; - - std::size_t max_size() const - { return N; } - - static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow() - { - (on_capacity_overflow)(throw_on_overflow_t()); - } - - typedef boost::container::dtl::version_type version; - - BOOST_CONTAINER_FORCEINLINE friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW - { return false; } - - BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW - { return true; } - - private: - BOOST_STATIC_ASSERT_MSG(!InplaceAlignment || (InplaceAlignment & (InplaceAlignment-1)) == 0, "Alignment option must be zero or power of two"); - static const std::size_t final_alignment = InplaceAlignment ? InplaceAlignment : dtl::alignment_of::value; - typename dtl::aligned_storage::type storage; -}; - -template -struct get_static_vector_opt -{ - typedef Options type; -}; - -template<> -struct get_static_vector_opt -{ - typedef static_vector_null_opt type; -}; - -template -struct get_static_vector_allocator -{ - typedef typename get_static_vector_opt::type options_t; - typedef dtl::static_storage_allocator - < T - , Capacity - , options_t::inplace_alignment - , options_t::throw_on_overflow - > type; -}; - - -} //namespace dtl { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! -//!@brief A variable-size array container with fixed capacity. -//! -//!static_vector is a sequence container like boost::container::vector with contiguous storage that can -//!change in size, along with the static allocation, low overhead, and fixed capacity of boost::array. -//! -//!A static_vector is a sequence that supports random access to elements, constant time insertion and -//!removal of elements at the end, and linear time insertion and removal of elements at the beginning or -//!in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity -//!because elements are stored within the object itself similarly to an array. However, objects are -//!initialized as they are inserted into static_vector unlike C arrays or std::array which must construct -//!all elements on instantiation. The behavior of static_vector enables the use of statically allocated -//!elements in cases with complex object lifetime requirements that would otherwise not be trivially -//!possible. -//! -//!@par Error Handling -//! If `throw_on_overflow` option is true (default behaviour), insertion beyond the capacity result -//! in throwing bad_alloc() if exceptions are enabled and or calling throw_bad_alloc() if not enabled. -//! If `throw_on_overflow` option is false, insertion beyond capacity results in Undefined Behaviour. -//! -//! out_of_range is thrown if out of bounds access is performed in at() if exceptions are -//! enabled, throw_out_of_range() if not enabled. -//! -//!@tparam T The type of element that will be stored. -//!@tparam Capacity The maximum number of elements static_vector can store, fixed at compile time. -//!@tparam Options A type produced from \c boost::container::static_vector_options. If no option -//! is specified, by default throw_on_overflow option is set. -template -class static_vector - : public vector::type> -{ - public: - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef typename dtl::get_static_vector_allocator< T, Capacity, Options>::type allocator_type; - typedef vector base_t; - - BOOST_COPYABLE_AND_MOVABLE(static_vector) - - template - friend class static_vector; - - public: - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -public: - //! @brief The type of elements stored in the container. - typedef typename base_t::value_type value_type; - //! @brief The unsigned integral type used by the container. - typedef typename base_t::size_type size_type; - //! @brief The pointers difference type. - typedef typename base_t::difference_type difference_type; - //! @brief The pointer type. - typedef typename base_t::pointer pointer; - //! @brief The const pointer type. - typedef typename base_t::const_pointer const_pointer; - //! @brief The value reference type. - typedef typename base_t::reference reference; - //! @brief The value const reference type. - typedef typename base_t::const_reference const_reference; - //! @brief The iterator type. - typedef typename base_t::iterator iterator; - //! @brief The const iterator type. - typedef typename base_t::const_iterator const_iterator; - //! @brief The reverse iterator type. - typedef typename base_t::reverse_iterator reverse_iterator; - //! @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 - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - BOOST_CONTAINER_FORCEINLINE static_vector() BOOST_NOEXCEPT_OR_NOTHROW - : base_t() - {} - - //! @pre count <= capacity() - //! - //! @brief Constructs a static_vector containing count value initialized values. - //! - //! @param count The number of values which will be contained in the container. - //! - //! @par Throws - //! @li If T's value initialization throws - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - BOOST_CONTAINER_FORCEINLINE explicit static_vector(size_type count) - : base_t(count) - {} - - //! @pre count <= capacity() - //! - //! @brief Constructs a static_vector containing count default initialized values. - //! - //! @param count The number of values which will be contained in the container. - //! - //! @par Throws - //! @li If T's default initialization throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - //! - //! @par Note - //! Non-standard extension - BOOST_CONTAINER_FORCEINLINE static_vector(size_type count, default_init_t) - : base_t(count, default_init_t()) - {} - - //! @pre count <= capacity() - //! - //! @brief Constructs a static_vector containing count copies of value. - //! - //! @param count The number of copies of a values that will be contained in the container. - //! @param value The value which will be used to copy construct values. - //! - //! @par Throws - //! @li If T's copy constructor throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - BOOST_CONTAINER_FORCEINLINE static_vector(size_type count, value_type const& value) - : base_t(count, value) - {} - - //! @pre - //! @li distance(first, last) <= capacity() - //! @li Iterator must meet the \c ForwardTraversalIterator concept. - //! - //! @brief Constructs a static_vector containing copy of a range [first, last). - //! - //! @param first The iterator to the first element in range. - //! @param last The iterator to the one after the last element in range. - //! - //! @par Throws - //! @li If T's constructor taking a dereferenced Iterator throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - template - BOOST_CONTAINER_FORCEINLINE static_vector(Iterator first, Iterator last) - : base_t(first, last) - {} - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! @pre - //! @li distance(il.begin(), il.end()) <= capacity() - //! - //! @brief Constructs a static_vector containing copy of a range [il.begin(), il.end()). - //! - //! @param il std::initializer_list with values to initialize vector. - //! - //! @par Throws - //! @li If T's constructor taking a dereferenced std::initializer_list throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - BOOST_CONTAINER_FORCEINLINE static_vector(std::initializer_list il) - : base_t(il) - {} -#endif - - //! @brief Constructs a copy of other static_vector. - //! - //! @param other The static_vector which content will be copied to this one. - //! - //! @par Throws - //! If T's copy constructor throws. - //! - //! @par Complexity - //! Linear O(N). - BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other) - : base_t(other) - {} - - BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other, const allocator_type &) - : base_t(other) - {} - - BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF(static_vector) other, const allocator_type &) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : base_t(BOOST_MOVE_BASE(base_t, other)) - {} - - BOOST_CONTAINER_FORCEINLINE explicit static_vector(const allocator_type &) - : base_t() - {} - - //! @pre other.size() <= capacity(). - //! - //! @brief Constructs a copy of other static_vector. - //! - //! @param other The static_vector which content will be copied to this one. - //! - //! @par Throws - //! @li If T's copy constructor throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - template - BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other) - : base_t(other) - {} - - //! @brief Move constructor. Moves Values stored in the other static_vector to this one. - //! - //! @param other The static_vector which content will be moved to this one. - //! - //! @par Throws - //! @li If \c has_nothrow_move::value is \c true and T's move constructor throws. - //! @li If \c has_nothrow_move::value is \c false and T's copy constructor throws. - //! - //! @par Complexity - //! Linear O(N). - BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF(static_vector) other) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible::value) - : base_t(BOOST_MOVE_BASE(base_t, other)) - {} - - //! @pre other.size() <= capacity() - //! - //! @brief Move constructor. Moves Values stored in the other static_vector to this one. - //! - //! @param other The static_vector which content will be moved to this one. - //! - //! @par Throws - //! @li If \c has_nothrow_move::value is \c true and T's move constructor throws. - //! @li If \c has_nothrow_move::value is \c false and T's copy constructor throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - template - BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF_BEG static_vector BOOST_RV_REF_END other) - : base_t(BOOST_MOVE_BASE(typename static_vector::base_t, other)) - {} - - //! @brief Copy assigns Values stored in the other static_vector to this one. - //! - //! @param other The static_vector which content will be copied to this one. - //! - //! @par Throws - //! If T's copy constructor or copy assignment throws. - //! - //! @par Complexity - //! Linear O(N). - BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_COPY_ASSIGN_REF(static_vector) other) - { - return static_cast(base_t::operator=(static_cast(other))); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - //! @brief Copy assigns Values stored in std::initializer_list to *this. - //! - //! @param il The std::initializer_list which content will be copied to this one. - //! - //! @par Throws - //! @li If T's copy constructor or copy assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - BOOST_CONTAINER_FORCEINLINE static_vector & operator=(std::initializer_list il) - { return static_cast(base_t::operator=(il)); } -#endif - - //! @pre other.size() <= capacity() - //! - //! @brief Copy assigns Values stored in the other static_vector to this one. - //! - //! @param other The static_vector which content will be copied to this one. - //! - //! @par Throws - //! @li If T's copy constructor or copy assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - template - BOOST_CONTAINER_FORCEINLINE static_vector & operator=(static_vector const& other) - { - return static_cast(base_t::operator= - (static_cast::base_t const&>(other))); - } - - //! @brief Move assignment. Moves Values stored in the other static_vector to this one. - //! - //! @param other The static_vector which content will be moved to this one. - //! - //! @par Throws - //! @li If \c has_nothrow_move::value is \c true and T's move constructor or move assignment throws. - //! @li If \c has_nothrow_move::value is \c false and T's copy constructor or copy assignment throws. - //! - //! @par Complexity - //! Linear O(N). - BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF(static_vector) other) - BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_assignable::value) - { - return static_cast(base_t::operator=(BOOST_MOVE_BASE(base_t, other))); - } - - //! @pre other.size() <= capacity() - //! - //! @brief Move assignment. Moves Values stored in the other static_vector to this one. - //! - //! @param other The static_vector which content will be moved to this one. - //! - //! @par Throws - //! @li If \c has_nothrow_move::value is \c true and T's move constructor or move assignment throws. - //! @li If \c has_nothrow_move::value is \c false and T's copy constructor or copy assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - template - BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF_BEG static_vector BOOST_RV_REF_END other) - { - return static_cast(base_t::operator= - (BOOST_MOVE_BASE(typename static_vector::base_t, other))); - } - -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - - //! @brief Destructor. Destroys Values stored in this container. - //! - //! @par Throws - //! Nothing - //! - //! @par Complexity - //! Linear O(N). - ~static_vector(); - - //! @brief Swaps contents of the other static_vector and this one. - //! - //! @param other The static_vector which content will be swapped with this one's content. - //! - //! @par Throws - //! @li If \c has_nothrow_move::value is \c true and T's move constructor or move assignment throws, - //! @li If \c has_nothrow_move::value is \c false and T's copy constructor or copy assignment throws, - //! - //! @par Complexity - //! Linear O(N). - void swap(static_vector & other); - - //! @pre other.size() <= capacity() && size() <= other.capacity() - //! - //! @brief Swaps contents of the other static_vector and this one. - //! - //! @param other The static_vector which content will be swapped with this one's content. - //! - //! @par Throws - //! @li If \c has_nothrow_move::value is \c true and T's move constructor or move assignment throws, - //! @li If \c has_nothrow_move::value is \c false and T's copy constructor or copy assignment throws, - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - template - void swap(static_vector & other); - - //! @pre count <= capacity() - //! - //! @brief Inserts or erases elements at the end such that - //! the size becomes count. New elements are value initialized. - //! - //! @param count The number of elements which will be stored in the container. - //! - //! @par Throws - //! @li If T's value initialization throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - void resize(size_type count); - - //! @pre count <= capacity() - //! - //! @brief Inserts or erases elements at the end such that - //! the size becomes count. New elements are default initialized. - //! - //! @param count The number of elements which will be stored in the container. - //! - //! @par Throws - //! @li If T's default initialization throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - //! - //! @par Note - //! Non-standard extension - void resize(size_type count, default_init_t); - - //! @pre count <= capacity() - //! - //! @brief Inserts or erases elements at the end such that - //! the size becomes count. New elements are copy constructed from value. - //! - //! @param count The number of elements which will be stored in the container. - //! @param value The value used to copy construct the new element. - //! - //! @par Throws - //! @li If T's copy constructor throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - void resize(size_type count, value_type const& value); - - //! @pre count <= capacity() - //! - //! @brief This call has no effect because the Capacity of this container is constant. - //! - //! @param count The number of elements which the container should be able to contain. - //! - //! @par Throws - //! If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Constant O(1). - void reserve(size_type count); - - //! @pre size() < capacity() - //! - //! @brief Adds a copy of value at the end. - //! - //! @param value The value used to copy construct the new element. - //! - //! @par Throws - //! @li If T's copy constructor throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Constant O(1). - void push_back(value_type const& value); - - //! @pre size() < capacity() - //! - //! @brief Moves value to the end. - //! - //! @param value The value to move construct the new element. - //! - //! @par Throws - //! @li If T's move constructor throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Constant O(1). - void push_back(BOOST_RV_REF(value_type) value); - - //! @pre !empty() - //! - //! @brief Destroys last value and decreases the size. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - void pop_back() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre - //! @li \c p must be a valid iterator of \c *this in range [begin(), end()]. - //! @li size() < capacity() - //! - //! @brief Inserts a copy of element at p. - //! - //! @param p The position at which the new value will be inserted. - //! @param value The value used to copy construct the new element. - //! - //! @par Throws - //! @li If T's copy constructor or copy assignment throws - //! @li If T's move constructor or move assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Constant or linear. - iterator insert(const_iterator p, value_type const& value); - - //! @pre - //! @li \c p must be a valid iterator of \c *this in range [begin(), end()]. - //! @li size() < capacity() - //! - //! @brief Inserts a move-constructed element at p. - //! - //! @param p The position at which the new value will be inserted. - //! @param value The value used to move construct the new element. - //! - //! @par Throws - //! @li If T's move constructor or move assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Constant or linear. - iterator insert(const_iterator p, BOOST_RV_REF(value_type) value); - - //! @pre - //! @li \c p must be a valid iterator of \c *this in range [begin(), end()]. - //! @li size() + count <= capacity() - //! - //! @brief Inserts a count copies of value at p. - //! - //! @param p The position at which new elements will be inserted. - //! @param count The number of new elements which will be inserted. - //! @param value The value used to copy construct new elements. - //! - //! @par Throws - //! @li If T's copy constructor or copy assignment throws. - //! @li If T's move constructor or move assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - iterator insert(const_iterator p, size_type count, value_type const& value); - - //! @pre - //! @li \c p must be a valid iterator of \c *this in range [begin(), end()]. - //! @li distance(first, last) <= capacity() - //! @li \c Iterator must meet the \c ForwardTraversalIterator concept. - //! - //! @brief Inserts a copy of a range [first, last) at p. - //! - //! @param p The position at which new elements will be inserted. - //! @param first The iterator to the first element of a range used to construct new elements. - //! @param last The iterator to the one after the last element of a range used to construct new elements. - //! - //! @par Throws - //! @li If T's constructor and assignment taking a dereferenced \c Iterator. - //! @li If T's move constructor or move assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - template - iterator insert(const_iterator p, Iterator first, Iterator last); - - //! @pre - //! @li \c p must be a valid iterator of \c *this in range [begin(), end()]. - //! @li distance(il.begin(), il.end()) <= capacity() - //! - //! @brief Inserts a copy of a range [il.begin(), il.end()) at p. - //! - //! @param p The position at which new elements will be inserted. - //! @param il The std::initializer_list which contains elements that will be inserted. - //! - //! @par Throws - //! @li If T's constructor and assignment taking a dereferenced std::initializer_list iterator. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - iterator insert(const_iterator p, std::initializer_list il); - - //! @pre \c p must be a valid iterator of \c *this in range [begin(), end()) - //! - //! @brief Erases T from p. - //! - //! @param p The position of the element which will be erased from the container. - //! - //! @par Throws - //! If T's move assignment throws. - //! - //! @par Complexity - //! Linear O(N). - iterator erase(const_iterator p); - - //! @pre - //! @li \c first and \c last must define a valid range - //! @li iterators must be in range [begin(), end()] - //! - //! @brief Erases Values from a range [first, last). - //! - //! @param first The position of the first element of a range which will be erased from the container. - //! @param last The position of the one after the last element of a range which will be erased from the container. - //! - //! @par Throws - //! If T's move assignment throws. - //! - //! @par Complexity - //! Linear O(N). - iterator erase(const_iterator first, const_iterator last); - - //! @pre distance(first, last) <= capacity() - //! - //! @brief Assigns a range [first, last) of Values to this container. - //! - //! @param first The iterator to the first element of a range used to construct new content of this container. - //! @param last The iterator to the one after the last element of a range used to construct new content of this container. - //! - //! @par Throws - //! @li If T's copy constructor or copy assignment throws, - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - template - void assign(Iterator first, Iterator last); - - //! @pre distance(il.begin(), il.end()) <= capacity() - //! - //! @brief Assigns a range [il.begin(), il.end()) of Values to this container. - //! - //! @param il std::initializer_list with values used to construct new content of this container. - //! - //! @par Throws - //! @li If T's copy constructor or copy assignment throws, - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - void assign(std::initializer_list il); - - //! @pre count <= capacity() - //! - //! @brief Assigns a count copies of value to this container. - //! - //! @param count The new number of elements which will be container in the container. - //! @param value The value which will be used to copy construct the new content. - //! - //! @par Throws - //! @li If T's copy constructor or copy assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Linear O(N). - void assign(size_type count, value_type const& value); - - //! @pre size() < capacity() - //! - //! @brief Inserts a T constructed with - //! \c std::forward(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 - //! @li If in-place constructor throws or T's move constructor throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Constant O(1). - template - reference emplace_back(Args &&...args); - - //! @pre - //! @li \c p must be a valid iterator of \c *this in range [begin(), end()] - //! @li size() < capacity() - //! - //! @brief Inserts a T constructed with - //! \c std::forward(args)... before p - //! - //! @param p The position at which new elements will be inserted. - //! @param args The arguments of the constructor of the new element. - //! - //! @par Throws - //! @li If in-place constructor throws or if T's move constructor or move assignment throws. - //! @li If \c throw_on_overflow option is set and the container runs out of capacity. - //! - //! @par Complexity - //! Constant or linear. - template - iterator emplace(const_iterator p, Args &&...args); - - //! @brief Removes all elements from the container. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - void clear() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre i < size() - //! - //! @brief Returns reference to the i-th element. - //! - //! @param i The element's index. - //! - //! @return reference to the i-th element - //! from the beginning of the container. - //! - //! @par Throws - //! \c out_of_range exception by default. - //! - //! @par Complexity - //! Constant O(1). - reference at(size_type i); - - //! @pre i < size() - //! - //! @brief Returns const reference to the i-th element. - //! - //! @param i The element's index. - //! - //! @return const reference to the i-th element - //! from the beginning of the container. - //! - //! @par Throws - //! \c out_of_range exception by default. - //! - //! @par Complexity - //! Constant O(1). - const_reference at(size_type i) const; - - //! @pre i < size() - //! - //! @brief Returns reference to the i-th element. - //! - //! @param i The element's index. - //! - //! @return reference to the i-th element - //! from the beginning of the container. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - reference operator[](size_type i) BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre i < size() - //! - //! @brief Returns const reference to the i-th element. - //! - //! @param i The element's index. - //! - //! @return const reference to the i-th element - //! from the beginning of the container. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_reference operator[](size_type i) const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre i =< size() - //! - //! @brief Returns a iterator to the i-th element. - //! - //! @param i The element's index. - //! - //! @return a iterator to the i-th element. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - iterator nth(size_type i) BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre i =< size() - //! - //! @brief Returns a const_iterator to the i-th element. - //! - //! @param i The element's index. - //! - //! @return a const_iterator to the i-th element. - //! - //! @par Throws - //! Nothing by default. - //! - //! @par Complexity - //! Constant O(1). - const_iterator nth(size_type i) const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre begin() <= p <= end() - //! - //! @brief Returns the index of the element pointed by p. - //! - //! @param p An iterator to the element. - //! - //! @return The index of the element pointed by p. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre begin() <= p <= end() - //! - //! @brief Returns 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. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre \c !empty() - //! - //! @brief Returns reference to the first element. - //! - //! @return reference to the first element - //! from the beginning of the container. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - reference front() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre \c !empty() - //! - //! @brief Returns const reference to the first element. - //! - //! @return const reference to the first element - //! from the beginning of the container. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre \c !empty() - //! - //! @brief Returns reference to the last element. - //! - //! @return reference to the last element - //! from the beginning of the container. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - reference back() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @pre \c !empty() - //! - //! @brief Returns const reference to the first element. - //! - //! @return const reference to the last element - //! from the beginning of the container. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Pointer such that [data(), data() + size()) is a valid range. - //! For a non-empty vector data() == &front(). - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - T * data() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Const pointer such that [data(), data() + size()) is a valid range. - //! For a non-empty vector data() == &front(). - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const T * data() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns iterator to the first element. - //! - //! @return iterator to the first element contained in the vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns const iterator to the first element. - //! - //! @return const_iterator to the first element contained in the vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns const iterator to the first element. - //! - //! @return const_iterator to the first element contained in the vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns iterator to the one after the last element. - //! - //! @return iterator pointing to the one after the last element contained in the vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - iterator end() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns const iterator to the one after the last element. - //! - //! @return const_iterator pointing to the one after the last element contained in the vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns const iterator to the one after the last element. - //! - //! @return const_iterator pointing to the one after the last element contained in the vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns reverse iterator to the first element of the reversed container. - //! - //! @return reverse_iterator pointing to the beginning - //! of the reversed static_vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns const reverse iterator to the first element of the reversed container. - //! - //! @return const_reverse_iterator pointing to the beginning - //! of the reversed static_vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns const reverse iterator to the first element of the reversed container. - //! - //! @return const_reverse_iterator pointing to the beginning - //! of the reversed static_vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns reverse iterator to the one after the last element of the reversed container. - //! - //! @return reverse_iterator pointing to the one after the last element - //! of the reversed static_vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns const reverse iterator to the one after the last element of the reversed container. - //! - //! @return const_reverse_iterator pointing to the one after the last element - //! of the reversed static_vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Returns const reverse iterator to the one after the last element of the reversed container. - //! - //! @return const_reverse_iterator pointing to the one after the last element - //! of the reversed static_vector. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW; - - #endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - - //! @brief Returns container's capacity. - //! - //! @return container's capacity. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - BOOST_CONTAINER_FORCEINLINE static size_type capacity() BOOST_NOEXCEPT_OR_NOTHROW - { return static_capacity; } - - //! @brief Returns container's capacity. - //! - //! @return container's capacity. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - BOOST_CONTAINER_FORCEINLINE static size_type max_size() BOOST_NOEXCEPT_OR_NOTHROW - { return static_capacity; } - - #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - - //! @brief Returns the number of stored elements. - //! - //! @return Number of elements contained in the container. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW; - - //! @brief Queries if the container contains elements. - //! - //! @return true if the number of elements contained in the - //! container is equal to 0. - //! - //! @par Throws - //! Nothing. - //! - //! @par Complexity - //! Constant O(1). - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW; -#else - - BOOST_CONTAINER_FORCEINLINE friend void swap(static_vector &x, static_vector &y) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) - { - x.swap(y); - } - -#endif // BOOST_CONTAINER_DOXYGEN_INVOKED - -}; - -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! @brief Checks if contents of two static_vectors are equal. -//! -//! @ingroup static_vector_non_member -//! -//! @param x The first static_vector. -//! @param y The second static_vector. -//! -//! @return \c true if containers have the same size and elements in both containers are equal. -//! -//! @par Complexity -//! Linear O(N). -template -bool operator== (static_vector const& x, static_vector const& y); - -//! @brief Checks if contents of two static_vectors are not equal. -//! -//! @ingroup static_vector_non_member -//! -//! @param x The first static_vector. -//! @param y The second static_vector. -//! -//! @return \c true if containers have different size or elements in both containers are not equal. -//! -//! @par Complexity -//! Linear O(N). -template -bool operator!= (static_vector const& x, static_vector const& y); - -//! @brief Lexicographically compares static_vectors. -//! -//! @ingroup static_vector_non_member -//! -//! @param x The first static_vector. -//! @param y The second static_vector. -//! -//! @return \c true if x compares lexicographically less than y. -//! -//! @par Complexity -//! Linear O(N). -template -bool operator< (static_vector const& x, static_vector const& y); - -//! @brief Lexicographically compares static_vectors. -//! -//! @ingroup static_vector_non_member -//! -//! @param x The first static_vector. -//! @param y The second static_vector. -//! -//! @return \c true if y compares lexicographically less than x. -//! -//! @par Complexity -//! Linear O(N). -template -bool operator> (static_vector const& x, static_vector const& y); - -//! @brief Lexicographically compares static_vectors. -//! -//! @ingroup static_vector_non_member -//! -//! @param x The first static_vector. -//! @param y The second static_vector. -//! -//! @return \c true if y don't compare lexicographically less than x. -//! -//! @par Complexity -//! Linear O(N). -template -bool operator<= (static_vector const& x, static_vector const& y); - -//! @brief Lexicographically compares static_vectors. -//! -//! @ingroup static_vector_non_member -//! -//! @param x The first static_vector. -//! @param y The second static_vector. -//! -//! @return \c true if x don't compare lexicographically less than y. -//! -//! @par Complexity -//! Linear O(N). -template -bool operator>= (static_vector const& x, static_vector const& y); - -//! @brief Swaps contents of two static_vectors. -//! -//! This function calls static_vector::swap(). -//! -//! @ingroup static_vector_non_member -//! -//! @param x The first static_vector. -//! @param y The second static_vector. -//! -//! @par Complexity -//! Linear O(N). -template -inline void swap(static_vector & x, static_vector & y) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))); - -#else - -template -inline void swap(static_vector & x, static_vector & y - , typename dtl::enable_if_c< C1 != C2>::type * = 0) - BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) -{ - x.swap(y); -} - -#endif // BOOST_CONTAINER_DOXYGEN_INVOKED - -}} // namespace boost::container - -#include - -#endif // BOOST_CONTAINER_STATIC_VECTOR_HPP diff --git a/inst/i/b/container/string.hpp b/inst/i/b/container/string.hpp deleted file mode 100644 index 84e204af0..000000000 --- a/inst/i/b/container/string.hpp +++ /dev/null @@ -1,3625 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (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) -// -// See http://www.boost.org/libs/container for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_CONTAINER_STRING_HPP -#define BOOST_CONTAINER_STRING_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -#include -// container -#include -#include //new_allocator -#include -// container/detail -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // for char_traits -//intrusive -#include -#include -#include -//move -#include -#include -#include - -#include - -#include -#include // -#include -#include -#include -#include -#include - -//std -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include //for std::initializer_list -#endif - -//GCC 12 has a regression for array-bounds warnings -#if defined(BOOST_GCC) && (BOOST_GCC >= 120000) && (BOOST_GCC < 130000) -#pragma GCC diagnostic push -//#pragma GCC diagnostic ignored "-Warray-bounds" -#endif - - -namespace boost { -namespace container { - -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -namespace dtl { -// ------------------------------------------------------------ -// Class basic_string_base. - -// basic_string_base is a helper class that makes it it easier to write -// an exception-safe version of basic_string. The constructor allocates, -// but does not initialize, a block of memory. The destructor -// deallocates, but does not destroy elements within, a block of -// memory. The destructor assumes that the memory either is the internal buffer, -// or else points to a block of memory that was allocated using string_base's -// allocator and whose size is this->m_storage. -template -class basic_string_base -{ - basic_string_base & operator=(const basic_string_base &); - basic_string_base(const basic_string_base &); - - typedef Allocator allocator_type; - public: - typedef allocator_traits allocator_traits_type; - typedef allocator_type stored_allocator_type; - typedef typename allocator_traits_type::pointer pointer; - typedef typename allocator_traits_type::value_type value_type; - typedef typename allocator_traits_type::size_type size_type; - typedef typename allocator_traits_type::difference_type difference_type; - - typedef ::boost::intrusive::pointer_traits pointer_traits; - - BOOST_CONTAINER_FORCEINLINE basic_string_base() - : members_() - {} - - BOOST_CONTAINER_FORCEINLINE explicit basic_string_base(const allocator_type& a) - : members_(a) - {} - - BOOST_CONTAINER_FORCEINLINE explicit basic_string_base(BOOST_RV_REF(allocator_type) a) - : members_(boost::move(a)) - {} - - BOOST_CONTAINER_FORCEINLINE basic_string_base(const allocator_type& a, size_type n) - : members_(a) - { - this->allocate_initial_block(n); - } - - BOOST_CONTAINER_FORCEINLINE explicit basic_string_base(size_type n) - : members_() - { - this->allocate_initial_block(n); - } - - BOOST_CONTAINER_FORCEINLINE ~basic_string_base() - { - if(!this->is_short()){ - this->deallocate(this->priv_long_addr(), this->priv_long_storage()); - } - } - - private: - - #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) - #pragma GCC diagnostic push - // #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" - #endif - - //This is the structure controlling a long string - struct long_t - { - size_type is_short : 1; - size_type length : (sizeof(size_type)*CHAR_BIT - 1); - size_type storage; - pointer start; - - BOOST_CONTAINER_FORCEINLINE long_t() - : is_short(0) - {} - - BOOST_CONTAINER_FORCEINLINE long_t(size_type len, size_type stor, pointer ptr) - : is_short(0), length(len), storage(stor), start(ptr) - {} - - BOOST_CONTAINER_FORCEINLINE long_t(const long_t &other) - { - this->is_short = false; - length = other.length; - storage = other.storage; - start = other.start; - } - - BOOST_CONTAINER_FORCEINLINE long_t &operator= (const long_t &other) - { - length = other.length; - storage = other.storage; - start = other.start; - return *this; - } - }; - - #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) - #pragma GCC diagnostic pop - #endif - - - //This type is the first part of the structure controlling a short string - //The "data" member stores - struct short_header - { - unsigned char is_short : 1; - unsigned char length : (CHAR_BIT - 1); - }; - - //This type has the same alignment and size as long_t but it's POD - //so, unlike long_t, it can be placed in a union - - typedef typename dtl::aligned_storage - ::value>::type long_raw_t; - - protected: - static const size_type MinInternalBufferChars = 8; - static const size_type AlignmentOfValueType = - alignment_of::value; - static const size_type ShortDataOffset = ((sizeof(short_header)-1)/AlignmentOfValueType+1)*AlignmentOfValueType; - static const size_type ZeroCostInternalBufferChars = - (sizeof(long_t) - ShortDataOffset)/sizeof(value_type); - static const size_type UnalignedFinalInternalBufferChars = - (ZeroCostInternalBufferChars > MinInternalBufferChars) ? - ZeroCostInternalBufferChars : MinInternalBufferChars; - - struct short_t - { - short_header h; - value_type data[UnalignedFinalInternalBufferChars]; - }; - - union repr_t_size_t - { - long_raw_t r; - short_t s; - }; - - union repr_t - { - long_raw_t r_aligner; - short_t s_aligner; - unsigned char data[sizeof(repr_t_size_t)]; - }; - - struct members_holder - : public allocator_type - { - BOOST_CONTAINER_FORCEINLINE void init() - { - short_t &s = *::new(this->m_repr.data) short_t; - s.h.is_short = 1; - s.h.length = 0; - } - - BOOST_CONTAINER_FORCEINLINE members_holder() - : allocator_type() - { this->init(); } - - template - BOOST_CONTAINER_FORCEINLINE explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a) - : allocator_type(boost::forward(a)) - { this->init(); } - - BOOST_CONTAINER_FORCEINLINE const short_t *pshort_repr() const - { return move_detail::force_ptr(m_repr.data); } - - BOOST_CONTAINER_FORCEINLINE const long_t *plong_repr() const - { return move_detail::force_ptr(m_repr.data); } - - BOOST_CONTAINER_FORCEINLINE short_t *pshort_repr() - { return move_detail::force_ptr(m_repr.data); } - - BOOST_CONTAINER_FORCEINLINE long_t *plong_repr() - { return move_detail::force_ptr(m_repr.data); } - - repr_t m_repr; - } members_; - - BOOST_CONTAINER_FORCEINLINE const allocator_type &alloc() const - { return members_; } - - BOOST_CONTAINER_FORCEINLINE allocator_type &alloc() - { return members_; } - - static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type); - - private: - - static const size_type MinAllocation = InternalBufferChars*2; - - protected: - BOOST_CONTAINER_FORCEINLINE bool is_short() const - { - //Access and copy (to avoid UB) the first byte of the union to know if the - //active representation is short or long - short_header hdr; - BOOST_STATIC_ASSERT((sizeof(short_header) == 1)); - *(unsigned char*)&hdr = *(unsigned char*)&this->members_.m_repr; - return hdr.is_short != 0; - } - - BOOST_CONTAINER_FORCEINLINE short_t *construct_short() - { - short_t *ps = ::new(this->members_.m_repr.data) short_t; - ps->h.is_short = 1; - return ps; - } - - BOOST_CONTAINER_FORCEINLINE void destroy_short() - { - BOOST_ASSERT(this->is_short()); - this->members_.pshort_repr()->~short_t(); - } - - short_t *assure_short() - { - if (!this->is_short()){ - this->destroy_long(); - return construct_short(); - } - return this->members_.pshort_repr(); - } - - BOOST_CONTAINER_FORCEINLINE long_t *construct_long() - { - long_t *pl = ::new(this->members_.m_repr.data) long_t; - //is_short flag is written in the constructor - return pl; - } - - BOOST_CONTAINER_FORCEINLINE void destroy_long() - { - BOOST_ASSERT(!this->is_short()); - this->members_.plong_repr()->~long_t(); - } - - long_t *assure_long() - { - if (this->is_short()){ - this->destroy_short(); - return this->construct_long(); - } - return this->members_.plong_repr(); - } - - - protected: - - typedef dtl::integral_constant::value> alloc_version; - - pointer allocation_command(allocation_type command, - size_type limit_size, - size_type &prefer_in_recvd_out_size, - pointer &reuse) - { - if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){ - reuse = 0; - command &= ~(expand_fwd | expand_bwd); - } - return dtl::allocator_version_traits::allocation_command - (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse); - } - - size_type next_capacity(size_type additional_objects) const - { - return growth_factor_100() - ( this->priv_storage(), additional_objects, allocator_traits_type::max_size(this->alloc())); - } - - void deallocate(pointer p, size_type n) - { - if (p && (n > InternalBufferChars)) - this->alloc().deallocate(p, n); - } - - BOOST_CONTAINER_FORCEINLINE void construct(pointer p, const value_type &value = value_type()) - { - allocator_traits_type::construct - ( this->alloc() - , boost::movelib::to_raw_pointer(p) - , value - ); - } - - void destroy(pointer p, size_type n) - { - value_type *raw_p = boost::movelib::to_raw_pointer(p); - for(; n--; ++raw_p){ - allocator_traits_type::destroy( this->alloc(), raw_p); - } - } - - BOOST_CONTAINER_FORCEINLINE void destroy(pointer p) - { - allocator_traits_type::destroy - ( this->alloc() - , boost::movelib::to_raw_pointer(p) - ); - } - - void allocate_initial_block(size_type n) - { - if (n <= this->max_size()) { - if(n > InternalBufferChars){ - size_type new_cap = this->next_capacity(n); - pointer reuse = 0; - pointer p = this->allocation_command(allocate_new, n, new_cap, reuse); - BOOST_ASSERT(this->is_short()); - this->construct_long(); - this->priv_long_addr(p); - this->priv_long_size(0); - this->priv_storage(new_cap); - } - } - else{ - throw_length_error("basic_string::allocate_initial_block max_size() exceeded"); - } - } - - BOOST_CONTAINER_FORCEINLINE void deallocate_block() - { this->deallocate(this->priv_addr(), this->priv_storage()); } - - BOOST_CONTAINER_FORCEINLINE size_type max_size() const - { return allocator_traits_type::max_size(this->alloc()) - 1; } - - protected: - BOOST_CONTAINER_FORCEINLINE size_type priv_capacity() const - { return this->priv_storage() - 1; } - - BOOST_CONTAINER_FORCEINLINE pointer priv_short_addr() const - { return pointer_traits::pointer_to(const_cast(this->members_.pshort_repr()->data[0])); } - - //GCC seems a bit confused about uninitialized accesses - #if defined(BOOST_GCC) && (BOOST_GCC >= 40700) - #pragma GCC diagnostic push - // #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" - #endif - - BOOST_CONTAINER_FORCEINLINE pointer priv_long_addr() const - { return this->members_.plong_repr()->start; } - - BOOST_CONTAINER_FORCEINLINE pointer priv_addr() const - { - return this->is_short() - ? priv_short_addr() - : priv_long_addr() - ; - } - - BOOST_CONTAINER_FORCEINLINE pointer priv_end_addr() const - { - return this->is_short() - ? this->priv_short_addr() + difference_type(this->priv_short_size()) - : this->priv_long_addr() + difference_type(this->priv_long_size()) - ; - } - - BOOST_CONTAINER_FORCEINLINE void priv_long_addr(pointer addr) - { this->members_.plong_repr()->start = addr; } - - BOOST_CONTAINER_FORCEINLINE size_type priv_storage() const - { return this->is_short() ? priv_short_storage() : priv_long_storage(); } - - BOOST_CONTAINER_FORCEINLINE size_type priv_short_storage() const - { return InternalBufferChars; } - - BOOST_CONTAINER_FORCEINLINE size_type priv_long_storage() const - { return this->members_.plong_repr()->storage; } - - BOOST_CONTAINER_FORCEINLINE void priv_storage(size_type storage) - { - if(!this->is_short()) - this->priv_long_storage(storage); - } - - BOOST_CONTAINER_FORCEINLINE void priv_long_storage(size_type storage) - { - this->members_.plong_repr()->storage = storage; - } - - BOOST_CONTAINER_FORCEINLINE size_type priv_size() const - { return this->is_short() ? this->priv_short_size() : this->priv_long_size(); } - - BOOST_CONTAINER_FORCEINLINE size_type priv_short_size() const - { return this->members_.pshort_repr()->h.length; } - - BOOST_CONTAINER_FORCEINLINE size_type priv_long_size() const - { return this->members_.plong_repr()->length; } - - BOOST_CONTAINER_FORCEINLINE void priv_size(size_type sz) - { - if(this->is_short()) - this->priv_short_size(sz); - else - this->priv_long_size(sz); - } - - BOOST_CONTAINER_FORCEINLINE void priv_short_size(size_type sz) - { - typedef unsigned char uchar_type; - static const uchar_type mask = uchar_type(uchar_type(-1) >> 1U); - BOOST_ASSERT( sz <= mask ); - //Make -Wconversion happy - this->members_.pshort_repr()->h.length = uchar_type(uchar_type(sz) & mask); - } - - BOOST_CONTAINER_FORCEINLINE void priv_long_size(size_type sz) - { - static const size_type mask = size_type(-1) >> 1U; - BOOST_ASSERT( sz <= mask ); - //Make -Wconversion happy - this->members_.plong_repr()->length = sz & mask; - } - #if defined(BOOST_GCC) && (BOOST_GCC >= 40700) - #pragma GCC diagnostic pop - #endif - - void swap_data(basic_string_base& other) - { - if(this->is_short()){ - if(other.is_short()){ - repr_t tmp(this->members_.m_repr); - this->members_.m_repr = other.members_.m_repr; - other.members_.m_repr = tmp; - } - else{ - short_t short_backup(*this->members_.pshort_repr()); - this->members_.pshort_repr()->~short_t(); - ::new(this->members_.plong_repr()) long_t(*other.members_.plong_repr()); - other.members_.plong_repr()->~long_t(); - ::new(other.members_.pshort_repr()) short_t(short_backup); - } - } - else{ - if(other.is_short()){ - short_t short_backup(*other.members_.pshort_repr()); - other.members_.pshort_repr()->~short_t(); - ::new(other.members_.plong_repr()) long_t(*this->members_.plong_repr()); - this->members_.plong_repr()->~long_t(); - ::new(this->members_.pshort_repr()) short_t(short_backup); - } - else{ - boost::adl_move_swap(*this->members_.plong_repr(), *other.members_.plong_repr()); - } - } - } -}; - -} //namespace dtl { - -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -//! The basic_string class represents a Sequence of characters. It contains all the -//! usual operations of a Sequence, and, additionally, it contains standard string -//! operations such as search and concatenation. -//! -//! The basic_string class is parameterized by character type, and by that type's -//! Character Traits. -//! -//! This class has performance characteristics very much like vector<>, meaning, -//! for example, that it does not perform reference-count or copy-on-write, and that -//! concatenation of two strings is an O(N) operation. -//! -//! Some of basic_string's member functions use an unusual method of specifying positions -//! and ranges. In addition to the conventional method using iterators, many of -//! basic_string's member functions use a single value pos of type size_type to represent a -//! position (in which case the position is begin() + pos, and many of basic_string's -//! member functions use two values, pos and n, to represent a range. In that case pos is -//! the beginning of the range and n is its size. That is, the range is -//! [begin() + pos, begin() + pos + n). -//! -//! Note that the C++ standard does not specify the complexity of basic_string operations. -//! In this implementation, basic_string has performance characteristics very similar to -//! those of vector: access to a single character is O(1), while copy and concatenation -//! are O(N). -//! -//! In this implementation, begin(), -//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators. -//! In this implementation, iterators are only invalidated by member functions that -//! explicitly change the string's contents. -//! -//! \tparam CharT The type of character it contains. -//! \tparam Traits The Character Traits type, which encapsulates basic character operations -//! \tparam Allocator The allocator, used for internal memory management. -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class Allocator = void > -#else -template -#endif -class basic_string - : private dtl::basic_string_base::type> -{ - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - BOOST_COPYABLE_AND_MOVABLE(basic_string) - typedef dtl::basic_string_base::type> base_t; - typedef typename base_t::allocator_traits_type allocator_traits_type; - static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars; - - protected: - // Allocator helper class to use a char_traits as a function object. - - template - struct Eq_traits - { - //Compatibility with std::binary_function - typedef typename Tr::char_type first_argument_type; - typedef typename Tr::char_type second_argument_type; - typedef bool result_type; - - bool operator()(const first_argument_type& x, const second_argument_type& y) const - { return Tr::eq(x, y); } - }; - - template - struct Not_within_traits - { - typedef typename Tr::char_type argument_type; - typedef bool result_type; - - typedef const typename Tr::char_type* Pointer; - const Pointer m_first; - const Pointer m_last; - - Not_within_traits(Pointer f, Pointer l) - : m_first(f), m_last(l) {} - - bool operator()(const typename Tr::char_type& x) const - { - return boost::container::find_if(m_first, m_last, - boost::container::bind1st(Eq_traits(), x)) == m_last; - } - }; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - typedef Traits traits_type; - typedef CharT value_type; - typedef typename real_allocator::type allocator_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(pointer) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; - static const size_type npos = size_type(-1); - - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - typedef constant_iterator cvalue_iterator; - typedef typename base_t::alloc_version alloc_version; - typedef ::boost::intrusive::pointer_traits pointer_traits; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - public: // Constructor, destructor, assignment. - ////////////////////////////////////////////// - // - // construct/copy/destroy - // - ////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - struct reserve_t {}; - - basic_string(reserve_t, size_type n, - const allocator_type& a = allocator_type()) - //Select allocator as in copy constructor as reserve_t-based constructors - //are two step copies optimized for capacity - : base_t( allocator_traits_type::select_on_container_copy_construction(a) - , n + 1) - { this->priv_terminate_string(); } - - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - - //! Effects: Default constructs a basic_string. - //! - //! Throws: If allocator_type's default constructor throws. - basic_string() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) - : base_t() - { this->priv_terminate_string(); } - - - //! Effects: Constructs a basic_string taking the allocator as parameter. - //! - //! Throws: Nothing - explicit basic_string(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW - : base_t(a) - { this->priv_terminate_string(); } - - //! Effects: Copy constructs a basic_string. - //! - //! Postcondition: x == *this. - //! - //! Throws: If allocator_type's default constructor or allocation throws. - basic_string(const basic_string& s) - : base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc())) - { - this->priv_terminate_string(); - this->assign(s.begin(), s.end()); - } - - //! Effects: Same as basic_string(sv.data(), sv.size(), a). - //! - //! Throws: If allocator_type's default constructor or allocation throws. - template