Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vector.h Source File

vector.h

Go to the documentation of this file.
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