00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ADOBE_VECTOR_HPP
00010 #define ADOBE_VECTOR_HPP
00011
00012
00013
00014 #include <adobe/config.hpp>
00015
00016 #include <adobe/vector_fwd.hpp>
00017
00018 #include <algorithm>
00019 #include <cassert>
00020 #include <cstddef>
00021 #include <iterator>
00022 #include <memory>
00023
00024 #include <boost/operators.hpp>
00025 #include <boost/static_assert.hpp>
00026 #include <boost/type_traits/has_nothrow_constructor.hpp>
00027 #include <boost/type_traits/is_integral.hpp>
00028 #include <boost/utility/enable_if.hpp>
00029
00030 #include <adobe/empty.hpp>
00031 #include <adobe/typeinfo.hpp>
00032 #include <adobe/memory.hpp>
00033 #include <adobe/algorithm/minmax.hpp>
00034
00035 #include <adobe/move.hpp>
00036 #include <adobe/implementation/swap.hpp>
00037
00038 #ifdef ADOBE_STD_SERIALIZATION
00039 #include <adobe/iomanip.hpp>
00040 #endif
00041
00042
00043
00044 namespace adobe {
00045 namespace version_1 {
00046
00053
00054
00056 template <typename T,
00057 typename A>
00058 class vector : boost::totally_ordered<vector<T, A>, vector<T, A> >
00059 {
00060 public:
00061 typedef T& reference;
00062 typedef const T& const_reference;
00063 typedef T* iterator;
00064 typedef const T* const_iterator;
00065 typedef std::size_t size_type;
00066 typedef std::ptrdiff_t difference_type;
00067 typedef T value_type;
00068 typedef A allocator_type;
00069 typedef T* pointer;
00070 typedef const T* const_pointer;
00071 typedef std::reverse_iterator<T*> reverse_iterator;
00072 typedef std::reverse_iterator<const T*> const_reverse_iterator;
00073
00074 private:
00075 struct header_t
00076 {
00077 struct compact_header_t
00078 {
00079 boost::compressed_pair<A, T*> allocate_finish_m;
00080 T* end_of_storage_m;
00081 };
00082 aligned_storage<compact_header_t> header_m;
00083 T storage_m[1];
00084
00085 allocator_type& allocator() { return header_m.get().allocate_finish_m.first(); }
00086 const allocator_type& allocator() const { return header_m.get().allocate_finish_m.first(); }
00087
00088 pointer& finish() { return header_m.get().allocate_finish_m.second(); }
00089 const pointer& finish() const { return header_m.get().allocate_finish_m.second(); }
00090
00091 pointer& end_of_storage() { return header_m.get().end_of_storage_m; }
00092 const pointer& end_of_storage() const { return header_m.get().end_of_storage_m; }
00093 };
00094
00095 header_t* header_m;
00096
00097 void set_finish(T* x)
00098 {
00099 assert(header_m != 0 || x == 0);
00100 if (header_m) header_m->finish() = x;
00101 }
00102
00103 const T* end_of_storage() const { return header_m ? header_m->end_of_storage() : 0; }
00104
00105 static header_t* allocate(allocator_type, std::size_t);
00106
00107 size_type remaining() const { return end_of_storage() - end(); }
00108
00109 template <typename I>
00110 void append(I f, I l) { append(f, l, typename std::iterator_traits<I>::iterator_category()); }
00111
00112 template <typename I>
00113 void append(I f, I l, std::input_iterator_tag);
00114
00115 template <typename I>
00116 void append(I f, I l, std::forward_iterator_tag);
00117
00118 template <typename I>
00119 void move_append(I f, I l)
00120 { move_append(f, l, typename std::iterator_traits<I>::iterator_category()); }
00121
00122 template <typename I>
00123 void move_append(I f, I l, std::input_iterator_tag);
00124
00125 template <typename I>
00126 void move_append(I f, I l, std::forward_iterator_tag);
00127
00128 template <typename I>
00129 iterator insert(iterator p, I f, I l, std::input_iterator_tag);
00130
00131 template <typename I>
00132 iterator insert(iterator p, I f, I l, std::forward_iterator_tag);
00133
00134 public:
00135
00136
00137 explicit vector(const allocator_type& a) : header_m(allocate(a, 0)) { }
00138 vector() : header_m(0) { }
00139
00140 explicit vector(size_type n) : header_m(allocate(allocator_type(), n))
00141 {
00142 std::uninitialized_fill_n(end(), n, value_type());
00143 set_finish(end() + n);
00144 }
00145
00146 vector(size_type n, const value_type& x) : header_m(allocate(allocator_type(), n))
00147 {
00148 std::uninitialized_fill_n(end(), n, x);
00149 set_finish(end() + n);
00150 }
00151
00152 vector(size_type n, const value_type& x, const allocator_type& a) : header_m(allocate(a, n))
00153 {
00154 std::uninitialized_fill_n(end(), n, x);
00155 set_finish(end() + n);
00156 }
00157
00158 vector(const vector& x) : header_m(allocate(x.get_allocator(), x.size()))
00159 {
00160 #ifndef NDEBUG
00161
00162 set_finish(x.begin() == x.end() ? end() : std::uninitialized_copy(x.begin(), x.end(), end()));
00163 #else
00164 set_finish(std::uninitialized_copy(x.begin(), x.end(), end()));
00165 #endif
00166 }
00167
00168 template <typename I>
00169 vector(I f, I l, typename boost::disable_if<boost::is_integral<I> >::type* = 0) : header_m(0)
00170 { append(f, l); }
00171
00172 template <typename I>
00173 vector(I f, I l, const allocator_type& a,
00174 typename boost::disable_if<boost::is_integral<I> >::type* = 0) : header_m(allocate(a), 0)
00175 { append(f, l); }
00176
00177 ~vector() {
00178 if (header_m) {
00179 clear();
00180
00181 typename allocator_type::template rebind<char>::other alloc(get_allocator());
00182 alloc.deallocate(reinterpret_cast<char*>(header_m),
00183 (end_of_storage() - begin()) * sizeof(T) + (sizeof(header_t) - sizeof(T)));
00184 }
00185 }
00186
00187
00188
00189 vector(move_from<vector> x) : header_m(x.source.header_m) { x.source.header_m = 0; }
00190
00191 allocator_type get_allocator() const
00192 { return header_m ? header_m->allocator() : allocator_type(); }
00193
00194 iterator begin() { return header_m ? &header_m->storage_m[0] : 0; }
00195 iterator end() { return header_m ? header_m->finish() : 0; }
00196
00197 const_iterator begin() const { return header_m ? &header_m->storage_m[0] : 0; }
00198 const_iterator end() const { return header_m ? header_m->finish() : 0; }
00199
00200 reverse_iterator rbegin() { return reverse_iterator(end()); }
00201 reverse_iterator rend() { return reverse_iterator(begin()); }
00202
00203 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00204 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00205
00206 size_type size() const { return size_type(end() - begin()); }
00207 size_type max_size() const { return size_type(-1) / sizeof(value_type); }
00208
00209 size_type capacity() const { return size_type(end_of_storage() - begin()); }
00210 bool empty() const { return begin() == end(); }
00211
00212 reference operator[](size_type n) { assert(n < size()); return *(begin() + n); }
00213 const_reference operator[](size_type n) const { assert(n < size()); return *(begin() + n); }
00214
00215
00216
00217
00218
00219
00220 vector& operator=(vector x) { swap(x); return *this; }
00221
00222 #if 0
00223 template <typename I>
00224 vector(I f, I l, move_ctor) : header_m(0)
00225 { move_append(f, l); }
00226
00227 #endif
00228
00229 void reserve(size_type n);
00230
00231 reference front() { assert(!empty()); return *begin(); }
00232 const_reference front() const { assert(!empty()); return *begin(); }
00233
00234 reference back() { assert(!empty()); return *(end() - 1); }
00235 const_reference back() const { assert(!empty()); return *(end() - 1); }
00236
00237 template <typename U>
00238 void push_back(const U& x, typename copy_sink<U, T>::type = 0)
00239 {
00240 if (remaining()) {
00241 construct<value_type>(end(), x);
00242 } else {
00243 value_type tmp(x);
00244 reserve(size() ? 2 * size() : 1);
00245 construct(end(), tmp);
00246 }
00247 set_finish(end() + 1);
00248 }
00249
00250 template <typename U>
00251 void push_back(U x, typename move_sink<U, T>::type = 0)
00252 { move_append(&x, &x + 1); }
00253
00254 void pop_back() { assert(!empty()); resize(size() - 1); }
00255
00256 void swap(vector& x) { std::swap(header_m, x.header_m); }
00257
00258 template <typename U>
00259 iterator insert(iterator p, const U& x, typename copy_sink<U, T>::type = 0)
00260 {
00261 if (remaining()) return insert(p, &x, &x + 1);
00262 else { value_type tmp(x); return insert(p, &tmp, &tmp + 1); }
00263 }
00264
00265 template <typename U>
00266 iterator insert(iterator p, U x, typename move_sink<U, T>::type = 0)
00267 { return move_insert(p, &x, &x + 1); }
00268
00269 template <typename I>
00270 iterator insert(iterator p, I f, I l, typename boost::disable_if<boost::is_integral<I> >::type* = 0)
00271 { return insert(p, f, l, typename std::iterator_traits<I>::iterator_category()); }
00272
00273 template <typename I>
00274 iterator move_insert(iterator p, I f, I l);
00275
00276 iterator insert(iterator p, size_type n, const T& x);
00277
00278 iterator erase(iterator pos) { assert(pos != end()); return erase(pos, pos + 1); }
00279
00280 iterator erase(iterator f, iterator l);
00281
00282 void clear() { erase(begin(), end()); }
00283
00284 void resize(size_type n);
00285
00286 void resize(size_type n, const value_type& x);
00287
00288 friend inline bool operator==(const vector& x, const vector& y)
00289 {
00290 return (x.size() == y.size()) && std::equal(x.begin(), x.end(), y.begin());
00291 }
00292
00293 friend inline bool operator<(const vector& x, const vector& y)
00294 {
00295 return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
00296 }
00297
00298 friend inline void swap(vector& x, vector& y) { x.swap(y); }
00299 };
00300
00301 template <typename T, typename A>
00302 typename vector<T, A>::header_t* vector<T, A>::allocate(allocator_type a, std::size_t n)
00303 {
00304 if (n == 0) {
00305 if (a == allocator_type()) return 0;
00306 n = 1;
00307 }
00308
00309 typename allocator_type::template rebind<char>::other alloc(a);
00310
00311 header_t* result = reinterpret_cast<header_t*>(alloc.allocate(sizeof(header_t) - sizeof(T)
00312 + n * sizeof(T)));
00313 construct(&result->allocator(), a);
00314 result->finish() = &result->storage_m[0];
00315 result->end_of_storage() = result->finish() + n;
00316
00317 return result;
00318 }
00319
00320 template <typename T, typename A>
00321 template <typename I>
00322 void vector<T, A>::append(I f, I l, std::input_iterator_tag) { while (f != l) { push_back(*f); ++f; } }
00323
00324 template <typename T, typename A>
00325 template <typename I>
00326 void vector<T, A>::move_append(I f, I l, std::input_iterator_tag)
00327 { while (f != l) { push_back(move(*f)); ++f; } }
00328
00329 template <typename T, typename A>
00330 template <typename I>
00331 void vector<T, A>::append(I f, I l, std::forward_iterator_tag)
00332 {
00333 size_type n(std::distance(f, l));
00334
00335 if (remaining() < n) reserve((adobe::max)(size() + n, 2 * size()));
00336 set_finish(std::uninitialized_copy(f, l, end()));
00337 }
00338
00339 template <typename T, typename A>
00340 template <typename I>
00341 void vector<T, A>::move_append(I f, I l, std::forward_iterator_tag)
00342 {
00343 size_type n(std::distance(f, l));
00344
00345 if (remaining() < n) reserve((adobe::max)(size() + n, 2 * size()));
00346 set_finish(uninitialized_move(f, l, end()));
00347 }
00348
00349 template <typename T, typename A>
00350 template <typename I>
00351 typename vector<T, A>::iterator vector<T, A>::insert(iterator p, I f, I l, std::input_iterator_tag)
00352 {
00353 size_type o(p - begin());
00354 size_type s = size();
00355 append(f, l);
00356
00357 std::rotate(begin() + o, begin() + s, end());
00358 return end() - s + o;
00359 }
00360
00361 template <typename T, typename A>
00362 template <typename I>
00363 typename vector<T, A>::iterator vector<T, A>::insert(iterator p, I f, I l, std::forward_iterator_tag)
00364 {
00365 size_type n(std::distance(f, l));
00366 iterator last = end();
00367 size_type before = p - begin();
00368
00369 if (remaining() < n) {
00370 vector tmp;
00371 tmp.reserve((adobe::max)(size() + n, 2 * size()));
00372 tmp.move_append(begin(), p);
00373 tmp.append(f, l);
00374 tmp.move_append(p, last);
00375 swap(tmp);
00376 } else {
00377 size_type after(last - p);
00378
00379 if (n < after) {
00380 move_append(last - n, last);
00381 move_backward(p, last - n, last);
00382 std::copy(f, l, p);
00383 } else {
00384 I m = f;
00385 std::advance(m, after);
00386 append(m, l);
00387 move_append(p, last);
00388 std::copy(f, m, p);
00389 }
00390 }
00391 return begin() + before + n;
00392 }
00393
00394 template <typename T, typename A>
00395 template <typename I>
00396 typename vector<T, A>::iterator vector<T, A>::move_insert(iterator p, I f, I l)
00397 {
00398 size_type n(std::distance(f, l));
00399 iterator last = end();
00400 size_type before = p - begin();
00401
00402 if (remaining() < n) {
00403 vector tmp;
00404 tmp.reserve((adobe::max)(size() + n, 2 * size()));
00405 tmp.move_append(begin(), p);
00406 tmp.move_append(f, l);
00407 tmp.move_append(p, last);
00408 swap(tmp);
00409 } else {
00410 size_type after(last - p);
00411
00412 if (n < after) {
00413 move_append(last - n, last);
00414 move_backward(p, last - n, last);
00415 move(f, l, p);
00416 } else {
00417 I m = f;
00418 std::advance(m, after);
00419 move_append(m, l);
00420 move_append(p, last);
00421 move(f, m, p);
00422 }
00423 }
00424 return begin() + before + n;
00425 }
00426
00427 template <typename T, typename A>
00428 void vector<T, A>::reserve(size_type n)
00429 {
00430 if (capacity() < n) {
00431 vector tmp;
00432 tmp.header_m = allocate(get_allocator(), n);
00433 tmp.header_m->finish() = uninitialized_move(begin(), end(), tmp.end());
00434 swap(tmp);
00435 }
00436 }
00437
00438 template <typename T, typename A>
00439 typename vector<T, A>::iterator vector<T, A>::insert(iterator p, size_type n, const T& x)
00440 {
00441 iterator last = end();
00442 size_type before = p - begin();
00443
00444 if (remaining() < n) {
00445 vector tmp;
00446 tmp.reserve((adobe::max)(size() + n, 2 * size()));
00447 tmp.move_append(begin(), p);
00448 std::uninitialized_fill_n(tmp.end(), n, x);
00449 tmp.set_finish(tmp.end() + n);
00450 tmp.move_append(p, last);
00451 swap(tmp);
00452 } else {
00453 size_type after(last - p);
00454
00455 if (n < after) {
00456 move_append(last - n, last);
00457 move_backward(p, last - n, last);
00458 std::fill_n(p, n, x);
00459 } else {
00460 std::uninitialized_fill_n(last, n - after, x);
00461 set_finish(last + (n - after));
00462 move_append(p, last);
00463 std::fill_n(p, after, x);
00464 }
00465 }
00466 return begin() + before + n;
00467 }
00468
00469 template <typename T, typename A>
00470 typename vector<T, A>::iterator vector<T, A>::erase(iterator f, iterator l)
00471 {
00472 iterator i = move(l, end(), f);
00473 for (iterator b(i), e(end()); b != e; ++b) {
00474 b->~value_type();
00475 }
00476 set_finish(i);
00477 return f;
00478 }
00479
00480 template <typename T, typename A>
00481 void vector<T, A>::resize(size_type n)
00482 {
00483 if (n < size()) erase(begin() + n, end());
00484 else insert(end(), n - size(), value_type());
00485 }
00486
00487 template <typename T, typename A>
00488 void vector<T, A>::resize(size_type n, const value_type& x)
00489 {
00490 if (n < size()) erase(begin() + n, end());
00491 else insert(end(), n - size(), x);
00492 }
00493
00494
00495
00496 #ifdef ADOBE_STD_SERIALIZATION
00497
00498 template <typename T, typename A>
00499 std::ostream& operator<<(std::ostream& out, const vector<T, A>& x)
00500 {
00501 out << begin_sequence;
00502
00503 for (typename vector<T, A>::const_iterator first(x.begin()), last(x.end()); first != last; ++first)
00504 {
00505 out << format(*first);
00506 }
00507
00508 out << end_sequence;
00509
00510 return out;
00511 }
00512
00513 #endif
00514
00515
00516
00517 BOOST_STATIC_ASSERT(sizeof(vector<int>) == sizeof(void*));
00518
00519
00520
00521 }
00522 }
00523
00524
00525
00526 ADOBE_NAME_TYPE_1("vector:version_1:adobe", adobe::version_1::vector<T0,
00527 adobe::capture_allocator<T0> >)
00528 ADOBE_NAME_TYPE_2("vector:version_1:adobe", adobe::version_1::vector<T0, T1>)
00529
00530
00531
00532 namespace boost {
00533
00534 template <typename T, typename A>
00535 struct has_nothrow_constructor<adobe::version_1::vector<T, A> > : boost::mpl::true_ { };
00536
00537 }
00538
00542
00543
00544 #endif