Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pvoidvector.h Source File

pvoidvector.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) 2016 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_PVOIDVECTOR__
00032 #define __ETL_PVOIDVECTOR__
00033 
00034 #define __ETL_IN_PVOIDVECTOR__
00035 
00036 #include <iterator>
00037 #include <algorithm>
00038 #include <functional>
00039 #include <stddef.h>
00040 
00041 #include "../platform.h"
00042 #include "../algorithm.h"
00043 #include "vector_base.h "
00044 #include "../type_traits.h"
00045 #include "../error_handler.h"
00046 
00047 #ifdef ETL_COMPILER_GCC
00048 #pragma GCC diagnostic ignored "-Wunused-variable"
00049 #endif
00050 
00051 #ifdef ETL_COMPILER_MICROSOFT
00052 #undef min
00053 #endif
00054 
00055 namespace etl
00056 {
00057   //***************************************************************************
00058   /// The base class for void* vectors.
00059   ///\ingroup vector
00060   //***************************************************************************
00061   class pvoidvector : public vector_base
00062   {
00063   public:
00064 
00065     typedef void*                                 value_type;
00066     typedef void*&                                reference;
00067     typedef const void*&                          const_reference;
00068     typedef void**                                pointer;
00069     typedef const void**                          const_pointer;
00070     typedef void**                                iterator;
00071     typedef const void**                          const_iterator;
00072     typedef std::reverse_iterator<iterator>       reverse_iterator;
00073     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00074     typedef size_t                                size_type;
00075     typedef std::iterator_traits<iterator>::difference_type difference_type;
00076 
00077   public:
00078 
00079     //*********************************************************************
00080     /// Returns an iterator to the beginning of the vector.
00081     ///\return An iterator to the beginning of the vector.
00082     //*********************************************************************
00083     iterator begin()
00084     {
00085       return p_buffer;
00086     }
00087 
00088     //*********************************************************************
00089     /// Returns a const_iterator to the beginning of the vector.
00090     ///\return A const iterator to the beginning of the vector.
00091     //*********************************************************************
00092     const_iterator begin() const
00093     {
00094       return const_iterator(p_buffer);
00095     }
00096 
00097     //*********************************************************************
00098     /// Returns an iterator to the end of the vector.
00099     ///\return An iterator to the end of the vector.
00100     //*********************************************************************
00101     iterator end()
00102     {
00103       return p_end;
00104     }
00105 
00106     //*********************************************************************
00107     /// Returns a const_iterator to the end of the vector.
00108     ///\return A const iterator to the end of the vector.
00109     //*********************************************************************
00110     const_iterator end() const
00111     {
00112       return const_iterator(p_end);
00113     }
00114 
00115     //*********************************************************************
00116     /// Returns a const_iterator to the beginning of the vector.
00117     ///\return A const iterator to the beginning of the vector.
00118     //*********************************************************************
00119     const_iterator cbegin() const
00120     {
00121       return const_iterator(p_buffer);
00122     }
00123 
00124     //*********************************************************************
00125     /// Returns a const_iterator to the end of the vector.
00126     ///\return A const iterator to the end of the vector.
00127     //*********************************************************************
00128     const_iterator cend() const
00129     {
00130       return const_iterator(p_end);
00131     }
00132 
00133     //*********************************************************************
00134     /// Returns an reverse iterator to the reverse beginning of the vector.
00135     ///\return Iterator to the reverse beginning of the vector.
00136     //*********************************************************************
00137     reverse_iterator rbegin()
00138     {
00139       return reverse_iterator(end());
00140     }
00141 
00142     //*********************************************************************
00143     /// Returns a const reverse iterator to the reverse beginning of the vector.
00144     ///\return Const iterator to the reverse beginning of the vector.
00145     //*********************************************************************
00146     const_reverse_iterator rbegin() const
00147     {
00148       return const_reverse_iterator(end());
00149     }
00150 
00151     //*********************************************************************
00152     /// Returns a reverse iterator to the end + 1 of the vector.
00153     ///\return Reverse iterator to the end + 1 of the vector.
00154     //*********************************************************************
00155     reverse_iterator rend()
00156     {
00157       return reverse_iterator(begin());
00158     }
00159 
00160     //*********************************************************************
00161     /// Returns a const reverse iterator to the end + 1 of the vector.
00162     ///\return Const reverse iterator to the end + 1 of the vector.
00163     //*********************************************************************
00164     const_reverse_iterator rend() const
00165     {
00166       return const_reverse_iterator(begin());
00167     }
00168 
00169     //*********************************************************************
00170     /// Returns a const reverse iterator to the reverse beginning of the vector.
00171     ///\return Const reverse iterator to the reverse beginning of the vector.
00172     //*********************************************************************
00173     const_reverse_iterator crbegin() const
00174     {
00175       return const_reverse_iterator(cend());
00176     }
00177 
00178     //*********************************************************************
00179     /// Returns a const reverse iterator to the end + 1 of the vector.
00180     ///\return Const reverse iterator to the end + 1 of the vector.
00181     //*********************************************************************
00182     const_reverse_iterator crend() const
00183     {
00184       return const_reverse_iterator(cbegin());
00185     }
00186 
00187     //*********************************************************************
00188     /// Resizes the vector.
00189     /// If asserts or exceptions are enabled and the new size is larger than the
00190     /// maximum then a vector_full is thrown.
00191     ///\param new_size The new size.
00192     //*********************************************************************
00193     void resize(size_t new_size)
00194     {
00195       ETL_ASSERT(new_size <= CAPACITY, ETL_ERROR(vector_full));
00196 
00197       p_end = p_buffer + new_size;
00198     }
00199 
00200     //*********************************************************************
00201     /// Resizes the vector.
00202     /// If asserts or exceptions are enabled and the new size is larger than the
00203     /// maximum then a vector_full is thrown.
00204     ///\param new_size The new size.
00205     ///\param value   The value to fill new elements with. Default = default constructed value.
00206     //*********************************************************************
00207     void resize(size_t new_size, value_type value)
00208     {
00209       ETL_ASSERT(new_size <= CAPACITY, ETL_ERROR(vector_full));
00210 
00211       pointer p_new_end = p_buffer + new_size;
00212 
00213       // Size up if necessary.
00214       if (p_end < p_new_end)
00215       {
00216         std::fill(p_end, p_new_end, value);
00217       }
00218 
00219       p_end = p_new_end;
00220     }
00221 
00222     //*********************************************************************
00223     /// Returns a reference to the value at index 'i'
00224     ///\param i The index.
00225     ///\return A reference to the value at index 'i'
00226     //*********************************************************************
00227     reference operator [](size_t i)
00228     {
00229       return p_buffer[i];
00230     }
00231 
00232     //*********************************************************************
00233     /// Returns a const reference to the value at index 'i'
00234     ///\param i The index.
00235     ///\return A const reference to the value at index 'i'
00236     //*********************************************************************
00237     const_reference operator [](size_t i) const
00238     {
00239       return const_reference(p_buffer[i]);
00240     }
00241 
00242     //*********************************************************************
00243     /// Returns a reference to the value at index 'i'
00244     /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range.
00245     ///\param i The index.
00246     ///\return A reference to the value at index 'i'
00247     //*********************************************************************
00248     reference at(size_t i)
00249     {
00250       ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds));
00251       return p_buffer[i];
00252     }
00253 
00254     //*********************************************************************
00255     /// Returns a const reference to the value at index 'i'
00256     /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range.
00257     ///\param i The index.
00258     ///\return A const reference to the value at index 'i'
00259     //*********************************************************************
00260     const_reference at(size_t i) const
00261     {
00262       ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds));
00263       return const_reference(p_buffer[i]);
00264     }
00265 
00266     //*********************************************************************
00267     /// Returns a reference to the first element.
00268     ///\return A reference to the first element.
00269     //*********************************************************************
00270     reference front()
00271     {
00272       return p_buffer[0];
00273     }
00274 
00275     //*********************************************************************
00276     /// Returns a const reference to the first element.
00277     ///\return A const reference to the first element.
00278     //*********************************************************************
00279     const_reference front() const
00280     {
00281       return const_reference(p_buffer[0]);
00282     }
00283 
00284     //*********************************************************************
00285     /// Returns a reference to the last element.
00286     ///\return A reference to the last element.
00287     //*********************************************************************
00288     reference back()
00289     {
00290       return *(p_end  -1);
00291     }
00292 
00293     //*********************************************************************
00294     /// Returns a const reference to the last element.
00295     ///\return A const reference to the last element.
00296     //*********************************************************************
00297     const_reference back() const
00298     {
00299       return const_reference(*(p_end - 1));
00300     }
00301 
00302     //*********************************************************************
00303     /// Returns a pointer to the beginning of the vector data.
00304     ///\return A pointer to the beginning of the vector data.
00305     //*********************************************************************
00306     pointer data()
00307     {
00308       return p_buffer;
00309     }
00310 
00311     //*********************************************************************
00312     /// Returns a const pointer to the beginning of the vector data.
00313     ///\return A const pointer to the beginning of the vector data.
00314     //*********************************************************************
00315     const_pointer data() const
00316     {
00317       return const_pointer(p_buffer);
00318     }
00319 
00320     //*********************************************************************
00321     /// Assigns values to the vector.
00322     /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
00323     /// If asserts or exceptions are enabled, emits vector_iterator if the iterators are reversed.
00324     ///\param first The iterator to the first element.
00325     ///\param last  The iterator to the last element + 1.
00326     //*********************************************************************
00327     template <typename TIterator>
00328     void assign(TIterator first, TIterator last)
00329     {
00330 #if defined(ETL_DEBUG)
00331       difference_type d = std::distance(first, last);
00332       ETL_ASSERT(static_cast<size_t>(d) <= CAPACITY, ETL_ERROR(vector_full));
00333 #endif
00334 
00335       initialise();
00336 
00337       while (first != last)
00338       {
00339         *p_end++ = const_cast<void*>(*first++);
00340       }
00341     }
00342 
00343     //*********************************************************************
00344     /// Assigns values to the vector.
00345     /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
00346     ///\param n     The number of elements to add.
00347     ///\param value The value to insert for each element.
00348     //*********************************************************************
00349     void assign(size_t n, value_type value)
00350     {
00351       initialise();
00352 
00353       ETL_ASSERT(n <= CAPACITY, ETL_ERROR(vector_full));
00354 
00355       for (size_t current_size = 0; current_size < n; ++current_size)
00356       {
00357         *p_end++ = value;
00358       }
00359     }
00360 
00361     //*************************************************************************
00362     /// Clears the vector.
00363     //*************************************************************************
00364     void clear()
00365     {
00366       initialise();
00367     }
00368 
00369     //*************************************************************************
00370     /// Increases the size of the vector by one, but does not initialise the new element.
00371     /// If asserts or exceptions are enabled, throws a vector_full if the vector is already full.
00372     //*************************************************************************
00373     void push_back()
00374     {
00375 #if defined(ETL_CHECK_PUSH_POP)
00376       ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
00377 #endif
00378 
00379       ++p_end;
00380     }
00381 
00382     //*********************************************************************
00383     /// Inserts a value at the end of the vector.
00384     /// If asserts or exceptions are enabled, emits vector_full if the vector is already full.
00385     ///\param value The value to add.
00386     //*********************************************************************
00387     void push_back(value_type value)
00388     {
00389 #if defined(ETL_CHECK_PUSH_POP)
00390       ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
00391 #endif
00392       *p_end++ = value;
00393     }
00394 
00395     //*************************************************************************
00396     /// Removes an element from the end of the vector.
00397     /// Does nothing if the vector is empty.
00398     //*************************************************************************
00399     void pop_back()
00400     {
00401 #if defined(ETL_CHECK_PUSH_POP)
00402       ETL_ASSERT(size() > 0, ETL_ERROR(vector_empty));
00403 #endif
00404       --p_end;
00405     }
00406 
00407     //*********************************************************************
00408     /// Inserts a value to the vector.
00409     /// If asserts or exceptions are enabled, emits vector_full if the vector is already full.
00410     ///\param position The position to insert before.
00411     ///\param value    The value to insert.
00412     //*********************************************************************
00413     iterator insert(iterator position, value_type value)
00414     {
00415       ETL_ASSERT(size() + 1 <= CAPACITY, ETL_ERROR(vector_full));
00416 
00417       if (position != end())
00418       {
00419         ++p_end;
00420         std::copy_backward(position, end() - 1, end());
00421         *position = value;
00422       }
00423       else
00424       {
00425         *p_end++ = value;
00426       }
00427 
00428       return position;
00429     }
00430 
00431     //*********************************************************************
00432     /// Inserts 'n' values to the vector.
00433     /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
00434     ///\param position The position to insert before.
00435     ///\param n        The number of elements to add.
00436     ///\param value    The value to insert.
00437     //*********************************************************************
00438     void insert(iterator position, size_t n, value_type value)
00439     {
00440       ETL_ASSERT((size() + 1) <= CAPACITY, ETL_ERROR(vector_full));
00441 
00442       std::copy_backward(position, p_end, p_end + n);
00443       std::fill_n(position, n, value);
00444 
00445       p_end += n;
00446     }
00447 
00448     //*********************************************************************
00449     /// Inserts a range of values to the vector.
00450     /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
00451     /// For fundamental and pointer types.
00452     ///\param position The position to insert before.
00453     ///\param first    The first element to add.
00454     ///\param last     The last + 1 element to add.
00455     //*********************************************************************
00456     template <typename TIterator>
00457     void insert(iterator position, TIterator first, TIterator last)
00458     {
00459       size_t count = std::distance(first, last);
00460 
00461       ETL_ASSERT((size() + count) <= CAPACITY, ETL_ERROR(vector_full));
00462 
00463       std::copy_backward(position, p_end, p_end + count);
00464       std::copy(first, last, position);
00465       p_end += count;
00466     }
00467 
00468     //*********************************************************************
00469     /// Erases an element.
00470     ///\param i_element Iterator to the element.
00471     ///\return An iterator pointing to the element that followed the erased element.
00472     //*********************************************************************
00473     iterator erase(iterator i_element)
00474     {
00475       std::copy(i_element + 1, end(), i_element);
00476       --p_end;
00477 
00478       return i_element;
00479     }
00480 
00481     //*********************************************************************
00482     /// Erases a range of elements.
00483     /// The range includes all the elements between first and last, including the
00484     /// element pointed by first, but not the one pointed by last.
00485     ///\param first Iterator to the first element.
00486     ///\param last  Iterator to the last element.
00487     ///\return An iterator pointing to the element that followed the erased element.
00488     //*********************************************************************
00489     iterator erase(iterator first, iterator last)
00490     {
00491       std::copy(last, end(), first);
00492       size_t n_delete = std::distance(first, last);
00493 
00494       // Just adjust the count.
00495       p_end -= n_delete;
00496 
00497       return first;
00498     }
00499 
00500     //*************************************************************************
00501     /// Assignment operator.
00502     //*************************************************************************
00503     pvoidvector& operator = (const pvoidvector& rhs)
00504     {
00505       if (&rhs != this)
00506       {
00507         assign(rhs.cbegin(), rhs.cend());
00508       }
00509 
00510       return *this;
00511     }
00512 
00513     //*************************************************************************
00514     /// Gets the current size of the vector.
00515     ///\return The current size of the vector.
00516     //*************************************************************************
00517     size_type size() const
00518     {
00519       return size_t(p_end - p_buffer);
00520     }
00521 
00522     //*************************************************************************
00523     /// Checks the 'empty' state of the vector.
00524     ///\return <b>true</b> if empty.
00525     //*************************************************************************
00526     bool empty() const
00527     {
00528       return (p_end == p_buffer);
00529     }
00530 
00531     //*************************************************************************
00532     /// Checks the 'full' state of the vector.
00533     ///\return <b>true</b> if full.
00534     //*************************************************************************
00535     bool full() const
00536     {
00537       return size() == CAPACITY;
00538     }
00539 
00540     //*************************************************************************
00541     /// Returns the remaining capacity.
00542     ///\return The remaining capacity.
00543     //*************************************************************************
00544     size_t available() const
00545     {
00546       return max_size() - size();
00547     }
00548 
00549   protected:
00550 
00551     //*********************************************************************
00552     /// Constructor.
00553     //*********************************************************************
00554     pvoidvector(void** p_buffer_, size_t MAX_SIZE)
00555       : vector_base(MAX_SIZE),
00556         p_buffer(p_buffer_),
00557         p_end(p_buffer_)
00558     {
00559     }
00560 
00561     //*********************************************************************
00562     /// Initialise the vector.
00563     //*********************************************************************
00564     void initialise()
00565     {
00566       p_end = p_buffer;
00567     }
00568 
00569     //*************************************************************************
00570     /// Fix the internal pointers after a low level memory copy.
00571     //*************************************************************************
00572     void repair(void** p_buffer_)
00573     {
00574       uintptr_t length = p_end - p_buffer;
00575 
00576       p_buffer = p_buffer_;
00577       p_end    = p_buffer_ + length;
00578     }
00579 
00580     void** p_buffer;
00581     void** p_end;
00582 
00583   private:
00584 
00585     // Disable copy construction.
00586     pvoidvector(const pvoidvector&);
00587   };
00588 
00589   bool operator ==(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs);
00590   bool operator !=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs);
00591   bool operator  <(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs);
00592   bool operator  >(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs);
00593   bool operator <=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs);
00594   bool operator >=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs);
00595 }
00596 
00597 #ifdef ETL_COMPILER_MICROSOFT
00598 #define min(a,b) (((a) < (b)) ? (a) : (b))
00599 #endif
00600 
00601 #undef __ETL_IN_PVOIDVECTOR__
00602 
00603 #endif
00604