Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers array_wrapper.h Source File

array_wrapper.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 https://www.etlcpp.com
00009 
00010 Copyright(c) 2017 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_ARRAY_WRAPPER__
00032 #define __ETL_ARRAY_WRAPPER__
00033 
00034 #include "platform.h "
00035 #include "iterator.h "
00036 #include "error_handler.h "
00037 #include "exception.h "
00038 #include "hash.h "
00039 #include "container.h "
00040 #include "parameter_type.h "
00041 
00042 #include <algorithm>
00043 
00044 ///\defgroup array array
00045 /// A wrapper for arrays
00046 ///\ingroup containers
00047 
00048 #undef ETL_FILE
00049 #define ETL_FILE "42"
00050 
00051 namespace etl
00052 {
00053   //***************************************************************************
00054   /// The base class for array_wrapper exceptions.
00055   //***************************************************************************
00056   class array_wrapper_exception : public exception
00057   {
00058   public:
00059 
00060     array_wrapper_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
00061       : exception(reason_, file_name_, line_number_)
00062     {
00063     }
00064   };
00065 
00066   //***************************************************************************
00067   ///\ingroup stack
00068   /// The exception thrown when the index is out of bounds.
00069   //***************************************************************************
00070   class array_wrapper_bounds : public array_wrapper_exception
00071   {
00072   public:
00073 
00074     array_wrapper_bounds(string_type file_name_, numeric_type line_number_)
00075       : array_wrapper_exception(ETL_ERROR_TEXT("array_wrapper:bounds", ETL_FILE"A"), file_name_, line_number_)
00076     {
00077     }
00078   };
00079 
00080   //***************************************************************************
00081   /// Array wrapper.
00082   //***************************************************************************
00083   template <typename T, std::size_t SIZE_, T(&ARRAY_)[SIZE_]>
00084   class array_wrapper
00085   {
00086   public:
00087 
00088     typedef T                                     value_type;
00089     typedef std::size_t                           size_type;
00090     typedef T&                                    reference;
00091     typedef const T&                              const_reference;
00092     typedef T*                                    pointer;
00093     typedef const T*                              const_pointer;
00094     typedef T*                                    iterator;
00095     typedef const T*                              const_iterator;
00096     typedef std::reverse_iterator<iterator>       reverse_iterator;
00097     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00098 
00099     typedef typename etl::parameter_type<T>::type parameter_t;
00100 
00101     // Indexes for positions in the array.
00102     enum
00103     {
00104       SIZE     = SIZE_,
00105       MAX_SIZE = SIZE_,
00106       FRONT    = 0,
00107       BACK     = SIZE - 1,
00108       BEGIN    = 0,
00109       END      = SIZE,
00110       RBEGIN   = SIZE - 1,
00111       REND     = -1
00112     };
00113 
00114     //*************************************************************************
00115     /// Returns a reference to the first element.
00116     //*************************************************************************
00117     reference front()
00118     {
00119       return *&ARRAY_[FRONT];
00120     }
00121 
00122     //*************************************************************************
00123     /// Returns a const reference to the first element.
00124     //*************************************************************************
00125     ETL_CONSTEXPR const_reference front() const
00126     {
00127       return *&ARRAY_[FRONT];
00128     }
00129 
00130     //*************************************************************************
00131     /// Returns a reference to the last element.
00132     //*************************************************************************
00133     reference back()
00134     {
00135       return *&ARRAY_[BACK];
00136     }
00137 
00138     //*************************************************************************
00139     /// Returns a const reference to the last element.
00140     //*************************************************************************
00141     ETL_CONSTEXPR const_reference back() const
00142     {
00143       return *&ARRAY_[BACK];
00144     }
00145 
00146     //*************************************************************************
00147     /// Returns a pointer to the first element of the internal storage.
00148     //*************************************************************************
00149     pointer data()
00150     {
00151       return &ARRAY_[BEGIN];
00152     }
00153 
00154     //*************************************************************************
00155     /// Returns a const pointer to the first element of the internal storage.
00156     //*************************************************************************
00157     ETL_CONSTEXPR const_pointer data() const
00158     {
00159       return &ARRAY_[BEGIN];
00160     }
00161 
00162     //*************************************************************************
00163     /// Returns an iterator to the beginning of the array.
00164     //*************************************************************************
00165     iterator begin()
00166     {
00167       return &ARRAY_[BEGIN];
00168     }
00169 
00170     //*************************************************************************
00171     /// Returns a const iterator to the beginning of the array.
00172     //*************************************************************************
00173     ETL_CONSTEXPR const_iterator begin() const
00174     {
00175       return &ARRAY_[BEGIN];
00176     }
00177 
00178     //*************************************************************************
00179     /// Returns a const iterator to the beginning of the array.
00180     //*************************************************************************
00181     ETL_CONSTEXPR const_iterator cbegin() const
00182     {
00183       return &ARRAY_[BEGIN];
00184     }
00185 
00186     //*************************************************************************
00187     /// Returns an iterator to the end of the array.
00188     //*************************************************************************
00189     iterator end()
00190     {
00191       return &ARRAY_[END];
00192     }
00193 
00194     //*************************************************************************
00195     /// Returns a const iterator to the end of the array.
00196     //*************************************************************************
00197     ETL_CONSTEXPR const_iterator end() const
00198     {
00199       return &ARRAY_[END];
00200     }
00201 
00202     //*************************************************************************
00203     // Returns a const iterator to the end of the array.
00204     //*************************************************************************
00205     ETL_CONSTEXPR const_iterator cend() const
00206     {
00207       return &ARRAY_[END];
00208     }
00209 
00210     //*************************************************************************
00211     // Returns an reverse iterator to the reverse beginning of the array.
00212     //*************************************************************************
00213     reverse_iterator rbegin()
00214     {
00215       return reverse_iterator(&ARRAY_[END]);
00216     }
00217 
00218     //*************************************************************************
00219     /// Returns a const reverse iterator to the reverse beginning of the array.
00220     //*************************************************************************
00221     ETL_CONSTEXPR const_reverse_iterator rbegin() const
00222     {
00223       return const_reverse_iterator(&ARRAY_[END]);
00224     }
00225 
00226     //*************************************************************************
00227     /// Returns a const reverse iterator to the reverse beginning of the array.
00228     //*************************************************************************
00229     ETL_CONSTEXPR const_reverse_iterator crbegin() const
00230     {
00231       return const_reverse_iterator(&ARRAY_[END]);
00232     }
00233 
00234     //*************************************************************************
00235     /// Returns a reverse iterator to the end of the array.
00236     //*************************************************************************
00237     reverse_iterator rend()
00238     {
00239       return reverse_iterator(&ARRAY_[BEGIN]);
00240     }
00241 
00242     //*************************************************************************
00243     /// Returns a const reverse iterator to the end of the array.
00244     //*************************************************************************
00245     ETL_CONSTEXPR const_reverse_iterator rend() const
00246     {
00247       return const_reverse_iterator(&ARRAY_[BEGIN]);
00248     }
00249 
00250     //*************************************************************************
00251     /// Returns a const reverse iterator to the end of the array.
00252     //*************************************************************************
00253     ETL_CONSTEXPR const_reverse_iterator crend() const
00254     {
00255       return const_reverse_iterator(&ARRAY_[BEGIN]);
00256     }
00257 
00258     //*************************************************************************
00259     /// Returns the size of the array.
00260     //*************************************************************************
00261     ETL_CONSTEXPR size_t size() const
00262     {
00263       return SIZE;
00264     }
00265 
00266     //*************************************************************************
00267     /// Returns the maximum possible size of the array.
00268     //*************************************************************************
00269     ETL_CONSTEXPR size_t max_size() const
00270     {
00271       return MAX_SIZE;
00272     }
00273 
00274     //*************************************************************************
00275     /// Returns a reference to the indexed value.
00276     //*************************************************************************
00277     reference operator[](size_t i)
00278     {
00279       return ARRAY_[i];
00280     }
00281 
00282     //*************************************************************************
00283     /// Returns a const reference to the indexed value.
00284     //*************************************************************************
00285     ETL_CONSTEXPR const_reference operator[](size_t i) const
00286     {
00287       return ARRAY_[i];
00288     }
00289 
00290     //*************************************************************************
00291     /// Returns a reference to the indexed value.
00292     //*************************************************************************
00293     reference at(size_t i)
00294     {
00295       ETL_ASSERT(i < SIZE, ETL_ERROR(etl::array_wrapper_bounds));
00296       return ARRAY_[i];
00297     }
00298 
00299     //*************************************************************************
00300     /// Returns a const reference to the indexed value.
00301     //*************************************************************************
00302     const_reference at(size_t i) const
00303     {
00304       ETL_ASSERT(i < SIZE, ETL_ERROR(etl::array_wrapper_bounds));
00305       return ARRAY_[i];
00306     }
00307 
00308     //*************************************************************************
00309     /// Fills the array.
00310     //*************************************************************************
00311     void fill(parameter_t value)
00312     {
00313       std::fill(begin(), end(), value);
00314     }
00315 
00316     //*************************************************************************
00317     /// Swaps the contents of arrays.
00318     //*************************************************************************
00319     template <typename U, U(&ARRAYOTHER)[SIZE_]>
00320     typename etl::enable_if<etl::is_same<T, U>::value, void>::type
00321      swap(etl::array_wrapper<U, SIZE_, ARRAYOTHER>& other)
00322     {
00323       for (size_t i = 0; i < SIZE; ++i)
00324       {
00325         std::swap(ARRAY_[i], other.begin()[i]);
00326       }
00327     }
00328   };
00329 
00330   //*************************************************************************
00331   /// Equality for array wrappers.
00332   //*************************************************************************
00333   template <typename TL, typename TR, std::size_t SIZEL, std::size_t SIZER, TL(&ARRAYL)[SIZEL], TR(&ARRAYR)[SIZER]>
00334   bool operator == (const etl::array_wrapper<TL, SIZEL, ARRAYL>& lhs,
00335                     const etl::array_wrapper<TR, SIZER, ARRAYR>& rhs)
00336   {
00337     return (SIZEL == SIZER) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
00338   }
00339 
00340   //*************************************************************************
00341   /// Inequality for array wrapper.
00342   //*************************************************************************
00343   template <typename TL, typename TR, std::size_t SIZEL, std::size_t SIZER, TL(&ARRAYL)[SIZEL], TR(&ARRAYR)[SIZER]>
00344   bool operator != (const etl::array_wrapper<TL, SIZEL, ARRAYL>& lhs,
00345                     const etl::array_wrapper<TR, SIZER, ARRAYR>& rhs)
00346   {
00347     return !(lhs == rhs);
00348   }
00349 
00350   //*************************************************************************
00351   /// Less-than for array wrapper.
00352   //*************************************************************************
00353   template <typename TL, typename TR, std::size_t SIZEL, std::size_t SIZER, TL(&ARRAYL)[SIZEL], TR(&ARRAYR)[SIZER]>
00354   bool operator < (const etl::array_wrapper<TL, SIZEL, ARRAYL>& lhs,
00355                    const etl::array_wrapper<TR, SIZER, ARRAYR>& rhs)
00356   {
00357     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
00358   }
00359 
00360   //*************************************************************************
00361   /// Greater-than for array wrapper.
00362   //*************************************************************************
00363   template <typename TL, typename TR, std::size_t SIZEL, std::size_t SIZER, TL(&ARRAYL)[SIZEL], TR(&ARRAYR)[SIZER]>
00364   bool operator > (const etl::array_wrapper<TL, SIZEL, ARRAYL>& lhs,
00365                    const etl::array_wrapper<TR, SIZER, ARRAYR>& rhs)
00366   {
00367     return rhs < lhs;
00368   }
00369 
00370   //*************************************************************************
00371   /// Less-than-equal for array wrapper.
00372   //*************************************************************************
00373   template <typename TL, typename TR, std::size_t SIZEL, std::size_t SIZER, TL(&ARRAYL)[SIZEL], TR(&ARRAYR)[SIZER]>
00374   bool operator <= (const etl::array_wrapper<TL, SIZEL, ARRAYL>& lhs,
00375                     const etl::array_wrapper<TR, SIZER, ARRAYR>& rhs)
00376   {
00377     return !(lhs > rhs);
00378   }
00379 
00380   //*************************************************************************
00381   /// Greater-than-equal for array wrapper.
00382   //*************************************************************************
00383   template <typename TL, typename TR, std::size_t SIZEL, std::size_t SIZER, TL(&ARRAYL)[SIZEL], TR(&ARRAYR)[SIZER]>
00384   bool operator >= (const etl::array_wrapper<TL, SIZEL, ARRAYL>& lhs,
00385                     const etl::array_wrapper<TR, SIZER, ARRAYR>& rhs)
00386   {
00387     return !(lhs < rhs);
00388   }
00389 
00390   //*************************************************************************
00391   /// Hash function.
00392   //*************************************************************************
00393 #if ETL_8BIT_SUPPORT
00394   template <typename T, std::size_t SIZE, T(&ARRAY)[SIZE]>
00395   struct hash<etl::array_wrapper<T, SIZE, ARRAY> >
00396   {
00397     size_t operator()(const etl::array_wrapper<T, SIZE, ARRAY>& aw) const
00398     {
00399       return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&aw[0]),
00400                                                          reinterpret_cast<const uint8_t*>(&aw[aw.size()]));
00401     }
00402   };
00403 #endif
00404 }
00405 
00406 //*************************************************************************
00407 /// Swap.
00408 //*************************************************************************
00409 template <typename T, std::size_t SIZE, T(&ARRAYL)[SIZE], T(&ARRAYR)[SIZE]>
00410 void swap(etl::array_wrapper<T, SIZE, ARRAYL>& lhs,
00411           etl::array_wrapper<T, SIZE, ARRAYR>& rhs)
00412 {
00413   lhs.swap(rhs);
00414 }
00415 
00416 #define ETL_ARRAY_WRAPPER(arraytype, arrayobject)  etl::array_wrapper<arraytype, ETL_ARRAY_SIZE(arrayobject), arrayobject>
00417 
00418 #undef ETL_FILE
00419 
00420 #endif
00421 
00422