Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
vector.h
00001 ///\file 00002 00003 /****************************************************************************** 00004 The MIT License(MIT) 00005 00006 Embedded Template Library. 00007 https://github.com/ETLCPP/etl 00008 http://www.etlcpp.com 00009 00010 Copyright(c) 2014 jwellbelove 00011 00012 Permission is hereby granted, free of charge, to any person obtaining a copy 00013 of this software and associated documentation files(the "Software"), to deal 00014 in the Software without restriction, including without limitation the rights 00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00016 copies of the Software, and to permit persons to whom the Software is 00017 furnished to do so, subject to the following conditions : 00018 00019 The above copyright notice and this permission notice shall be included in all 00020 copies or substantial portions of the Software. 00021 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00028 SOFTWARE. 00029 ******************************************************************************/ 00030 00031 #ifndef __ETL_VECTOR__ 00032 #define __ETL_VECTOR__ 00033 00034 #define __ETL_IN_VECTOR_H__ 00035 00036 #include <stddef.h> 00037 #include <stdint.h> 00038 #include <iterator> 00039 #include <algorithm> 00040 #include <functional> 00041 #include <stddef.h> 00042 00043 #include "platform.h " 00044 #include "algorithm.h " 00045 #include "type_traits.h " 00046 #include "parameter_type.h " 00047 #include "error_handler.h " 00048 #include "memory.h " 00049 #include "container.h " 00050 #include "alignment.h " 00051 #include "array.h " 00052 #include "exception.h " 00053 #include "debug_count.h " 00054 #include "private/vector_base.h " 00055 00056 #ifdef ETL_COMPILER_GCC 00057 #pragma GCC diagnostic ignored "-Wunused-variable" 00058 #endif 00059 00060 //***************************************************************************** 00061 ///\defgroup vector vector 00062 /// A vector with the capacity defined at compile time. 00063 ///\ingroup containers 00064 //***************************************************************************** 00065 00066 namespace etl 00067 { 00068 //*************************************************************************** 00069 /// The base class for specifically sized vectors. 00070 /// Can be used as a reference type for all vectors containing a specific type. 00071 ///\ingroup vector 00072 //*************************************************************************** 00073 template <typename T> 00074 class ivector : public etl::vector_base 00075 { 00076 public: 00077 00078 typedef T value_type; 00079 typedef T& reference; 00080 typedef const T& const_reference; 00081 typedef T* pointer; 00082 typedef const T* const_pointer; 00083 typedef T* iterator; 00084 typedef const T* const_iterator; 00085 typedef std::reverse_iterator<iterator> reverse_iterator; 00086 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00087 typedef size_t size_type; 00088 typedef typename std::iterator_traits<iterator>::difference_type difference_type; 00089 00090 protected: 00091 00092 typedef typename etl::parameter_type<T>::type parameter_t; 00093 00094 public: 00095 00096 //********************************************************************* 00097 /// Returns an iterator to the beginning of the vector. 00098 ///\return An iterator to the beginning of the vector. 00099 //********************************************************************* 00100 iterator begin() 00101 { 00102 return p_buffer; 00103 } 00104 00105 //********************************************************************* 00106 /// Returns a const_iterator to the beginning of the vector. 00107 ///\return A const iterator to the beginning of the vector. 00108 //********************************************************************* 00109 const_iterator begin() const 00110 { 00111 return p_buffer; 00112 } 00113 00114 //********************************************************************* 00115 /// Returns an iterator to the end of the vector. 00116 ///\return An iterator to the end of the vector. 00117 //********************************************************************* 00118 iterator end() 00119 { 00120 return p_end; 00121 } 00122 00123 //********************************************************************* 00124 /// Returns a const_iterator to the end of the vector. 00125 ///\return A const iterator to the end of the vector. 00126 //********************************************************************* 00127 const_iterator end() const 00128 { 00129 return p_end; 00130 } 00131 00132 //********************************************************************* 00133 /// Returns a const_iterator to the beginning of the vector. 00134 ///\return A const iterator to the beginning of the vector. 00135 //********************************************************************* 00136 const_iterator cbegin() const 00137 { 00138 return p_buffer; 00139 } 00140 00141 //********************************************************************* 00142 /// Returns a const_iterator to the end of the vector. 00143 ///\return A const iterator to the end of the vector. 00144 //********************************************************************* 00145 const_iterator cend() const 00146 { 00147 return p_end; 00148 } 00149 00150 //********************************************************************* 00151 /// Returns an reverse iterator to the reverse beginning of the vector. 00152 ///\return Iterator to the reverse beginning of the vector. 00153 //********************************************************************* 00154 reverse_iterator rbegin() 00155 { 00156 return reverse_iterator(end()); 00157 } 00158 00159 //********************************************************************* 00160 /// Returns a const reverse iterator to the reverse beginning of the vector. 00161 ///\return Const iterator to the reverse beginning of the vector. 00162 //********************************************************************* 00163 const_reverse_iterator rbegin() const 00164 { 00165 return const_reverse_iterator(end()); 00166 } 00167 00168 //********************************************************************* 00169 /// Returns a reverse iterator to the end + 1 of the vector. 00170 ///\return Reverse iterator to the end + 1 of the vector. 00171 //********************************************************************* 00172 reverse_iterator rend() 00173 { 00174 return reverse_iterator(begin()); 00175 } 00176 00177 //********************************************************************* 00178 /// Returns a const reverse iterator to the end + 1 of the vector. 00179 ///\return Const reverse iterator to the end + 1 of the vector. 00180 //********************************************************************* 00181 const_reverse_iterator rend() const 00182 { 00183 return const_reverse_iterator(begin()); 00184 } 00185 00186 //********************************************************************* 00187 /// Returns a const reverse iterator to the reverse beginning of the vector. 00188 ///\return Const reverse iterator to the reverse beginning of the vector. 00189 //********************************************************************* 00190 const_reverse_iterator crbegin() const 00191 { 00192 return const_reverse_iterator(cend()); 00193 } 00194 00195 //********************************************************************* 00196 /// Returns a const reverse iterator to the end + 1 of the vector. 00197 ///\return Const reverse iterator to the end + 1 of the vector. 00198 //********************************************************************* 00199 const_reverse_iterator crend() const 00200 { 00201 return const_reverse_iterator(cbegin()); 00202 } 00203 00204 //********************************************************************* 00205 /// Resizes the vector. 00206 /// If asserts or exceptions are enabled and the new size is larger than the 00207 /// maximum then a vector_full is thrown. 00208 ///\param new_size The new size. 00209 //********************************************************************* 00210 void resize(size_t new_size) 00211 { 00212 resize(new_size, T()); 00213 } 00214 00215 //********************************************************************* 00216 /// Resizes the vector. 00217 /// If asserts or exceptions are enabled and the new size is larger than the 00218 /// maximum then a vector_full is thrown. 00219 ///\param new_size The new size. 00220 ///\param value The value to fill new elements with. Default = default constructed value. 00221 //********************************************************************* 00222 void resize(size_t new_size, T value) 00223 { 00224 ETL_ASSERT(new_size <= CAPACITY, ETL_ERROR(vector_full)); 00225 00226 const size_t current_size = size(); 00227 size_t delta = (current_size < new_size) ? new_size - current_size : current_size - new_size; 00228 00229 if (current_size < new_size) 00230 { 00231 etl::uninitialized_fill_n(p_end, delta, value); 00232 #if defined(ETL_DEBUG) 00233 construct_count += delta; 00234 #endif 00235 } 00236 else 00237 { 00238 etl::destroy_n(p_end - delta, delta); 00239 #if defined(ETL_DEBUG) 00240 construct_count -= delta; 00241 #endif 00242 } 00243 00244 p_end = p_buffer + new_size; 00245 } 00246 00247 //********************************************************************* 00248 /// Does nothing. 00249 //********************************************************************* 00250 void reserve(size_t) 00251 { 00252 } 00253 00254 //********************************************************************* 00255 /// Returns a reference to the value at index 'i' 00256 ///\param i The index. 00257 ///\return A reference to the value at index 'i' 00258 //********************************************************************* 00259 reference operator [](size_t i) 00260 { 00261 return p_buffer[i]; 00262 } 00263 00264 //********************************************************************* 00265 /// Returns a const reference to the value at index 'i' 00266 ///\param i The index. 00267 ///\return A const reference to the value at index 'i' 00268 //********************************************************************* 00269 const_reference operator [](size_t i) const 00270 { 00271 return p_buffer[i]; 00272 } 00273 00274 //********************************************************************* 00275 /// Returns a reference to the value at index 'i' 00276 /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range. 00277 ///\param i The index. 00278 ///\return A reference to the value at index 'i' 00279 //********************************************************************* 00280 reference at(size_t i) 00281 { 00282 ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); 00283 return p_buffer[i]; 00284 } 00285 00286 //********************************************************************* 00287 /// Returns a const reference to the value at index 'i' 00288 /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range. 00289 ///\param i The index. 00290 ///\return A const reference to the value at index 'i' 00291 //********************************************************************* 00292 const_reference at(size_t i) const 00293 { 00294 ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); 00295 return p_buffer[i]; 00296 } 00297 00298 //********************************************************************* 00299 /// Returns a reference to the first element. 00300 ///\return A reference to the first element. 00301 //********************************************************************* 00302 reference front() 00303 { 00304 return *p_buffer; 00305 } 00306 00307 //********************************************************************* 00308 /// Returns a const reference to the first element. 00309 ///\return A const reference to the first element. 00310 //********************************************************************* 00311 const_reference front() const 00312 { 00313 return *p_buffer; 00314 } 00315 00316 //********************************************************************* 00317 /// Returns a reference to the last element. 00318 ///\return A reference to the last element. 00319 //********************************************************************* 00320 reference back() 00321 { 00322 return *(p_end - 1); 00323 } 00324 00325 //********************************************************************* 00326 /// Returns a const reference to the last element. 00327 ///\return A const reference to the last element. 00328 //********************************************************************* 00329 const_reference back() const 00330 { 00331 return *(p_end - 1); 00332 } 00333 00334 //********************************************************************* 00335 /// Returns a pointer to the beginning of the vector data. 00336 ///\return A pointer to the beginning of the vector data. 00337 //********************************************************************* 00338 pointer data() 00339 { 00340 return p_buffer; 00341 } 00342 00343 //********************************************************************* 00344 /// Returns a const pointer to the beginning of the vector data. 00345 ///\return A const pointer to the beginning of the vector data. 00346 //********************************************************************* 00347 const_pointer data() const 00348 { 00349 return p_buffer; 00350 } 00351 00352 //********************************************************************* 00353 /// Assigns values to the vector. 00354 /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. 00355 /// If asserts or exceptions are enabled, emits vector_iterator if the iterators are reversed. 00356 ///\param first The iterator to the first element. 00357 ///\param last The iterator to the last element + 1. 00358 //********************************************************************* 00359 template <typename TIterator> 00360 void assign(TIterator first, TIterator last) 00361 { 00362 STATIC_ASSERT((etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename std::iterator_traits<TIterator>::value_type>::type>::value), "Iterator type does not match container type"); 00363 00364 #if defined(ETL_DEBUG) 00365 difference_type d = std::distance(first, last); 00366 ETL_ASSERT(static_cast<size_t>(d) <= CAPACITY, ETL_ERROR(vector_full)); 00367 #endif 00368 00369 initialise(); 00370 00371 #if defined(ETL_DEBUG) 00372 p_end = etl::uninitialized_copy(first, last, p_buffer, construct_count); 00373 #else 00374 p_end = etl::uninitialized_copy(first, last, p_buffer); 00375 #endif 00376 } 00377 00378 //********************************************************************* 00379 /// Assigns values to the vector. 00380 /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. 00381 ///\param n The number of elements to add. 00382 ///\param value The value to insert for each element. 00383 //********************************************************************* 00384 void assign(size_t n, parameter_t value) 00385 { 00386 ETL_ASSERT(n <= CAPACITY, ETL_ERROR(vector_full)); 00387 00388 initialise(); 00389 00390 #if defined(ETL_DEBUG) 00391 p_end = etl::uninitialized_fill_n(p_buffer, n, value, construct_count); 00392 #else 00393 p_end = etl::uninitialized_fill_n(p_buffer, n, value); 00394 #endif 00395 } 00396 00397 //************************************************************************* 00398 /// Clears the vector. 00399 //************************************************************************* 00400 void clear() 00401 { 00402 initialise(); 00403 } 00404 00405 //************************************************************************* 00406 /// Increases the size of the vector by one, but does not initialise the new element. 00407 /// If asserts or exceptions are enabled, throws a vector_full if the vector is already full. 00408 //************************************************************************* 00409 void push_back() 00410 { 00411 #if defined(ETL_CHECK_PUSH_POP) 00412 ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); 00413 #endif 00414 00415 create_back(); 00416 } 00417 00418 //********************************************************************* 00419 /// Inserts a value at the end of the vector. 00420 /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. 00421 ///\param value The value to add. 00422 //********************************************************************* 00423 void push_back(parameter_t value) 00424 { 00425 #if defined(ETL_CHECK_PUSH_POP) 00426 ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); 00427 #endif 00428 create_back(value); 00429 } 00430 00431 //********************************************************************* 00432 /// Constructs a value at the end of the vector. 00433 /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. 00434 ///\param value The value to add. 00435 //********************************************************************* 00436 template <typename T1> 00437 void emplace_back(const T1& value1) 00438 { 00439 #if defined(ETL_CHECK_PUSH_POP) 00440 ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); 00441 #endif 00442 ::new (p_end) T(value1); 00443 ++p_end; 00444 ++construct_count; 00445 } 00446 00447 //********************************************************************* 00448 /// Constructs a value at the end of the vector. 00449 /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. 00450 ///\param value The value to add. 00451 //********************************************************************* 00452 template <typename T1, typename T2> 00453 void emplace_back(const T1& value1, const T2& value2) 00454 { 00455 #if defined(ETL_CHECK_PUSH_POP) 00456 ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); 00457 #endif 00458 ::new (p_end) T(value1, value2); 00459 ++p_end; 00460 ++construct_count; 00461 } 00462 00463 //********************************************************************* 00464 /// Constructs a value at the end of the vector. 00465 /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. 00466 ///\param value The value to add. 00467 //********************************************************************* 00468 template <typename T1, typename T2, typename T3> 00469 void emplace_back(const T1& value1, const T2& value2, const T3& value3) 00470 { 00471 #if defined(ETL_CHECK_PUSH_POP) 00472 ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); 00473 #endif 00474 ::new (p_end) T(value1, value2, value3); 00475 ++p_end; 00476 ++construct_count; 00477 } 00478 00479 //********************************************************************* 00480 /// Constructs a value at the end of the vector. 00481 /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. 00482 ///\param value The value to add. 00483 //********************************************************************* 00484 template <typename T1, typename T2, typename T3, typename T4> 00485 void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) 00486 { 00487 #if defined(ETL_CHECK_PUSH_POP) 00488 ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); 00489 #endif 00490 ::new (p_end) T(value1, value2, value3, value4); 00491 ++p_end; 00492 ++construct_count; 00493 } 00494 00495 //************************************************************************* 00496 /// Removes an element from the end of the vector. 00497 /// Does nothing if the vector is empty. 00498 //************************************************************************* 00499 void pop_back() 00500 { 00501 #if defined(ETL_CHECK_PUSH_POP) 00502 ETL_ASSERT(size() > 0, ETL_ERROR(vector_empty)); 00503 #endif 00504 destroy_back(); 00505 } 00506 00507 //********************************************************************* 00508 /// Inserts a value to the vector. 00509 /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. 00510 ///\param position The position to insert before. 00511 ///\param value The value to insert. 00512 //********************************************************************* 00513 iterator insert(iterator position, parameter_t value) 00514 { 00515 ETL_ASSERT(size() + 1 <= CAPACITY, ETL_ERROR(vector_full)); 00516 00517 if (position == end()) 00518 { 00519 create_back(value); 00520 } 00521 else 00522 { 00523 create_back(back()); 00524 std::copy_backward(position, p_end - 1, p_end); 00525 *position = value; 00526 } 00527 00528 return position; 00529 } 00530 00531 //************************************************************************* 00532 /// Emplaces a value to the vextor at the specified position. 00533 //************************************************************************* 00534 template <typename T1> 00535 iterator emplace(iterator position, const T1& value1) 00536 { 00537 ETL_ASSERT(!full(), ETL_ERROR(vector_full)); 00538 00539 void* p; 00540 00541 if (position == end()) 00542 { 00543 p = p_end++; 00544 ++construct_count; 00545 } 00546 else 00547 { 00548 p = etl::addressof(*position); 00549 create_back(back()); 00550 std::copy_backward(position, p_end - 1, p_end); 00551 (*position).~T(); 00552 } 00553 00554 ::new (p) T(value1); 00555 00556 return position; 00557 } 00558 00559 //************************************************************************* 00560 /// Emplaces a value to the vextor at the specified position. 00561 //************************************************************************* 00562 template <typename T1, typename T2> 00563 iterator emplace(iterator position, const T1& value1, const T2& value2) 00564 { 00565 ETL_ASSERT(!full(), ETL_ERROR(vector_full)); 00566 00567 void* p; 00568 00569 if (position == end()) 00570 { 00571 p = p_end++; 00572 ++construct_count; 00573 } 00574 else 00575 { 00576 p = etl::addressof(*position); 00577 create_back(back()); 00578 std::copy_backward(position, p_end - 1, p_end); 00579 (*position).~T(); 00580 } 00581 00582 ::new (p) T(value1, value2); 00583 00584 return position; 00585 } 00586 00587 //************************************************************************* 00588 /// Emplaces a value to the vextor at the specified position. 00589 //************************************************************************* 00590 template <typename T1, typename T2, typename T3> 00591 iterator emplace(iterator position, const T1& value1, const T2& value2, const T3& value3) 00592 { 00593 ETL_ASSERT(!full(), ETL_ERROR(vector_full)); 00594 00595 void* p; 00596 00597 if (position == end()) 00598 { 00599 p = p_end++; 00600 ++construct_count; 00601 } 00602 else 00603 { 00604 p = etl::addressof(*position); 00605 create_back(back()); 00606 std::copy_backward(position, p_end - 1, p_end); 00607 (*position).~T(); 00608 } 00609 00610 ::new (p) T(value1, value2, value3); 00611 00612 return position; 00613 } 00614 00615 //************************************************************************* 00616 /// Emplaces a value to the vextor at the specified position. 00617 //************************************************************************* 00618 template <typename T1, typename T2, typename T3, typename T4> 00619 iterator emplace(iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4) 00620 { 00621 ETL_ASSERT(!full(), ETL_ERROR(vector_full)); 00622 00623 void* p; 00624 00625 if (position == end()) 00626 { 00627 p = p_end++; 00628 ++construct_count; 00629 } 00630 else 00631 { 00632 p = etl::addressof(*position); 00633 create_back(back()); 00634 std::copy_backward(position, p_end - 1, p_end); 00635 (*position).~T(); 00636 } 00637 00638 ::new (p) T(value1, value2, value3, value4); 00639 00640 return position; 00641 } 00642 00643 //********************************************************************* 00644 /// Inserts 'n' values to the vector. 00645 /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. 00646 ///\param position The position to insert before. 00647 ///\param n The number of elements to add. 00648 ///\param value The value to insert. 00649 //********************************************************************* 00650 void insert(iterator position, size_t n, parameter_t value) 00651 { 00652 ETL_ASSERT((size() + n) <= CAPACITY, ETL_ERROR(vector_full)); 00653 00654 size_t insert_n = n; 00655 size_t insert_begin = std::distance(begin(), position); 00656 size_t insert_end = insert_begin + insert_n; 00657 00658 // Copy old data. 00659 size_t copy_old_n; 00660 size_t construct_old_n; 00661 iterator p_construct_old; 00662 00663 if (insert_end > size()) 00664 { 00665 copy_old_n = 0; 00666 construct_old_n = size() - insert_begin; 00667 p_construct_old = p_buffer + insert_end; 00668 } 00669 else 00670 { 00671 copy_old_n = size() - insert_begin - insert_n; 00672 construct_old_n = insert_n; 00673 p_construct_old = p_end; 00674 } 00675 00676 size_t copy_new_n = construct_old_n; 00677 size_t construct_new_n = insert_n - copy_new_n; 00678 00679 #if defined(ETL_DEBUG) 00680 // Construct old. 00681 etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old, construct_count); 00682 00683 // Copy old. 00684 etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); 00685 00686 // Construct new. 00687 etl::uninitialized_fill_n(p_end, construct_new_n, value, construct_count); 00688 00689 // Copy new. 00690 std::fill_n(p_buffer + insert_begin, copy_new_n, value); 00691 #else 00692 // Construct old. 00693 etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old); 00694 00695 // Copy old. 00696 etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); 00697 00698 // Construct new. 00699 etl::uninitialized_fill_n(p_end, construct_new_n, value); 00700 00701 // Copy new. 00702 std::fill_n(p_buffer + insert_begin, copy_new_n, value); 00703 #endif 00704 00705 p_end += n; 00706 } 00707 00708 //********************************************************************* 00709 /// Inserts a range of values to the vector. 00710 /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. 00711 /// For fundamental and pointer types. 00712 ///\param position The position to insert before. 00713 ///\param first The first element to add. 00714 ///\param last The last + 1 element to add. 00715 //********************************************************************* 00716 template <class TIterator> 00717 void insert(iterator position, TIterator first, TIterator last) 00718 { 00719 size_t count = std::distance(first, last); 00720 00721 ETL_ASSERT((size() + count) <= CAPACITY, ETL_ERROR(vector_full)); 00722 00723 size_t insert_n = count; 00724 size_t insert_begin = std::distance(begin(), position); 00725 size_t insert_end = insert_begin + insert_n; 00726 00727 // Copy old data. 00728 size_t copy_old_n; 00729 size_t construct_old_n; 00730 iterator p_construct_old; 00731 00732 if (insert_end > size()) 00733 { 00734 copy_old_n = 0; 00735 construct_old_n = size() - insert_begin; 00736 p_construct_old = p_buffer + insert_end; 00737 } 00738 else 00739 { 00740 copy_old_n = size() - insert_begin - insert_n; 00741 construct_old_n = insert_n; 00742 p_construct_old = p_end; 00743 } 00744 00745 size_t copy_new_n = construct_old_n; 00746 size_t construct_new_n = insert_n - copy_new_n; 00747 00748 #if defined(ETL_DEBUG) 00749 // Construct old. 00750 etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old, construct_count); 00751 00752 // Copy old. 00753 etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); 00754 00755 // Construct new. 00756 etl::uninitialized_copy_n(first + copy_new_n, construct_new_n, p_end, construct_count); 00757 00758 // Copy new. 00759 etl::copy_n(first, copy_new_n, p_buffer + insert_begin); 00760 #else 00761 // Construct old. 00762 etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old); 00763 00764 // Copy old. 00765 etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); 00766 00767 // Construct new. 00768 etl::uninitialized_copy_n(first + copy_new_n, construct_new_n, p_end); 00769 00770 // Copy new. 00771 etl::copy_n(first, copy_new_n, p_buffer + insert_begin); 00772 #endif 00773 00774 p_end += count; 00775 } 00776 00777 //********************************************************************* 00778 /// Erases an element. 00779 ///\param i_element Iterator to the element. 00780 ///\return An iterator pointing to the element that followed the erased element. 00781 //********************************************************************* 00782 iterator erase(iterator i_element) 00783 { 00784 std::copy(i_element + 1, end(), i_element); 00785 destroy_back(); 00786 00787 return i_element; 00788 } 00789 00790 //********************************************************************* 00791 /// Erases a range of elements. 00792 /// The range includes all the elements between first and last, including the 00793 /// element pointed by first, but not the one pointed by last. 00794 ///\param first Iterator to the first element. 00795 ///\param last Iterator to the last element. 00796 ///\return An iterator pointing to the element that followed the erased element. 00797 //********************************************************************* 00798 iterator erase(iterator first, iterator last) 00799 { 00800 if (first == begin() && last == end()) 00801 { 00802 clear(); 00803 } 00804 else 00805 { 00806 std::copy(last, end(), first); 00807 size_t n_delete = std::distance(first, last); 00808 00809 // Destroy the elements left over at the end. 00810 #if defined(ETL_DEBUG) 00811 etl::destroy(p_end - n_delete, p_end, construct_count); 00812 #else 00813 etl::destroy(p_end - n_delete, p_end); 00814 #endif 00815 p_end -= n_delete; 00816 } 00817 00818 return first; 00819 } 00820 00821 //************************************************************************* 00822 /// Assignment operator. 00823 //************************************************************************* 00824 ivector& operator = (const ivector& rhs) 00825 { 00826 if (&rhs != this) 00827 { 00828 assign(rhs.cbegin(), rhs.cend()); 00829 } 00830 00831 return *this; 00832 } 00833 00834 //************************************************************************* 00835 /// Gets the current size of the vector. 00836 ///\return The current size of the vector. 00837 //************************************************************************* 00838 size_type size() const 00839 { 00840 return size_t(p_end - p_buffer); 00841 } 00842 00843 //************************************************************************* 00844 /// Checks the 'empty' state of the vector. 00845 ///\return <b>true</b> if empty. 00846 //************************************************************************* 00847 bool empty() const 00848 { 00849 return (p_end == p_buffer); 00850 } 00851 00852 //************************************************************************* 00853 /// Checks the 'full' state of the vector. 00854 ///\return <b>true</b> if full. 00855 //************************************************************************* 00856 bool full() const 00857 { 00858 return size() == CAPACITY; 00859 } 00860 00861 //************************************************************************* 00862 /// Returns the remaining capacity. 00863 ///\return The remaining capacity. 00864 //************************************************************************* 00865 size_t available() const 00866 { 00867 return max_size() - size(); 00868 } 00869 00870 #ifdef ETL_IVECTOR_REPAIR_ENABLE 00871 //************************************************************************* 00872 /// Fix the internal pointers after a low level memory copy. 00873 //************************************************************************* 00874 virtual void repair() = 0; 00875 #endif 00876 00877 protected: 00878 00879 //********************************************************************* 00880 /// Constructor. 00881 //********************************************************************* 00882 ivector(T* p_buffer_, size_t MAX_SIZE) 00883 : vector_base(MAX_SIZE), 00884 p_buffer(p_buffer_), 00885 p_end(p_buffer_) 00886 { 00887 } 00888 00889 //********************************************************************* 00890 /// Initialise the vector. 00891 //********************************************************************* 00892 void initialise() 00893 { 00894 #if defined(ETL_DEBUG) 00895 etl::destroy(p_buffer, p_end, construct_count); 00896 #else 00897 etl::destroy(p_buffer, p_end); 00898 #endif 00899 00900 p_end = p_buffer; 00901 } 00902 00903 //************************************************************************* 00904 /// Fix the internal pointers after a low level memory copy. 00905 //************************************************************************* 00906 void repair(T* p_buffer_) 00907 { 00908 uintptr_t length = p_end - p_buffer; 00909 p_buffer = p_buffer_; 00910 p_end = p_buffer_ + length; 00911 } 00912 00913 private: 00914 00915 pointer p_buffer; ///< Pointer to the start of the buffer. 00916 pointer p_end; ///< Pointer to one past the last element in the buffer. 00917 00918 //********************************************************************* 00919 /// Create a new element with a default value at the back. 00920 //********************************************************************* 00921 inline void create_back() 00922 { 00923 #if defined(ETL_DEBUG) 00924 etl::create_value_at(p_end, construct_count); 00925 #else 00926 etl::create_value_at(p_end); 00927 #endif 00928 ++p_end; 00929 } 00930 00931 //********************************************************************* 00932 /// Create a new element with a value at the back 00933 //********************************************************************* 00934 inline void create_back(parameter_t value) 00935 { 00936 #if defined(ETL_DEBUG) 00937 etl::create_copy_at(p_end, value, construct_count); 00938 #else 00939 etl::create_copy_at(p_end, value); 00940 #endif 00941 ++p_end; 00942 } 00943 00944 //********************************************************************* 00945 /// Destroy an element at the back. 00946 //********************************************************************* 00947 inline void destroy_back() 00948 { 00949 --p_end; 00950 00951 #if defined(ETL_DEBUG) 00952 etl::destroy_at(p_end, construct_count); 00953 #else 00954 etl::destroy_at(p_end); 00955 #endif 00956 } 00957 00958 // Disable copy construction. 00959 ivector(const ivector&); 00960 }; 00961 00962 //*************************************************************************** 00963 /// Equal operator. 00964 ///\param lhs Reference to the first vector. 00965 ///\param rhs Reference to the second vector. 00966 ///\return <b>true</b> if the arrays are equal, otherwise <b>false</b> 00967 ///\ingroup vector 00968 //*************************************************************************** 00969 template <typename T> 00970 bool operator ==(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs) 00971 { 00972 return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin()); 00973 } 00974 00975 //*************************************************************************** 00976 /// Not equal operator. 00977 ///\param lhs Reference to the first vector. 00978 ///\param rhs Reference to the second vector. 00979 ///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b> 00980 ///\ingroup vector 00981 //*************************************************************************** 00982 template <typename T> 00983 bool operator !=(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs) 00984 { 00985 return !(lhs == rhs); 00986 } 00987 00988 //*************************************************************************** 00989 /// Less than operator. 00990 ///\param lhs Reference to the first vector. 00991 ///\param rhs Reference to the second vector. 00992 ///\return <b>true</b> if the first vector is lexicographically less than the second, otherwise <b>false</b> 00993 ///\ingroup vector 00994 //*************************************************************************** 00995 template <typename T> 00996 bool operator <(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs) 00997 { 00998 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); 00999 } 01000 01001 //*************************************************************************** 01002 /// Greater than operator. 01003 ///\param lhs Reference to the first vector. 01004 ///\param rhs Reference to the second vector. 01005 ///\return <b>true</b> if the first vector is lexicographically greater than the second, otherwise <b>false</b> 01006 ///\ingroup vector 01007 //*************************************************************************** 01008 template <typename T> 01009 bool operator >(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs) 01010 { 01011 return (rhs < lhs); 01012 } 01013 01014 //*************************************************************************** 01015 /// Less than or equal operator. 01016 ///\param lhs Reference to the first vector. 01017 ///\param rhs Reference to the second vector. 01018 ///\return <b>true</b> if the first vector is lexicographically less than or equal to the second, otherwise <b>false</b> 01019 ///\ingroup vector 01020 //*************************************************************************** 01021 template <typename T> 01022 bool operator <=(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs) 01023 { 01024 return !(lhs > rhs); 01025 } 01026 01027 //*************************************************************************** 01028 /// Greater than or equal operator. 01029 ///\param lhs Reference to the first vector. 01030 ///\param rhs Reference to the second vector. 01031 ///\return <b>true</b> if the first vector is lexicographically greater than or equal to the second, otherwise <b>false</b> 01032 ///\ingroup vector 01033 //*************************************************************************** 01034 template <typename T> 01035 bool operator >=(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs) 01036 { 01037 return !(lhs < rhs); 01038 } 01039 01040 //*************************************************************************** 01041 /// A vector implementation that uses a fixed size buffer. 01042 ///\tparam T The element type. 01043 ///\tparam MAX_SIZE_ The maximum number of elements that can be stored. 01044 ///\ingroup vector 01045 //*************************************************************************** 01046 template <typename T, const size_t MAX_SIZE_> 01047 class vector : public etl::ivector<T> 01048 { 01049 public: 01050 01051 static const size_t MAX_SIZE = MAX_SIZE_; 01052 01053 //************************************************************************* 01054 /// Constructor. 01055 //************************************************************************* 01056 vector() 01057 : etl::ivector<T>(reinterpret_cast<T*>(&buffer), MAX_SIZE) 01058 { 01059 etl::ivector<T>::initialise(); 01060 } 01061 01062 //************************************************************************* 01063 /// Constructor, with size. 01064 ///\param initial_size The initial size of the vector. 01065 //************************************************************************* 01066 explicit vector(size_t initial_size) 01067 : etl::ivector<T>(reinterpret_cast<T*>(&buffer), MAX_SIZE) 01068 { 01069 etl::ivector<T>::initialise(); 01070 etl::ivector<T>::resize(initial_size); 01071 } 01072 01073 //************************************************************************* 01074 /// Constructor, from initial size and value. 01075 ///\param initial_size The initial size of the vector. 01076 ///\param value The value to fill the vector with. 01077 //************************************************************************* 01078 vector(size_t initial_size, typename etl::ivector<T>::parameter_t value) 01079 : etl::ivector<T>(reinterpret_cast<T*>(&buffer), MAX_SIZE) 01080 { 01081 etl::ivector<T>::initialise(); 01082 etl::ivector<T>::resize(initial_size, value); 01083 } 01084 01085 //************************************************************************* 01086 /// Constructor, from an iterator range. 01087 ///\tparam TIterator The iterator type. 01088 ///\param first The iterator to the first element. 01089 ///\param last The iterator to the last element + 1. 01090 //************************************************************************* 01091 template <typename TIterator> 01092 vector(TIterator first, TIterator last) 01093 : etl::ivector<T>(reinterpret_cast<T*>(&buffer), MAX_SIZE) 01094 { 01095 etl::ivector<T>::assign(first, last); 01096 } 01097 01098 //************************************************************************* 01099 /// Copy constructor. 01100 //************************************************************************* 01101 vector(const vector& other) 01102 : etl::ivector<T>(reinterpret_cast<T*>(&buffer), MAX_SIZE) 01103 { 01104 etl::ivector<T>::assign(other.begin(), other.end()); 01105 } 01106 01107 //************************************************************************* 01108 /// Destructor. 01109 //************************************************************************* 01110 ~vector() 01111 { 01112 etl::ivector<T>::clear(); 01113 } 01114 01115 //************************************************************************* 01116 /// Assignment operator. 01117 //************************************************************************* 01118 vector& operator = (const vector& rhs) 01119 { 01120 if (&rhs != this) 01121 { 01122 etl::ivector<T>::assign(rhs.cbegin(), rhs.cend()); 01123 } 01124 01125 return *this; 01126 } 01127 01128 //************************************************************************* 01129 /// Fix the internal pointers after a low level memory copy. 01130 //************************************************************************* 01131 void repair() 01132 { 01133 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED 01134 ETL_ASSERT(std::is_trivially_copyable<T>::value, ETL_ERROR(etl::vector_incompatible_type)); 01135 #endif 01136 01137 etl::ivector<T>::repair(buffer); 01138 } 01139 01140 private: 01141 01142 typename etl::aligned_storage<sizeof(T) * MAX_SIZE, etl::alignment_of<T>::value>::type buffer; 01143 }; 01144 01145 //*************************************************************************** 01146 /// A vector implementation that uses a fixed size buffer. 01147 ///\tparam T The element type. 01148 ///\tparam MAX_SIZE_ The maximum number of elements that can be stored. 01149 ///\ingroup vector 01150 //*************************************************************************** 01151 template <typename T, const size_t MAX_SIZE_> 01152 class vector<T*, MAX_SIZE_> : public etl::ivector<T*> 01153 { 01154 public: 01155 01156 static const size_t MAX_SIZE = MAX_SIZE_; 01157 01158 //************************************************************************* 01159 /// Constructor. 01160 //************************************************************************* 01161 vector() 01162 : etl::ivector<T*>(reinterpret_cast<T**>(&buffer), MAX_SIZE) 01163 { 01164 etl::ivector<T*>::initialise(); 01165 } 01166 01167 //************************************************************************* 01168 /// Constructor, with size. 01169 ///\param initial_size The initial size of the vector. 01170 //************************************************************************* 01171 explicit vector(size_t initial_size) 01172 : etl::ivector<T*>(reinterpret_cast<T**>(&buffer), MAX_SIZE) 01173 { 01174 etl::ivector<T*>::initialise(); 01175 etl::ivector<T*>::resize(initial_size); 01176 } 01177 01178 //************************************************************************* 01179 /// Constructor, from initial size and value. 01180 ///\param initial_size The initial size of the vector. 01181 ///\param value The value to fill the vector with. 01182 //************************************************************************* 01183 vector(size_t initial_size, typename etl::ivector<T*>::parameter_t value) 01184 : etl::ivector<T*>(reinterpret_cast<T**>(&buffer), MAX_SIZE) 01185 { 01186 etl::ivector<T*>::initialise(); 01187 etl::ivector<T*>::resize(initial_size, value); 01188 } 01189 01190 //************************************************************************* 01191 /// Constructor, from an iterator range. 01192 ///\tparam TIterator The iterator type. 01193 ///\param first The iterator to the first element. 01194 ///\param last The iterator to the last element + 1. 01195 //************************************************************************* 01196 template <typename TIterator> 01197 vector(TIterator first, TIterator last) 01198 : etl::ivector<T*>(reinterpret_cast<T**>(&buffer), MAX_SIZE) 01199 { 01200 etl::ivector<T*>::assign(first, last); 01201 } 01202 01203 //************************************************************************* 01204 /// Copy constructor. 01205 //************************************************************************* 01206 vector(const vector& other) 01207 : etl::ivector<T*>(reinterpret_cast<T**>(&buffer), MAX_SIZE) 01208 { 01209 etl::ivector<T*>::assign(other.begin(), other.end()); 01210 } 01211 01212 //************************************************************************* 01213 /// Assignment operator. 01214 //************************************************************************* 01215 vector& operator = (const vector& rhs) 01216 { 01217 if (&rhs != this) 01218 { 01219 etl::ivector<T*>::assign(rhs.cbegin(), rhs.cend()); 01220 } 01221 01222 return *this; 01223 } 01224 01225 //************************************************************************* 01226 /// Fix the internal pointers after a low level memory copy. 01227 //************************************************************************* 01228 void repair() 01229 { 01230 etl::ivector<T*>::repair(buffer); 01231 } 01232 01233 private: 01234 01235 typename etl::aligned_storage<sizeof(T*) * MAX_SIZE, etl::alignment_of<T*>::value>::type buffer; 01236 }; 01237 } 01238 01239 #include "private/ivectorpointer.h " 01240 01241 #endif 01242
Generated on Tue Jul 12 2022 14:05:46 by
