Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
array.h
00001 ///\file 00002 00003 /****************************************************************************** 00004 The MIT License(MIT) 00005 00006 Embedded Template Library. 00007 https://github.com/ETLCPP/etl 00008 http://www.etlcpp.com 00009 00010 Copyright(c) 2014 jwellbelove 00011 00012 Permission is hereby granted, free of charge, to any person obtaining a copy 00013 of this software and associated documentation files(the "Software"), to deal 00014 in the Software without restriction, including without limitation the rights 00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00016 copies of the Software, and to permit persons to whom the Software is 00017 furnished to do so, subject to the following conditions : 00018 00019 The above copyright notice and this permission notice shall be included in all 00020 copies or substantial portions of the Software. 00021 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00028 SOFTWARE. 00029 ******************************************************************************/ 00030 00031 #ifndef __ETL_ARRAY__ 00032 #define __ETL_ARRAY__ 00033 00034 #include <iterator> 00035 #include <functional> 00036 #include <algorithm> 00037 #include <stddef.h> 00038 00039 #include "platform.h " 00040 #include "exception.h " 00041 #include "type_traits.h " 00042 #include "parameter_type.h " 00043 #include "static_assert.h" 00044 #include "error_handler.h " 00045 #include "algorithm.h " 00046 00047 ///\defgroup array array 00048 /// A replacement for std::array if you haven't got C++0x11. 00049 ///\ingroup containers 00050 00051 namespace etl 00052 { 00053 //*************************************************************************** 00054 ///\ingroup array 00055 /// The base class for array exceptions. 00056 //*************************************************************************** 00057 class array_exception : public exception 00058 { 00059 public: 00060 00061 array_exception(string_type reason_, string_type file_name_, numeric_type line_number_) 00062 : exception(reason_, file_name_, line_number_) 00063 { 00064 } 00065 }; 00066 00067 //*************************************************************************** 00068 ///\ingroup array 00069 /// The out of range exceptions. 00070 //*************************************************************************** 00071 class array_out_of_range : public array_exception 00072 { 00073 public: 00074 00075 array_out_of_range(string_type file_name_, numeric_type line_number_) 00076 : array_exception("array:range", file_name_, line_number_) 00077 { 00078 } 00079 }; 00080 00081 //*************************************************************************** 00082 ///\ingroup array 00083 /// A replacement for std::array if you haven't got C++0x11. 00084 //*************************************************************************** 00085 template <typename T, const size_t SIZE_> 00086 class array 00087 { 00088 private: 00089 00090 typedef typename etl::parameter_type<T>::type parameter_t; 00091 00092 public: 00093 00094 enum 00095 { 00096 SIZE = SIZE_ 00097 }; 00098 00099 typedef T value_type; 00100 typedef std::size_t size_type; 00101 typedef std::ptrdiff_t difference_type; 00102 typedef T& reference; 00103 typedef const T& const_reference; 00104 typedef T* pointer; 00105 typedef const T* const_pointer; 00106 typedef T* iterator; 00107 typedef const T* const_iterator; 00108 typedef std::reverse_iterator<iterator> reverse_iterator; 00109 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00110 00111 //************************************************************************* 00112 // Element access 00113 //************************************************************************* 00114 00115 //************************************************************************* 00116 /// Returns a reference to the value at index 'i'. 00117 ///\param i The index of the element to access. 00118 //************************************************************************* 00119 reference at(size_t i) 00120 { 00121 ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); 00122 00123 return _buffer[i]; 00124 } 00125 00126 //************************************************************************* 00127 /// Returns a const reference to the value at index 'i'. 00128 ///\param i The index of the element to access. 00129 //************************************************************************* 00130 const_reference at(size_t i) const 00131 { 00132 ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); 00133 00134 return _buffer[i]; 00135 } 00136 00137 //************************************************************************* 00138 /// [] operator. 00139 /// Returns a reference to the value at index 'i'. 00140 ///\param i The index of the element to access. 00141 //************************************************************************* 00142 reference operator[](size_t i) 00143 { 00144 return _buffer[i]; 00145 } 00146 00147 //************************************************************************* 00148 /// [] operator. 00149 /// Returns a const reference to the value at index 'i'. 00150 ///\param i The index of the element to access. 00151 //************************************************************************* 00152 const_reference operator[](size_t i) const 00153 { 00154 return _buffer[i]; 00155 } 00156 00157 //************************************************************************* 00158 /// Returns a reference to the first element. 00159 //************************************************************************* 00160 reference front() 00161 { 00162 return _buffer[0]; 00163 } 00164 00165 //************************************************************************* 00166 /// Returns a const reference to the first element. 00167 //************************************************************************* 00168 const_reference front() const 00169 { 00170 return _buffer[0]; 00171 } 00172 00173 //************************************************************************* 00174 /// Returns a reference to the last element. 00175 //************************************************************************* 00176 reference back() 00177 { 00178 return _buffer[SIZE - 1]; 00179 } 00180 00181 //************************************************************************* 00182 /// Returns a const reference to the last element. 00183 //************************************************************************* 00184 const_reference back() const 00185 { 00186 return _buffer[SIZE - 1]; 00187 } 00188 00189 //************************************************************************* 00190 /// Returns a pointer to the first element of the internal buffer. 00191 //************************************************************************* 00192 pointer data() 00193 { 00194 return &_buffer[0]; 00195 } 00196 00197 //************************************************************************* 00198 /// Returns a const pointer to the first element of the internal buffer. 00199 //************************************************************************* 00200 const_pointer data() const 00201 { 00202 return &_buffer[0]; 00203 } 00204 00205 //************************************************************************* 00206 // Iterators 00207 //************************************************************************* 00208 00209 //************************************************************************* 00210 /// Returns an iterator to the beginning of the array. 00211 //************************************************************************* 00212 iterator begin() 00213 { 00214 return &_buffer[0]; 00215 } 00216 00217 //************************************************************************* 00218 /// Returns a const iterator to the beginning of the array. 00219 //************************************************************************* 00220 const_iterator begin() const 00221 { 00222 return &_buffer[0]; 00223 } 00224 00225 //************************************************************************* 00226 /// Returns a const iterator to the beginning of the array. 00227 //************************************************************************* 00228 const_iterator cbegin() const 00229 { 00230 return begin(); 00231 } 00232 00233 //************************************************************************* 00234 /// Returns an iterator to the end of the array. 00235 //************************************************************************* 00236 iterator end() 00237 { 00238 return &_buffer[SIZE]; 00239 } 00240 00241 //************************************************************************* 00242 /// Returns a const iterator to the end of the array. 00243 //************************************************************************* 00244 const_iterator end() const 00245 { 00246 return &_buffer[SIZE]; 00247 } 00248 00249 //************************************************************************* 00250 // Returns a const iterator to the end of the array. 00251 //************************************************************************* 00252 const_iterator cend() const 00253 { 00254 return &_buffer[SIZE]; 00255 } 00256 00257 //************************************************************************* 00258 // Returns an reverse iterator to the reverse beginning of the array. 00259 //************************************************************************* 00260 reverse_iterator rbegin() 00261 { 00262 return reverse_iterator(end()); 00263 } 00264 00265 //************************************************************************* 00266 /// Returns a const reverse iterator to the reverse beginning of the array. 00267 //************************************************************************* 00268 const_reverse_iterator rbegin() const 00269 { 00270 return const_reverse_iterator(end()); 00271 } 00272 00273 //************************************************************************* 00274 /// Returns a const reverse iterator to the reverse beginning of the array. 00275 //************************************************************************* 00276 const_reverse_iterator crbegin() const 00277 { 00278 return const_reverse_iterator(end()); 00279 } 00280 00281 //************************************************************************* 00282 /// Returns a reverse iterator to the end of the array. 00283 //************************************************************************* 00284 reverse_iterator rend() 00285 { 00286 return reverse_iterator(begin()); 00287 } 00288 00289 //************************************************************************* 00290 /// Returns a const reverse iterator to the end of the array. 00291 //************************************************************************* 00292 const_reverse_iterator rend() const 00293 { 00294 return const_reverse_iterator(begin()); 00295 } 00296 00297 //************************************************************************* 00298 /// Returns a const reverse iterator to the end of the array. 00299 //************************************************************************* 00300 const_reverse_iterator crend() const 00301 { 00302 return const_reverse_iterator(begin()); 00303 } 00304 00305 //************************************************************************* 00306 // Capacity 00307 //************************************************************************* 00308 00309 //************************************************************************* 00310 /// Returns <b>true</b> if the array size is zero. 00311 //************************************************************************* 00312 bool empty() const 00313 { 00314 return (SIZE == 0); 00315 } 00316 00317 //************************************************************************* 00318 /// Returns the size of the array. 00319 //************************************************************************* 00320 size_t size() const 00321 { 00322 return SIZE; 00323 } 00324 00325 //************************************************************************* 00326 /// Returns the maximum possible size of the array. 00327 //************************************************************************* 00328 size_t max_size() const 00329 { 00330 return SIZE; 00331 } 00332 00333 //************************************************************************* 00334 // Operations 00335 //************************************************************************* 00336 00337 //************************************************************************* 00338 /// Fills the array with the specified value. 00339 ///\param value The value to fill the array with. 00340 //************************************************************************* 00341 void fill(parameter_t value) 00342 { 00343 std::fill(begin(), end(), value); 00344 } 00345 00346 //************************************************************************* 00347 /// Swaps the contents of this array and another. 00348 ///\param other A reference to the other array. 00349 //************************************************************************* 00350 void swap(array& other) 00351 { 00352 for (size_t i = 0; i < SIZE; ++i) 00353 { 00354 std::swap(_buffer[i], other._buffer[i]); 00355 } 00356 } 00357 00358 //************************************************************************* 00359 /// Fills the array from the range. 00360 /// If the range is larger than the array then the extra data is ignored. 00361 /// If the range is smaller than the array then the unused array elements are left unmodified. 00362 ///\param first The iterator to the first item in the ramge. 00363 ///\param last The iterator to one past the final item in the range. 00364 //************************************************************************* 00365 template <typename TIterator> 00366 void assign(TIterator first, const TIterator last) 00367 { 00368 etl::copy(first, last, begin(), end()); 00369 } 00370 00371 //************************************************************************* 00372 /// Fills the array from the range. 00373 /// If the range is larger than the array then the extra data is ignored. 00374 /// If the range is smaller than the array then the unused array elements are initialised with the supplied value. 00375 ///\param first The iterator to the first item in the ramge. 00376 ///\param last The iterator to one past the final item in the range. 00377 //************************************************************************* 00378 template <typename TIterator> 00379 void assign(TIterator first, const TIterator last, parameter_t value) 00380 { 00381 // Copy from the range. 00382 iterator p = etl::copy(first, last, begin(), end()); 00383 00384 // Default initialise any that are left. 00385 std::fill(p, end(), value); 00386 } 00387 00388 //************************************************************************* 00389 /// Inserts a value into the array. 00390 ///\param position The index of the position to insert at. 00391 ///\param value The value to insert. 00392 //************************************************************************* 00393 inline iterator insert_at(size_t position, parameter_t value) 00394 { 00395 return insert(begin() + position, value); 00396 } 00397 00398 //************************************************************************* 00399 /// Inserts a value into the array. 00400 ///\param position The iterator to the position to insert at. 00401 ///\param value The value to insert. 00402 //************************************************************************* 00403 iterator insert(const_iterator position, parameter_t value) 00404 { 00405 iterator p = const_cast<iterator>(position); 00406 00407 std::copy_backward(p, end() - 1, end()); 00408 *p = value; 00409 00410 return p; 00411 } 00412 00413 //************************************************************************* 00414 /// Insert into the array from the range. 00415 ///\param position The position to insert at. 00416 ///\param first The iterator to the first item in the range. 00417 ///\param last The iterator to one past the final item in the range. 00418 //************************************************************************* 00419 template <typename TIterator> 00420 inline iterator insert_at(size_t position, TIterator first, const TIterator last) 00421 { 00422 return insert(begin() + position, first, last); 00423 } 00424 00425 //************************************************************************* 00426 /// Insert into the array from the range. 00427 ///\param position The position to insert at. 00428 ///\param first The iterator to the first item in the range. 00429 ///\param last The iterator to one past the final item in the range. 00430 //************************************************************************* 00431 template <typename TIterator> 00432 iterator insert(const_iterator position, TIterator first, const TIterator last) 00433 { 00434 iterator p = const_cast<iterator>(position); 00435 iterator result(p); 00436 00437 size_t source_size = std::distance(first, last); 00438 size_t destination_space = std::distance(position, cend()); 00439 00440 // Do we need to move anything? 00441 if (source_size < destination_space) 00442 { 00443 size_t length = SIZE - (std::distance(begin(), p) + source_size); 00444 std::copy_backward(p, p + length, end()); 00445 } 00446 00447 // Copy from the range. 00448 etl::copy(first, last, p, end()); 00449 00450 return result; 00451 } 00452 00453 //************************************************************************* 00454 /// Erases a value from the array. 00455 /// After erase, the last value in the array will be unmodified. 00456 ///\param position The index of the position to erase at. 00457 //************************************************************************* 00458 inline iterator erase_at(size_t position) 00459 { 00460 return erase(begin() + position); 00461 } 00462 00463 //************************************************************************* 00464 /// Erases a value from the array. 00465 /// After erase, the last value in the array will be unmodified. 00466 ///\param position The iterator to the position to erase at. 00467 //************************************************************************* 00468 iterator erase(const_iterator position) 00469 { 00470 iterator p = const_cast<iterator>(position); 00471 std::copy(p + 1, end(), p); 00472 00473 return p; 00474 } 00475 00476 //************************************************************************* 00477 /// Erases a range of values from the array. 00478 /// After erase, the last values in the array will be unmodified. 00479 ///\param first The first item to erase. 00480 ///\param last The one past the last item to erase. 00481 //************************************************************************* 00482 iterator erase_range(size_t first, size_t last) 00483 { 00484 return erase(begin() + first, begin() + last); 00485 } 00486 00487 //************************************************************************* 00488 /// Erases a range of values from the array. 00489 /// After erase, the last values in the array will be unmodified. 00490 ///\param first The first item to erase. 00491 ///\param last The one past the last item to erase. 00492 //************************************************************************* 00493 iterator erase(const_iterator first, const_iterator last) 00494 { 00495 iterator p = const_cast<iterator>(first); 00496 std::copy(last, cend(), p); 00497 return p; 00498 } 00499 00500 //************************************************************************* 00501 /// Erases a value from the array. 00502 ///\param position The index of the position to erase at. 00503 ///\param value The value to use to overwrite the last element in the array. 00504 //************************************************************************* 00505 inline iterator erase_at(size_t position, parameter_t value) 00506 { 00507 return erase(begin() + position, value); 00508 } 00509 00510 //************************************************************************* 00511 /// Erases a value from the array. 00512 ///\param position The iterator to the position to erase at. 00513 ///\param value The value to use to overwrite the last element in the array. 00514 //************************************************************************* 00515 iterator erase(const_iterator position, parameter_t value) 00516 { 00517 iterator p = const_cast<iterator>(position); 00518 00519 std::copy(p + 1, end(), p); 00520 back() = value; 00521 00522 return p; 00523 } 00524 00525 //************************************************************************* 00526 /// Erases a range of values from the array. 00527 ///\param first The first item to erase. 00528 ///\param last The one past the last item to erase. 00529 ///\param value The value to use to overwrite the last elements in the array. 00530 //************************************************************************* 00531 iterator erase_range(size_t first, size_t last, parameter_t value) 00532 { 00533 return erase(begin() + first, begin() + last, value); 00534 } 00535 00536 //************************************************************************* 00537 /// Erases a range of values from the array. 00538 ///\param position The iterator to the position to erase at. 00539 ///\param value The value to use to overwrite the last elements in the array. 00540 //************************************************************************* 00541 iterator erase(const_iterator first, const_iterator last, parameter_t value) 00542 { 00543 iterator p = const_cast<iterator>(first); 00544 00545 p = std::copy(last, cend(), p); 00546 std::fill(p, end(), value); 00547 00548 return const_cast<iterator>(first); 00549 } 00550 00551 /// The array data. 00552 T _buffer[SIZE]; 00553 }; 00554 00555 //************************************************************************* 00556 /// Overloaded swap for etl::array<T, SIZE> 00557 ///\param lhs The first array. 00558 ///\param rhs The second array. 00559 //************************************************************************* 00560 template <typename T, const size_t SIZE> 00561 void swap(etl::array<T, SIZE> &lhs, etl::array<T, SIZE> &rhs) 00562 { 00563 lhs.swap(rhs); 00564 } 00565 00566 //************************************************************************* 00567 /// Equal operator. 00568 ///\param lhs The first array. 00569 ///\param rhs The second array. 00570 ///\return <b>true</b> if the arrays are equal, otherwise <b>false</b> 00571 //************************************************************************* 00572 template <typename T, std::size_t SIZE> 00573 bool operator ==(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs) 00574 { 00575 return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin()); 00576 } 00577 00578 //************************************************************************* 00579 /// Not equal operator. 00580 ///\param lhs The first array. 00581 ///\param rhs The second array. 00582 ///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b> 00583 //************************************************************************* 00584 template <typename T, std::size_t SIZE> 00585 bool operator !=(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs) 00586 { 00587 return !(lhs == rhs); 00588 } 00589 00590 //************************************************************************* 00591 /// Less than operator. 00592 ///\param lhs The first array. 00593 ///\param rhs The second array. 00594 ///\return <b>true</b> if the first array is lexicographically less than the second, otherwise <b>false</b> 00595 //************************************************************************* 00596 template <typename T, std::size_t SIZE> 00597 bool operator <(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs) 00598 { 00599 return std::lexicographical_compare(lhs.cbegin(), 00600 lhs.cend(), 00601 rhs.cbegin(), 00602 rhs.cend()); 00603 } 00604 00605 //************************************************************************* 00606 /// Less than or equal operator. 00607 ///\param lhs The first array. 00608 ///\param rhs The second array. 00609 ///\return <b>true</b> if the first array is lexicographically less than or equal to the second, otherwise <b>false</b> 00610 //************************************************************************* 00611 template <typename T, std::size_t SIZE> 00612 bool operator <=(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs) 00613 { 00614 return !(lhs > rhs); 00615 } 00616 00617 //************************************************************************* 00618 /// Greater than operator. 00619 ///\param lhs The first array. 00620 ///\param rhs The second array. 00621 ///\return <b>true</b> if the first array is lexicographically greater than the second, otherwise <b>false</b> 00622 template <typename T, std::size_t SIZE> 00623 //************************************************************************* 00624 bool operator >(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs) 00625 { 00626 return (rhs < lhs); 00627 } 00628 00629 //************************************************************************* 00630 /// Greater than or equal operator. 00631 ///\param lhs The first array. 00632 ///\param rhs The second array. 00633 ///\return <b>true</b> if the first array is lexicographically greater than or equal to the second, otherwise <b>false</b> 00634 //************************************************************************* 00635 template <typename T, std::size_t SIZE> 00636 bool operator >=(const etl::array<T, SIZE>& lhs, const etl::array<T, SIZE>& rhs) 00637 { 00638 return !(lhs < rhs); 00639 } 00640 00641 //************************************************************************* 00642 /// Gets a reference to an element in the array. 00643 ///\tparam I The index. 00644 ///\tparam T The type. 00645 ///\tparam MAXN The array size. 00646 ///\param a The array. 00647 ///\return A reference to the element 00648 //************************************************************************* 00649 template <std::size_t I, typename T, std::size_t MAXN> 00650 inline T& get(array<T, MAXN>& a) 00651 { 00652 STATIC_ASSERT(I < MAXN, "Index out of bounds"); 00653 return a[I]; 00654 } 00655 00656 //************************************************************************* 00657 /// Gets a const reference to an element in the array. 00658 ///\tparam I The index. 00659 ///\tparam T The type. 00660 ///\tparam MAXN The array size. 00661 ///\param a The array. 00662 ///\return A const reference to the element 00663 //************************************************************************* 00664 template <std::size_t I, typename T, std::size_t MAXN> 00665 inline const T& get(const array<T, MAXN>& a) 00666 { 00667 STATIC_ASSERT(I < MAXN, "Index out of bounds"); 00668 return a[I]; 00669 } 00670 } 00671 00672 #endif 00673 00674
Generated on Tue Jul 12 2022 14:05:38 by
