]>
Commit | Line | Data |
---|---|---|
f67539c2 | 1 | /* Copyright 2003-2020 Joaquin M Lopez Munoz. |
7c673cae FG |
2 | * Distributed under the Boost Software License, Version 1.0. |
3 | * (See accompanying file LICENSE_1_0.txt or copy at | |
4 | * http://www.boost.org/LICENSE_1_0.txt) | |
5 | * | |
6 | * See http://www.boost.org/libs/multi_index for library home page. | |
7 | */ | |
8 | ||
9 | #ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP | |
10 | #define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP | |
11 | ||
12 | #if defined(_MSC_VER) | |
13 | #pragma once | |
14 | #endif | |
15 | ||
16 | #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ | |
17 | #include <algorithm> | |
92f5a8d4 | 18 | #include <boost/multi_index/detail/allocator_traits.hpp> |
7c673cae FG |
19 | #include <boost/multi_index/detail/auto_space.hpp> |
20 | #include <boost/multi_index/detail/rnd_index_node.hpp> | |
21 | #include <boost/noncopyable.hpp> | |
7c673cae FG |
22 | |
23 | namespace boost{ | |
24 | ||
25 | namespace multi_index{ | |
26 | ||
27 | namespace detail{ | |
28 | ||
29 | /* pointer structure for use by random access indices */ | |
30 | ||
31 | template<typename Allocator> | |
32 | class random_access_index_ptr_array:private noncopyable | |
33 | { | |
34 | typedef random_access_index_node_impl< | |
92f5a8d4 | 35 | typename rebind_alloc_for< |
7c673cae FG |
36 | Allocator, |
37 | char | |
38 | >::type | |
92f5a8d4 | 39 | > node_impl_type; |
7c673cae FG |
40 | |
41 | public: | |
92f5a8d4 TL |
42 | typedef typename node_impl_type::pointer value_type; |
43 | typedef typename rebind_alloc_for< | |
7c673cae | 44 | Allocator,value_type |
92f5a8d4 TL |
45 | >::type value_allocator; |
46 | typedef allocator_traits<value_allocator> alloc_traits; | |
47 | typedef typename alloc_traits::pointer pointer; | |
48 | typedef typename alloc_traits::size_type size_type; | |
7c673cae FG |
49 | |
50 | random_access_index_ptr_array( | |
92f5a8d4 | 51 | const Allocator& al,value_type end_,size_type sz): |
7c673cae FG |
52 | size_(sz), |
53 | capacity_(sz), | |
54 | spc(al,capacity_+1) | |
55 | { | |
56 | *end()=end_; | |
57 | end_->up()=end(); | |
58 | } | |
59 | ||
92f5a8d4 TL |
60 | size_type size()const{return size_;} |
61 | size_type capacity()const{return capacity_;} | |
7c673cae FG |
62 | |
63 | void room_for_one() | |
64 | { | |
65 | if(size_==capacity_){ | |
66 | reserve(capacity_<=10?15:capacity_+capacity_/2); | |
67 | } | |
68 | } | |
69 | ||
92f5a8d4 | 70 | void reserve(size_type c) |
7c673cae FG |
71 | { |
72 | if(c>capacity_)set_capacity(c); | |
73 | } | |
74 | ||
75 | void shrink_to_fit() | |
76 | { | |
77 | if(capacity_>size_)set_capacity(size_); | |
78 | } | |
79 | ||
80 | pointer begin()const{return ptrs();} | |
81 | pointer end()const{return ptrs()+size_;} | |
92f5a8d4 | 82 | pointer at(size_type n)const{return ptrs()+n;} |
7c673cae FG |
83 | |
84 | void push_back(value_type x) | |
85 | { | |
86 | *(end()+1)=*end(); | |
87 | (*(end()+1))->up()=end()+1; | |
88 | *end()=x; | |
89 | (*end())->up()=end(); | |
90 | ++size_; | |
91 | } | |
92 | ||
93 | void erase(value_type x) | |
94 | { | |
95 | node_impl_type::extract(x->up(),end()+1); | |
96 | --size_; | |
97 | } | |
98 | ||
99 | void clear() | |
100 | { | |
101 | *begin()=*end(); | |
102 | (*begin())->up()=begin(); | |
103 | size_=0; | |
104 | } | |
105 | ||
106 | void swap(random_access_index_ptr_array& x) | |
107 | { | |
108 | std::swap(size_,x.size_); | |
109 | std::swap(capacity_,x.capacity_); | |
110 | spc.swap(x.spc); | |
111 | } | |
112 | ||
f67539c2 TL |
113 | template<typename BoolConstant> |
114 | void swap(random_access_index_ptr_array& x,BoolConstant swap_allocators) | |
115 | { | |
116 | std::swap(size_,x.size_); | |
117 | std::swap(capacity_,x.capacity_); | |
118 | spc.swap(x.spc,swap_allocators); | |
119 | } | |
120 | ||
7c673cae | 121 | private: |
92f5a8d4 TL |
122 | size_type size_; |
123 | size_type capacity_; | |
7c673cae FG |
124 | auto_space<value_type,Allocator> spc; |
125 | ||
126 | pointer ptrs()const | |
127 | { | |
128 | return spc.data(); | |
129 | } | |
130 | ||
92f5a8d4 | 131 | void set_capacity(size_type c) |
7c673cae FG |
132 | { |
133 | auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1); | |
134 | node_impl_type::transfer(begin(),end()+1,spc1.data()); | |
135 | spc.swap(spc1); | |
136 | capacity_=c; | |
137 | } | |
138 | }; | |
139 | ||
140 | template<typename Allocator> | |
141 | void swap( | |
142 | random_access_index_ptr_array<Allocator>& x, | |
143 | random_access_index_ptr_array<Allocator>& y) | |
144 | { | |
145 | x.swap(y); | |
146 | } | |
147 | ||
148 | } /* namespace multi_index::detail */ | |
149 | ||
150 | } /* namespace multi_index */ | |
151 | ||
152 | } /* namespace boost */ | |
153 | ||
154 | #endif |