/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/include/array $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ #ifndef stl_array #define stl_array /** * @file array * @brief simple stl array template class declaration. */ #include #if !defined( __STDC_LIMIT_MACROS) #define __STDC_LIMIT_MACROS #endif #include #include namespace std { template struct array { // types: typedef T& reference; typedef const T& const_reference; typedef T * iterator; typedef const T * const_iterator; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T value_type; typedef T* pointer; typedef const T* const_pointer; /* Not supporting for now typedef reverse_iterator reverse_iterator; typedef reverse_iterator const_reverse_iterator; */ T elems[N ? N : 1]; // exposition only // no explicit construct/copy/destroy for aggregate type /** * Assigns the given value to all elements in the container. * @param[in] the value to assign to the elements * @pre None. * @post None. */ void fill(const T& value) { fill_n(begin(), N, value); } /** * Exchanges the contents of the container with those of other. * @param[in] container to exchange the contents with * @pre Does not cause iterators and references to associate with the * other container. * @post None. */ void swap(array& other) { std::swap(elems, other.elems); } // iterators: /** * Returns an iterator to the first element of the container. * @return iterator to the first element * @pre If the container is empty, the returned iterator will be equal * to end(). * @post None. */ iterator begin() { return iterator(&elems[0]); } /** * Returns a const_iterator to the first element of the container. * @return const_iterator to the first element * @pre If the container is empty, the returned iterator will be equal * to end(). * @post None. */ constexpr const_iterator begin() const { return const_iterator(&elems[0]); } /** * Returns a const_iterator to the first element of the container. * @return const_iterator to the first element * @pre If the container is empty, the returned iterator will be equal * to end(). * @post None. */ constexpr const_iterator cbegin() const { return const_iterator(&elems[0]); } /** * Returns an iterator to the element following the last element of the * container. * @return iterator to the element following the last element. * @pre This element acts as a placeholder; attempting to access it * results in undefined behavior. * @post None. */ iterator end() { return iterator(&elems[N]); } /** * Returns an const_iterator to the element following the last element * of the container. * @return const_iterator to the element following the last element. * @pre This element acts as a placeholder; attempting to access it * results in undefined behavior. * @post None. */ constexpr const_iterator end() const { return const_iterator(&elems[N]); } /** * Returns an const_iterator to the element following the last element * of the container. * @return const_iterator to the element following the last element. * @pre This element acts as a placeholder; attempting to access it * results in undefined behavior. * @post None. */ constexpr const_iterator cend() const { return const_iterator(&elems[N]); } /* Not supporting for now reverse_iterator rbegin(); const_reverse_iterator rbegin() const; reverse_iterator rend(); const_reverse_iterator rend() const; const_reverse_iterator crbegin() const; const_reverse_iterator crend() const; */ // capacity: /** * Returns the number of elements in the container * @return The number of elements in the container. * @pre None. * @post None. */ constexpr size_type size() const { return N; } /** * Returns the maximum number of elements the container is able to hold * due to system or library implementation limitations, * @return Maximum number of elements. * @pre Because each std::array is a fixed-size container, the * value returned by max_size equals N (which is also the value * returned by size) * @post None. */ constexpr size_type max_size() { return size(); } /** * Checks if the container has no elements * @return true if the container is empty, false otherwise * @pre None. * @post None. */ constexpr bool empty() { return (N == 0); } // element access: /** * Returns a reference to the element at specified location pos. * No bounds checking is performed. * @param[in] position of the element to return * @return Reference to the requested element. * @pre Unlike std::map::operator[], this operator never inserts a new * element into the container. * @post None. */ reference operator[](size_type n) { return elems[n]; } /** * Returns a const_reference to the element at specified location pos. * No bounds checking is performed. * @param[in] position of the element to return * @return const_reference to the requested element. * @pre None. * @post None. */ const_reference operator[](size_type n) const { return elems[n]; } /** * Returns a reference to the element at specified location pos, with * bounds checking. Will assert if pos is not within the range of the * container * @param[in] position of the element to return * @return reference to the requested element. * @pre None. * @post None. */ reference at(size_type n) { assert(n < size()); return elems[n]; } /** * Returns a const_reference to the element at specified location pos, * with bounds checking. Will assert if pos is not within the range of * the container * @param[in] position of the element to return * @return const_reference to the requested element. * @pre None. * @post None. */ const_reference at(size_type n) const { assert(n < size()); return elems[n]; } /** * Returns a reference to the first element in the container. Calling * front on an empty container is undefined. * @return reference to the first element * @pre For a container c, the expression c.front() is equivalent to * *c.begin(). * @post None. */ reference front() { return *begin(); } /** * Returns a const_reference to the first element in the container. * Calling front on an empty container is undefined. * @return const_reference to the first element * @pre For a container c, the expression c.front() is equivalent to * *c.begin(). * @post None. */ constexpr const_reference front() const { return *begin(); } /** * Returns reference to the last element in the container. * Calling back on an empty container is undefined. * @return Reference to the last element. * @pre For a container c, the expression return c.back(); is equivalent * to { auto tmp = c.end(); --tmp; return *tmp; } * @post None. */ reference back() { return N ? *(end() - 1) : *end(); } /** * Returns const_reference to the last element in the container. * Calling back on an empty container is undefined. * @return const_reference to the last element. * @pre For a container c, the expression return c.back(); is equivalent * to { auto tmp = c.end(); --tmp; return *tmp; } * @post None. */ constexpr const_reference back() const { return N ? *(end() - 1) : *end(); } /** * Returns pointer to the underlying array serving as element storage. * Calling back on an empty container is undefined. * @return Pointer to the underlying element storage. * For non-empty containers, returns &front() * @pre The pointer is such that range [data(); data() + size()) is * always a valid range, even if the container is empty (data() is * not dereferenceable in that case). * @post None. */ T * data() { return &front(); } /** * Returns const pointer to the underlying array serving as element * storage. Calling back on an empty container is undefined. * @return const_pointer to the underlying element storage. * For non-empty containers, returns &front() * @pre The pointer is such that range [data(); data() + size()) is * always a valid range, even if the container is empty (data() is * not dereferenceable in that case). * @post None. */ constexpr const T * data() const { return &front(); } }; /** * Compare the contents of two containers - overload operator== * @return true if the contents of the containers are equal, false otherwise * @pre None. * @post None. */ template inline bool operator==(const array& lhs, const array& rhs) { static_assert(N==M, "std::arrays must be of the same size when using " "overloaded compare operators"); return std::equal(lhs.begin(), lhs.end(), rhs.begin()); } /** * Compare the contents of two containers - overload operator!= * @return true if the contents of the containers are not equal, false * otherwise * @pre None. * @post None. */ template inline bool operator!=(const array& lhs, const array& rhs) { static_assert(N==M, "std::arrays must be of the same size when using " "overloaded compare operators"); return !(lhs == rhs); } /** * Compare the contents of two containers - overload operator< * @return true if the contents of the lhs are lexicographically less than * the contents of rhs, false otherwise * @pre None. * @post None. */ template inline bool operator<(const array& lhs, const array& rhs) { static_assert(N==M, "std::arrays must be of the same size when using overloaded compare operators"); return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } /** * Compare the contents of two containers - overload operator<= * @return true if the contents of the lhs are lexicographically less than * or equal the contents of rhs, false otherwise * @pre None. * @post None. */ template inline bool operator<=(const array& lhs, const array& rhs) { static_assert(N==M, "std::arrays must be of the same size when using overloaded compare operators"); return (lhs < rhs) || (lhs == rhs); } /** * Compare the contents of two containers - overload operator> * @return true if the contents of the lhs are lexicographically greater * than the contents of rhs, false otherwise * @pre None. * @post None. */ template inline bool operator>(const array& lhs, const array& rhs) { static_assert(N==M, "std::arrays must be of the same size when using overloaded compare operators"); return !(lhs < rhs) && !(lhs == rhs); } /** * Compare the contents of two containers - overload operator>= * @return true if the contents of the lhs are lexicographically greater * than or equal the contents of rhs, false otherwise * @pre None. * @post None. */ template inline bool operator>=(const array& lhs, const array& rhs) { static_assert(N==M, "std::arrays must be of the same size when using overloaded compare operators"); return !(lhs < rhs); } /** * Specializes the std::swap algorithm for std::array. Swaps the contents of * lhs and rhs. Calls lhs.swap(rhs) * @param[in] container whose contents to swap * @param[in] container whose contents to swap * @pre None. * @post None. */ template inline void swap(array& lhs, array& rhs) { lhs.swap(rhs); } /** * Extracts the Ith element element from the array. * @param[in] array whose contents to extract * @return A reference to the Ith element of a. * @pre I must be an integer value in range [0, N). This is enforced at * compile time as opposed to at() or operator[]. * @post None. */ template inline constexpr T& get(array& a) { static_assert( ( I>=0 && I inline constexpr const T& get(const array& a) { static_assert( ( I>=0 && I inline constexpr T&& get(array&& a) { static_assert( ( I>=0 && I class tuple_size; template class tuple_element; template struct tuple_size >; template struct tuple_element >; */ } #endif