/* Copyright 2003-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) | |
* | |
* See http://www.boost.org/libs/multi_index for library home page. | |
*/ | |
#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP | |
#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP | |
#if defined(_MSC_VER)&&(_MSC_VER>=1200) | |
#pragma once | |
#endif | |
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ | |
#include <algorithm> | |
#include <boost/detail/allocator_utilities.hpp> | |
#include <boost/multi_index/detail/auto_space.hpp> | |
#include <boost/multi_index/detail/prevent_eti.hpp> | |
#include <boost/multi_index/detail/rnd_index_node.hpp> | |
#include <boost/noncopyable.hpp> | |
#include <cstddef> | |
namespace boost{ | |
namespace multi_index{ | |
namespace detail{ | |
/* pointer structure for use by random access indices */ | |
template<typename Allocator> | |
class random_access_index_ptr_array:private noncopyable | |
{ | |
typedef typename prevent_eti< | |
Allocator, | |
random_access_index_node_impl< | |
typename boost::detail::allocator::rebind_to< | |
Allocator, | |
char | |
>::type | |
> | |
>::type node_impl_type; | |
public: | |
typedef typename node_impl_type::pointer value_type; | |
typedef typename prevent_eti< | |
Allocator, | |
typename boost::detail::allocator::rebind_to< | |
Allocator,value_type | |
>::type | |
>::type::pointer pointer; | |
random_access_index_ptr_array( | |
const Allocator& al,value_type end_,std::size_t size): | |
size_(size), | |
capacity_(size), | |
spc(al,capacity_+1) | |
{ | |
*end()=end_; | |
end_->up()=end(); | |
} | |
std::size_t size()const{return size_;} | |
std::size_t capacity()const{return capacity_;} | |
void room_for_one() | |
{ | |
if(size_==capacity_){ | |
reserve(capacity_<=10?15:capacity_+capacity_/2); | |
} | |
} | |
void reserve(std::size_t c) | |
{ | |
if(c>capacity_){ | |
auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1); | |
node_impl_type::transfer(begin(),end()+1,spc1.data()); | |
spc.swap(spc1); | |
capacity_=c; | |
} | |
} | |
pointer begin()const{return ptrs();} | |
pointer end()const{return ptrs()+size_;} | |
pointer at(std::size_t n)const{return ptrs()+n;} | |
void push_back(value_type x) | |
{ | |
*(end()+1)=*end(); | |
(*(end()+1))->up()=end()+1; | |
*end()=x; | |
(*end())->up()=end(); | |
++size_; | |
} | |
void erase(value_type x) | |
{ | |
node_impl_type::extract(x->up(),end()+1); | |
--size_; | |
} | |
void clear() | |
{ | |
*begin()=*end(); | |
(*begin())->up()=begin(); | |
size_=0; | |
} | |
void swap(random_access_index_ptr_array& x) | |
{ | |
std::swap(size_,x.size_); | |
std::swap(capacity_,x.capacity_); | |
spc.swap(x.spc); | |
} | |
private: | |
std::size_t size_; | |
std::size_t capacity_; | |
auto_space<value_type,Allocator> spc; | |
pointer ptrs()const | |
{ | |
return spc.data(); | |
} | |
}; | |
template<typename Allocator> | |
void swap( | |
random_access_index_ptr_array<Allocator>& x, | |
random_access_index_ptr_array<Allocator>& y) | |
{ | |
x.swap(y); | |
} | |
} /* namespace multi_index::detail */ | |
} /* namespace multi_index */ | |
} /* namespace boost */ | |
#endif |