Adobe Source Libraries 1.49.0
A collection of C++ libraries.
Loading...
Searching...
No Matches
vector.hpp
Go to the documentation of this file.
1/*
2 Copyright 2013 Adobe
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5*/
6/**************************************************************************************************/
7
8#error Deprecated
9#ifndef ADOBE_VECTOR_HPP
10#define ADOBE_VECTOR_HPP
11
12/**************************************************************************************************/
13
14#include <adobe/config.hpp>
15
16#include <adobe/vector_fwd.hpp>
17
18#include <algorithm>
19#include <cassert>
20#include <cstddef>
21#include <iterator>
22#include <memory>
23
25#include <adobe/empty.hpp>
26#include <adobe/memory.hpp>
27#include <adobe/typeinfo.hpp>
28
29#include <adobe/implementation/swap.hpp>
30#include <adobe/move.hpp>
31
32#ifdef ADOBE_STD_SERIALIZATION
33#include <adobe/iomanip.hpp>
34#endif
35
36/**************************************************************************************************/
37
38namespace adobe {
39inline namespace version_1 {
40
45
46
47/**************************************************************************************************/
48
49template <typename T, // T models Regular
50 typename A> // A models Allocator(T)
51class vector : boost::totally_ordered<vector<T, A>, vector<T, A>> {
52public:
53 typedef T& reference;
54 typedef const T& const_reference;
55 typedef T* iterator;
56 typedef const T* const_iterator;
57 typedef std::size_t size_type;
58 typedef std::ptrdiff_t difference_type;
59 typedef T value_type;
60 typedef A allocator_type;
61 typedef T* pointer;
62 typedef const T* const_pointer;
63 typedef std::reverse_iterator<T*> reverse_iterator;
64 typedef std::reverse_iterator<const T*> const_reverse_iterator;
65
66private:
67 struct header_t {
69 boost::compressed_pair<A, T*> allocate_finish_m;
71 };
73 T storage_m[1];
74
75 allocator_type& allocator() { return header_m.get().allocate_finish_m.first(); }
76 const allocator_type& allocator() const { return header_m.get().allocate_finish_m.first(); }
77
78 pointer& finish() { return header_m.get().allocate_finish_m.second(); }
79 const pointer& finish() const { return header_m.get().allocate_finish_m.second(); }
80
81 pointer& end_of_storage() { return header_m.get().end_of_storage_m; }
82 const pointer& end_of_storage() const { return header_m.get().end_of_storage_m; }
83 };
84
85 header_t* header_m;
86
87 void set_finish(T* x) {
88 assert(header_m != 0 || x == 0);
89 if (header_m)
90 header_m->finish() = x;
91 }
92
93 const T* end_of_storage() const { return header_m ? header_m->end_of_storage() : 0; }
94
95 static header_t* allocate(allocator_type, std::size_t);
96
97 size_type remaining() const { return end_of_storage() - end(); }
98
99 template <typename I> // I models InputIterator
100 void append(I f, I l) {
101 append(f, l, typename std::iterator_traits<I>::iterator_category());
102 }
103
104 template <typename I> // I models InputIterator
105 void append(I f, I l, std::input_iterator_tag);
106
107 template <typename I> // I models ForwardIterator
108 void append(I f, I l, std::forward_iterator_tag);
109
110 template <typename I> // I models InputIterator
111 void append_move(I f, I l) {
112 append_move(f, l, typename std::iterator_traits<I>::iterator_category());
113 }
114
115 template <typename I> // I models InputIterator
116 void append_move(I f, I l, std::input_iterator_tag);
117
118 template <typename I> // I models ForwardIterator
119 void append_move(I f, I l, std::forward_iterator_tag);
120
121 template <typename I> // I models InputIterator
122 iterator insert(iterator p, I f, I l, std::input_iterator_tag);
123
124 template <typename I> // I models ForwardIterator
125 iterator insert(iterator p, I f, I l, std::forward_iterator_tag);
126
127public:
128 // 23.2.4.1 construct/copy/destroy
129
130 explicit vector(const allocator_type& a) : header_m(allocate(a, 0)) {}
131 vector() : header_m(0) {}
132
133 explicit vector(size_type n) : header_m(allocate(allocator_type(), n)) {
134 std::uninitialized_fill_n(end(), n, value_type());
135 set_finish(end() + n);
136 }
137
138 vector(size_type n, const value_type& x) : header_m(allocate(allocator_type(), n)) {
139 std::uninitialized_fill_n(end(), n, x);
140 set_finish(end() + n);
141 }
142
143 vector(size_type n, const value_type& x, const allocator_type& a) : header_m(allocate(a, n)) {
144 std::uninitialized_fill_n(end(), n, x);
145 set_finish(end() + n);
146 }
147
148 vector(const vector& x) : header_m(allocate(x.get_allocator(), x.size())) {
149#ifndef NDEBUG
150 /* REVISIT (sparent) : MS stupid "safety check" doesn't known about empty ranges. */
151 set_finish(x.begin() == x.end() ? end()
152 : std::uninitialized_copy(x.begin(), x.end(), end()));
153#else
154 set_finish(std::uninitialized_copy(x.begin(), x.end(), end()));
155#endif
156 }
157
158 template <typename I> // I models InputIterator
159 vector(I f, I l, typename boost::disable_if<boost::is_integral<I>>::type* = 0) : header_m(0) {
160 append(f, l);
161 }
162
163 template <typename I> // I models InputIterator
164 vector(I f, I l, const allocator_type& a,
165 typename boost::disable_if<boost::is_integral<I>>::type* = 0)
166 : header_m(allocate(a), 0) {
167 append(f, l);
168 }
169
171 if (header_m) {
172 clear();
173
174 typename allocator_type::template rebind<char>::other alloc(get_allocator());
175 alloc.deallocate(reinterpret_cast<char*>(header_m),
176 (end_of_storage() - begin()) * sizeof(T) +
177 (sizeof(header_t) - sizeof(T)));
178 }
179 }
180
181 // adobe addition
182
183 vector(move_from<vector> x) : header_m(x.header_m) { x.header_m = 0; }
184
186 return header_m ? header_m->allocator() : allocator_type();
187 }
188
189 iterator begin() { return header_m ? &header_m->storage_m[0] : 0; }
190 iterator end() { return header_m ? header_m->finish() : 0; }
191
192 const_iterator begin() const { return header_m ? &header_m->storage_m[0] : 0; }
193 const_iterator end() const { return header_m ? header_m->finish() : 0; }
194
197
200
201 size_type size() const { return size_type(end() - begin()); }
202 size_type max_size() const { return size_type(-1) / sizeof(value_type); }
203
204 size_type capacity() const { return size_type(end_of_storage() - begin()); }
205 bool empty() const { return begin() == end(); }
206
208 assert(n < size());
209 return *(begin() + n);
210 }
212 assert(n < size());
213 return *(begin() + n);
214 }
215
216 /*
217 REVISIT (sparent@adobe.com): at() explicitly omitted because it pulls in out_of_range
218 which inherits from logic_error and uses std::string.
219 */
220
222 swap(x);
223 return *this;
224 }
225
226 void reserve(size_type n);
227
229 assert(!empty());
230 return *begin();
231 }
233 assert(!empty());
234 return *begin();
235 }
236
238 assert(!empty());
239 return *(end() - 1);
240 }
242 assert(!empty());
243 return *(end() - 1);
244 }
245
246 void push_back(value_type x) { append_move(&x, &x + 1); }
247
248 void pop_back() {
249 assert(!empty());
250 resize(size() - 1);
251 }
252
253 void swap(vector& x) { std::swap(header_m, x.header_m); }
254
255 iterator insert(iterator p, value_type x) { return insert_move(p, &x, &x + 1); }
256
257 template <typename I> // I models InputIterator
259 typename boost::disable_if<boost::is_integral<I>>::type* = 0) {
260 return insert(p, f, l, typename std::iterator_traits<I>::iterator_category());
261 }
262
263 template <typename I> // I models ForwardIterator
264 iterator insert_move(iterator p, I f, I l);
265
266 iterator insert(iterator p, size_type n, const T& x);
267
269 assert(pos != end());
270 return erase(pos, pos + 1);
271 }
272
274
275 void clear() { erase(begin(), end()); }
276
277 void resize(size_type n);
278
279 void resize(size_type n, const value_type& x);
280
281 friend inline bool operator==(const vector& x, const vector& y) {
282#if defined(_MSC_VER) && _MSC_VER == 1600 && _ITERATOR_DEBUG_LEVEL != 0
283 return (x.size() == y.size()) &&
284 std::_Equal1(x.begin(), x.end(), y.begin(), std::false_type());
285#else
286 return (x.size() == y.size()) && std::equal(x.begin(), x.end(), y.begin());
287#endif
288 }
289
290 friend inline bool operator<(const vector& x, const vector& y) {
291 return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
292 }
293
294 friend inline void swap(vector& x, vector& y) { x.swap(y); }
295};
296
297template <typename T, typename A>
298typename vector<T, A>::header_t* vector<T, A>::allocate(allocator_type a, std::size_t n) {
299 if (n == 0) {
300 if (a == allocator_type())
301 return 0;
302 n = 1;
303 }
304
305 typename allocator_type::template rebind<char>::other alloc(a);
306
307 header_t* result =
308 reinterpret_cast<header_t*>(alloc.allocate(sizeof(header_t) - sizeof(T) + n * sizeof(T)));
309 construct(&result->allocator(), a);
310 result->finish() = &result->storage_m[0];
311 result->end_of_storage() = result->finish() + n;
312
313 return result;
314}
315
316template <typename T, typename A>
317template <typename I> // I models InputIterator
318void vector<T, A>::append(I f, I l, std::input_iterator_tag) {
319 while (f != l) {
320 push_back(*f);
321 ++f;
322 }
323}
324
325template <typename T, typename A>
326template <typename I> // I models InputIterator
327void vector<T, A>::append_move(I f, I l, std::input_iterator_tag) {
328 while (f != l) {
329 push_back(adobe::move(*f));
330 ++f;
331 }
332}
333
334template <typename T, typename A>
335template <typename I> // I models ForwardIterator
336void vector<T, A>::append(I f, I l, std::forward_iterator_tag) {
337 size_type n(std::distance(f, l));
338
339 if (remaining() < n)
340 reserve((adobe::max)(size() + n, 2 * size()));
341 set_finish(std::uninitialized_copy(f, l, end()));
342}
343
344template <typename T, typename A>
345template <typename I> // I models ForwardIterator
346void vector<T, A>::append_move(I f, I l, std::forward_iterator_tag) {
347 size_type n(std::distance(f, l));
348
349 if (remaining() < n)
350 reserve((adobe::max)(size() + n, 2 * size()));
351 set_finish(adobe::uninitialized_move(f, l, end()));
352}
353
354template <typename T, typename A>
355template <typename I> // I models InputIterator
356typename vector<T, A>::iterator vector<T, A>::insert(iterator p, I f, I l,
357 std::input_iterator_tag) {
358 size_type o(p - begin());
359 size_type s = size();
360 append(f, l);
361 // REVISIT (sparent) : This could be a move based rotate
362 std::rotate(begin() + o, begin() + s, end());
363 return end() - s + o;
364}
365
366template <typename T, typename A>
367template <typename I> // I models ForwardIterator
368typename vector<T, A>::iterator vector<T, A>::insert(iterator p, I f, I l,
369 std::forward_iterator_tag) {
370 size_type n(std::distance(f, l));
371 iterator last = end();
372 size_type before = p - begin();
373
374 if (remaining() < n) {
375 vector tmp;
376 tmp.reserve((adobe::max)(size() + n, 2 * size()));
377 tmp.append_move(begin(), p);
378 tmp.append(f, l);
379 tmp.append_move(p, last);
380 swap(tmp);
381 } else {
382 size_type after(last - p);
383
384 if (n < after) {
385 append_move(last - n, last);
386 adobe::move_backward(p, last - n, last);
387 std::copy(f, l, p);
388 } else {
389 I m = f;
390 std::advance(m, after);
391 append(m, l);
392 append_move(p, last);
393 std::copy(f, m, p);
394 }
395 }
396 return begin() + before + n;
397}
398
399template <typename T, typename A>
400template <typename I> // I models ForwardIterator
402 size_type n(std::distance(f, l));
403 iterator last = end();
404 size_type before = p - begin();
405
406 if (remaining() < n) {
407 vector tmp;
408 tmp.reserve((adobe::max)(size() + n, 2 * size()));
409 tmp.append_move(begin(), p);
410 tmp.append_move(f, l);
411 tmp.append_move(p, last);
412 swap(tmp);
413 } else {
414 size_type after(last - p);
415
416 if (n < after) {
417 append_move(last - n, last);
418 move_backward(p, last - n, last);
419 adobe::move(f, l, p);
420 } else {
421 I m = f;
422 std::advance(m, after);
423 append_move(m, l);
424 append_move(p, last);
425 adobe::move(f, m, p);
426 }
427 }
428 return begin() + before + n;
429}
430
431template <typename T, typename A>
433 if (capacity() < n) {
434 vector tmp;
435 tmp.header_m = allocate(get_allocator(), n);
436 tmp.header_m->finish() = adobe::uninitialized_move(begin(), end(), tmp.end());
437 swap(tmp);
438 }
439}
440
441template <typename T, typename A>
442typename vector<T, A>::iterator vector<T, A>::insert(iterator p, size_type n, const T& x) {
443 iterator last = end();
444 size_type before = p - begin();
445
446 if (remaining() < n) {
447 vector tmp;
448 tmp.reserve((adobe::max)(size() + n, 2 * size()));
449 tmp.append_move(begin(), p);
450 std::uninitialized_fill_n(tmp.end(), n, x);
451 tmp.set_finish(tmp.end() + n);
452 tmp.append_move(p, last);
453 swap(tmp);
454 } else {
455 size_type after(last - p);
456
457 if (n < after) {
458 append_move(last - n, last);
459 adobe::move_backward(p, last - n, last);
460 std::fill_n(p, n, x);
461 } else {
462 std::uninitialized_fill_n(last, n - after, x);
463 set_finish(last + (n - after));
464 append_move(p, last);
465 std::fill_n(p, after, x);
466 }
467 }
468 return begin() + before + n;
469}
470
471template <typename T, typename A>
473 iterator i = adobe::move(l, end(), f);
474 for (iterator b(i), e(end()); b != e; ++b) {
475 b->~value_type();
476 }
477 set_finish(i);
478 return f;
479}
480
481template <typename T, typename A>
483 if (n < size())
484 erase(begin() + n, end());
485 else
486 insert(end(), n - size(), value_type());
487}
488
489template <typename T, typename A>
491 if (n < size())
492 erase(begin() + n, end());
493 else
494 insert(end(), n - size(), x);
495}
496
497/**************************************************************************************************/
498
499#ifdef ADOBE_STD_SERIALIZATION
500
501template <typename T, typename A>
502std::ostream& operator<<(std::ostream& out, const vector<T, A>& x) {
503 out << begin_sequence;
504
505 for (typename vector<T, A>::const_iterator first(x.begin()), last(x.end()); first != last;
506 ++first) {
507 out << format(*first);
508 }
509
510 out << end_sequence;
511
512 return out;
513}
514
515#endif
516
517/**************************************************************************************************/
518
519static_assert(sizeof(vector<int>) == sizeof(void*));
520
521/**************************************************************************************************/
522
523} // namespace version_1
524} // namespace adobe
525
526/**************************************************************************************************/
527
528ADOBE_NAME_TYPE_1("vector:version_1:adobe",
530ADOBE_NAME_TYPE_2("vector:version_1:adobe", adobe::version_1::vector<T0, T1>)
531
532/**************************************************************************************************/
533/**************************************************************************************************/
534
535#endif
vector(I f, I l, const allocator_type &a, typename boost::disable_if< boost::is_integral< I > >::type *=0)
Definition vector.hpp:164
const_reverse_iterator rend() const
Definition vector.hpp:199
const_reference front() const
Definition vector.hpp:232
vector(size_type n, const value_type &x, const allocator_type &a)
Definition vector.hpp:143
vector(size_type n, const value_type &x)
Definition vector.hpp:138
std::reverse_iterator< const T * > const_reverse_iterator
Definition vector.hpp:64
const_iterator begin() const
Definition vector.hpp:192
friend bool operator==(const vector &x, const vector &y)
Definition vector.hpp:281
friend bool operator<(const vector &x, const vector &y)
Definition vector.hpp:290
vector(const vector &x)
Definition vector.hpp:148
void reserve(size_type n)
Definition vector.hpp:432
std::reverse_iterator< T * > reverse_iterator
Definition vector.hpp:63
size_type size() const
Definition vector.hpp:201
const_reference back() const
Definition vector.hpp:241
friend void swap(vector &x, vector &y)
Definition vector.hpp:294
reverse_iterator rend()
Definition vector.hpp:196
void resize(size_type n)
Definition vector.hpp:482
vector & operator=(vector x)
Definition vector.hpp:221
allocator_type get_allocator() const
Definition vector.hpp:185
vector(move_from< vector > x)
Definition vector.hpp:183
void swap(vector &x)
Definition vector.hpp:253
std::size_t size_type
Definition vector.hpp:57
vector(I f, I l, typename boost::disable_if< boost::is_integral< I > >::type *=0)
Definition vector.hpp:159
iterator insert_move(iterator p, I f, I l)
Definition vector.hpp:401
size_type max_size() const
Definition vector.hpp:202
iterator insert(iterator p, value_type x)
Definition vector.hpp:255
void push_back(value_type x)
Definition vector.hpp:246
reference operator[](size_type n)
Definition vector.hpp:207
const_reference operator[](size_type n) const
Definition vector.hpp:211
iterator insert(iterator p, I f, I l, typename boost::disable_if< boost::is_integral< I > >::type *=0)
Definition vector.hpp:258
const_iterator end() const
Definition vector.hpp:193
reverse_iterator rbegin()
Definition vector.hpp:195
size_type capacity() const
Definition vector.hpp:204
std::ptrdiff_t difference_type
Definition vector.hpp:58
const_reverse_iterator rbegin() const
Definition vector.hpp:198
vector(const allocator_type &a)
Definition vector.hpp:130
iterator erase(iterator pos)
Definition vector.hpp:268
const T & const_reference
Definition vector.hpp:54
T::iterator erase(T &x, typename T::iterator f, typename T::iterator l)
Definition erase_if.hpp:65
const T & max(const T &a, const T &b, R r)
minmax implementation
Definition minmax.hpp:113
boost::range_size< Selection >::type size(const Selection &x)
void swap(any_regular_t &x, any_regular_t &y)
void push_back(array_t &v, T x)
Definition array.hpp:28
constexpr auto construct(T *p, U &&x)
Definition memory.hpp:355
F uninitialized_move(I f, I l, F r)
Similar to std::uninitialized_copy but with move semantics.
Definition memory.hpp:380
auto append(T &c, const R &r)
Definition append.hpp:22
std::ostream & operator<<(std::ostream &s, const extents_t &x)
void swap(adobe::extents_t::slice_t &x, adobe::extents_t::slice_t &y) BOOST_NOEXCEPT
Definition extents.hpp:120
boost::compressed_pair< A, T * > allocate_finish_m
Definition vector.hpp:69