You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
252 lines
7.7 KiB
252 lines
7.7 KiB
////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// (C) Copyright Ion Gaztanaga 2005-2011. 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_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP |
|
#define BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP |
|
|
|
#include "config_begin.hpp" |
|
#include <boost/container/container_fwd.hpp> |
|
#include <boost/container/detail/utilities.hpp> |
|
#include <boost/container/detail/type_traits.hpp> |
|
#include <boost/container/detail/transform_iterator.hpp> |
|
#include <boost/intrusive/slist.hpp> |
|
#include <boost/pointer_to_other.hpp> |
|
#include <boost/type_traits/make_unsigned.hpp> |
|
#include <boost/move/move.hpp> |
|
|
|
namespace boost { |
|
namespace container { |
|
namespace containers_detail { |
|
|
|
template<class VoidPointer> |
|
class basic_multiallocation_chain |
|
{ |
|
private: |
|
typedef bi::slist_base_hook<bi::void_pointer<VoidPointer> |
|
,bi::link_mode<bi::normal_link> |
|
> node; |
|
|
|
typedef typename boost::pointer_to_other<VoidPointer, char>::type char_ptr; |
|
typedef typename std::iterator_traits<char_ptr>::difference_type difference_type; |
|
|
|
typedef bi::slist< node |
|
, bi::linear<true> |
|
, bi::cache_last<true> |
|
, bi::size_type<typename boost::make_unsigned<difference_type>::type> |
|
> slist_impl_t; |
|
slist_impl_t slist_impl_; |
|
|
|
static node & to_node(VoidPointer p) |
|
{ return *static_cast<node*>(static_cast<void*>(containers_detail::get_pointer(p))); } |
|
|
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain) |
|
|
|
public: |
|
|
|
|
|
typedef VoidPointer void_pointer; |
|
typedef typename slist_impl_t::iterator iterator; |
|
typedef typename slist_impl_t::size_type size_type; |
|
|
|
basic_multiallocation_chain() |
|
: slist_impl_() |
|
{} |
|
|
|
basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other) |
|
: slist_impl_() |
|
{ slist_impl_.swap(other.slist_impl_); } |
|
|
|
basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other) |
|
{ |
|
basic_multiallocation_chain tmp(boost::move(other)); |
|
this->swap(tmp); |
|
return *this; |
|
} |
|
|
|
bool empty() const |
|
{ return slist_impl_.empty(); } |
|
|
|
size_type size() const |
|
{ return slist_impl_.size(); } |
|
|
|
iterator before_begin() |
|
{ return slist_impl_.before_begin(); } |
|
|
|
iterator begin() |
|
{ return slist_impl_.begin(); } |
|
|
|
iterator end() |
|
{ return slist_impl_.end(); } |
|
|
|
iterator last() |
|
{ return slist_impl_.last(); } |
|
|
|
void clear() |
|
{ slist_impl_.clear(); } |
|
|
|
iterator insert_after(iterator it, void_pointer m) |
|
{ return slist_impl_.insert_after(it, to_node(m)); } |
|
|
|
void push_front(void_pointer m) |
|
{ return slist_impl_.push_front(to_node(m)); } |
|
|
|
void push_back(void_pointer m) |
|
{ return slist_impl_.push_back(to_node(m)); } |
|
|
|
void pop_front() |
|
{ return slist_impl_.pop_front(); } |
|
|
|
void *front() |
|
{ return &*slist_impl_.begin(); } |
|
|
|
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end) |
|
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end); } |
|
|
|
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end, size_type n) |
|
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end, n); } |
|
|
|
void splice_after(iterator after_this, basic_multiallocation_chain &x) |
|
{ slist_impl_.splice_after(after_this, x.slist_impl_); } |
|
|
|
void incorporate_after(iterator after_this, void_pointer begin , iterator before_end) |
|
{ slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end)); } |
|
|
|
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n) |
|
{ slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end), n); } |
|
|
|
void swap(basic_multiallocation_chain &x) |
|
{ slist_impl_.swap(x.slist_impl_); } |
|
|
|
static iterator iterator_to(void_pointer p) |
|
{ return slist_impl_t::s_iterator_to(to_node(p)); } |
|
|
|
std::pair<void_pointer, void_pointer> extract_data() |
|
{ |
|
std::pair<void_pointer, void_pointer> ret |
|
(slist_impl_.begin().operator->() |
|
,slist_impl_.last().operator->()); |
|
slist_impl_.clear(); |
|
return ret; |
|
} |
|
}; |
|
|
|
template<class T> |
|
struct cast_functor |
|
{ |
|
typedef typename containers_detail::add_reference<T>::type result_type; |
|
template<class U> |
|
result_type operator()(U &ptr) const |
|
{ return *static_cast<T*>(static_cast<void*>(&ptr)); } |
|
}; |
|
|
|
template<class MultiallocationChain, class T> |
|
class transform_multiallocation_chain |
|
{ |
|
private: |
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain) |
|
|
|
MultiallocationChain holder_; |
|
typedef typename MultiallocationChain::void_pointer void_pointer; |
|
typedef typename boost::pointer_to_other |
|
<void_pointer, T>::type pointer; |
|
|
|
static pointer cast(void_pointer p) |
|
{ |
|
return pointer(static_cast<T*>(containers_detail::get_pointer(p))); |
|
} |
|
|
|
public: |
|
typedef transform_iterator |
|
< typename MultiallocationChain::iterator |
|
, containers_detail::cast_functor <T> > iterator; |
|
typedef typename MultiallocationChain::size_type size_type; |
|
|
|
transform_multiallocation_chain() |
|
: holder_() |
|
{} |
|
|
|
transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other) |
|
: holder_() |
|
{ this->swap(other); } |
|
|
|
transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other) |
|
: holder_(boost::move(other)) |
|
{} |
|
|
|
transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other) |
|
{ |
|
transform_multiallocation_chain tmp(boost::move(other)); |
|
this->swap(tmp); |
|
return *this; |
|
} |
|
|
|
void push_front(pointer mem) |
|
{ holder_.push_front(mem); } |
|
|
|
void swap(transform_multiallocation_chain &other_chain) |
|
{ holder_.swap(other_chain.holder_); } |
|
|
|
void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, size_type n) |
|
{ holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); } |
|
|
|
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n) |
|
{ holder_.incorporate_after(after_this.base(), begin, before_end, n); } |
|
|
|
void pop_front() |
|
{ holder_.pop_front(); } |
|
|
|
pointer front() |
|
{ return cast(holder_.front()); } |
|
|
|
bool empty() const |
|
{ return holder_.empty(); } |
|
|
|
iterator before_begin() |
|
{ return iterator(holder_.before_begin()); } |
|
|
|
iterator begin() |
|
{ return iterator(holder_.begin()); } |
|
|
|
iterator end() |
|
{ return iterator(holder_.end()); } |
|
|
|
iterator last() |
|
{ return iterator(holder_.last()); } |
|
|
|
size_type size() const |
|
{ return holder_.size(); } |
|
|
|
void clear() |
|
{ holder_.clear(); } |
|
|
|
iterator insert_after(iterator it, pointer m) |
|
{ return iterator(holder_.insert_after(it.base(), m)); } |
|
|
|
static iterator iterator_to(pointer p) |
|
{ return iterator(MultiallocationChain::iterator_to(p)); } |
|
|
|
std::pair<void_pointer, void_pointer> extract_data() |
|
{ return holder_.extract_data(); } |
|
|
|
MultiallocationChain extract_multiallocation_chain() |
|
{ |
|
return MultiallocationChain(boost::move(holder_)); |
|
} |
|
}; |
|
|
|
}}} |
|
|
|
// namespace containers_detail { |
|
// namespace container { |
|
// namespace boost { |
|
|
|
#include <boost/container/detail/config_end.hpp> |
|
|
|
#endif //BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
|
|