diff options
author | Stephen Cprek <smcprek@us.ibm.com> | 2016-09-30 16:55:15 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-10-30 22:44:23 -0400 |
commit | a6f34cd9b2c79e803e564b917951b63f9252d02a (patch) | |
tree | a3afd7a876addc0b5a27b97fb37dc06c46103bfc /src | |
parent | 99552570de2dfc1f11f22746c5cdb86820f154b8 (diff) | |
download | talos-hostboot-a6f34cd9b2c79e803e564b917951b63f9252d02a.tar.gz talos-hostboot-a6f34cd9b2c79e803e564b917951b63f9252d02a.zip |
Implement std::array
Change-Id: I86149816b46f213502801fb710dc2f68d4a4b0f7
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/30647
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Andres A. Lugo-Reyes <aalugore@us.ibm.com>
Reviewed-by: A. P. Williams III <iawillia@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/include/algorithm | 140 | ||||
-rw-r--r-- | src/include/array | 507 | ||||
-rw-r--r-- | src/makefile | 2 | ||||
-rw-r--r-- | src/usr/testcore/lib/makefile | 4 | ||||
-rw-r--r-- | src/usr/testcore/lib/stltest.H | 183 |
5 files changed, 834 insertions, 2 deletions
diff --git a/src/include/algorithm b/src/include/algorithm index 9641a797a..cc3886ff5 100644 --- a/src/include/algorithm +++ b/src/include/algorithm @@ -78,6 +78,38 @@ namespace std } /** + * Swaps the values of the elements the given iterators are pointing to. + * @param[in] a iterator to the elements to swap + * @param[in] b iterator to the elements to swap + */ + template<class ForwardIterator1, class ForwardIterator2> + inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) + { + swap(*a, *b); + } + + /** + * Swaps the values of the elements the given iterators are pointing to. + * @param[in] first1 iterator of the beginning of first range + * @param[in] last1 iterator of the end of first range + * @param[in] first2 iterator of the beginning of the second range + * @return Iterator to the element past the last element exchanged in the + * range beginning with first2. + */ + + template< class ForwardIterator1, class ForwardIterator2 > + inline ForwardIterator2 swap_ranges(ForwardIterator1 first1, + ForwardIterator1 last1, + ForwardIterator2 first2) + { + while (first1 != last1) + { + iter_swap(first1++, first2++); + } + return first2; + } + + /** * Exchange values of two objects * @param[in] a reference to an object to be swaped with b * @param[in] b reference to an object to be swaped with a @@ -87,12 +119,24 @@ namespace std inline void swap(T& a, T&b ) { + // @TODO RTC:162287 use std::move() T c(a); a=b; b=c; } /** + * Swaps the arrays a and b. In effect calls std::swap_ranges(a, a+N, b) + * @param[in] a reference to an object to be swaped with b + * @param[in] b reference to an object to be swaped with a + */ + template< class T, size_t N> + inline void swap(T(&a)[N], T(&b)[N]) + { + swap_ranges(a, a+N, b); + } + + /** * Fill a range with value * @param[in] first ForwardIterator to the first position in the source range. * @param[in] last ForwardIterator to the last position +1 in the source range. @@ -874,7 +918,103 @@ namespace std return result; } + /** Returns true if the range [first1, last1) is equal to the range + * [first2, first2 + (last1 - first1)), and false otherwise + * + * The two ranges are considered equal if, for every iterator i in the range + * [first1,last1), *i equals *(first2 + (i - first1)). The overloads use + * operator== to determine if two elements are equal. + * + * @param[in] first1 - The beginning of the first range. + * @param[in] last1 - The end of the first range. + * @param[in] first2 - The beginning of the second range. + * @return - Returns true equal, false otherwise + */ + template < typename InputIterator1, typename InputIterator2 > + bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2) + { + while(first1 != last1) + { + if (!(*first1 == *first2)) + { + return false; + } + ++first1; ++first2; + } + return true; + } + /** Returns true if the range [first1, last1) is equal, using a predicate, + * to the range [first2, first2 + (last1 - first1)), and false otherwise + * + * The two ranges are considered equal if, for every iterator i in the range + * [first1,last1), *i equals *(first2 + (i - first1)). The overloads use + * operator== to determine if two elements are equal. + * + * @param[in] first1 - The beginning of the first range. + * @param[in] last1 - The end of the first range. + * @param[in] first2 - The beginning of the second range. + * @param[in] comp - Binary predicate which returns true if the elements + * should be treated as equal. + * @return - Returns true equal, false otherwise + */ + template < typename InputIterator1, typename InputIterator2, + typename BinaryPredicate > + bool equal( InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate comp ) + { + while(first1 != last1) + { + if (!comp(*first1, *first2)) + { + return false; + } + ++first1; ++first2; + } + return true; + } + + /** Checks if the first range [first1, last1) is lexicographically less than + * the second range [first2, last2). + * + * Elements are compared using operator<. + * Lexicographical comparison is a operation with the following properties: + * - Two ranges are compared element by element. + * - The first mismatching element defines which range is lexicographically + * less or greater than the other. + * - If one range is a prefix of another, the shorter range is + * lexicographically less than the other. + * - If two ranges have equivalent elements and are of the same length, + * then the ranges are lexicographically equal. + * - An empty range is lexicographically less than any non-empty range. + * - Two empty ranges are lexicographically equal. + * + * @param[in] first1 - The beginning of the first range. + * @param[in] last1 - The end of the first range. + * @param[in] first2 - The beginning of the second range. + * @param[in] last2 - The end of the second range. + * @return - true if the first range is lexicographically less than the + * second. + */ + template < typename InputIterator1, typename InputIterator2 > + bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2) + { + while( (first1 != last1) && (first2 != last2) ) + { + if (*first1 < *first2) + { + return true; + } + if (*first2 < *first1) + { + return false; + } + first1++; first2++; + } + return (first1 == last1) && (first2 != last2); + } }; #endif diff --git a/src/include/array b/src/include/array new file mode 100644 index 000000000..59c313046 --- /dev/null +++ b/src/include/array @@ -0,0 +1,507 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/array $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 <stddef.h> + +#if !defined( __STDC_LIMIT_MACROS) +#define __STDC_LIMIT_MACROS +#endif +#include <stdint.h> + +namespace std +{ + template <class T, size_t N > + 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<iterator> reverse_iterator; + typedef reverse_iterator<const_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<T, N>& 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() + { + 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<T, N> 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 <class T, size_t N, size_t M=N> + inline bool operator==(const array<T,N>& lhs, const array<T,M>& 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 <class T, size_t N, size_t M=N> + inline bool operator!=(const array<T,N>& lhs, const array<T,M>& 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 <class T, size_t N, size_t M=N> + inline bool operator<(const array<T,N>& lhs, const array<T,M>& 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 <class T, size_t N, size_t M=N> + inline bool operator<=(const array<T,N>& lhs, const array<T,M>& 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 <class T, size_t N, size_t M=N> + inline bool operator>(const array<T,N>& lhs, const array<T,M>& 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 <class T, size_t N, size_t M=N> + inline bool operator>=(const array<T,N>& lhs, const array<T,M>& 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 <class T, size_t N> + inline void swap(array<T,N>& lhs, array<T,N>& 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 <size_t I, class T, size_t N> + inline constexpr T& get(array<T, N>& a) + { + static_assert( ( I>=0 && I<N ), "std::get trying to access element out of range"); + return a[I]; + } + + /** + * Extracts the Ith element element from the array. + * @param[in] array whose contents to extract + * @return A const 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 <size_t I, class T, size_t N> + inline constexpr const T& get(const array<T, N>& a) + { + static_assert( ( I>=0 && I<N ), "std::get trying to access element out of range"); + return a[I]; + } + + /** + * Extracts the Ith element element from the array. + * @param[in] array whose contents to extract + * @return An rvalue 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 <size_t I, class T, size_t N> + inline constexpr T&& get(array<T, N>&& a) + { + static_assert( ( I>=0 && I<N ), "std::get trying to access element out of range"); + return a[I]; + } + +/* Not supporting for now + template <class T> class tuple_size; + template <size_t I, class T> class tuple_element; + template <class T, size_t N> struct tuple_size<array<T, N> >; + template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N> >; +*/ + +} + +#endif
\ No newline at end of file diff --git a/src/makefile b/src/makefile index b63cd42c2..f7d5e68e1 100644 --- a/src/makefile +++ b/src/makefile @@ -220,7 +220,7 @@ TESTCASE_MODULES += testpirformat TESTCASE_MODULES += testerrl TESTCASE_MODULES += testhwas TESTCASE_MODULES += testvpd -#TESTCASE_MODULES += testsyslib @TODO-RTC:151185-Turn this back on +TESTCASE_MODULES += testsyslib TESTCASE_MODULES += testscom #Requires main store memory @TODO RTC: 132577 diff --git a/src/usr/testcore/lib/makefile b/src/usr/testcore/lib/makefile index 877793617..98666371f 100644 --- a/src/usr/testcore/lib/makefile +++ b/src/usr/testcore/lib/makefile @@ -25,7 +25,9 @@ ROOTPATH = ../../../.. MODULE = testsyslib -TESTS = *.H +// @TODO-RTC:151185-Turn enable all test cases +// TESTS = *.H +TESTS = stltest.H SUBDIRS += runtime.d diff --git a/src/usr/testcore/lib/stltest.H b/src/usr/testcore/lib/stltest.H index d5133c3e2..227a3f5c7 100644 --- a/src/usr/testcore/lib/stltest.H +++ b/src/usr/testcore/lib/stltest.H @@ -29,6 +29,7 @@ #include <vector> #include <list> #include <map> +#include <array> #include <algorithm> #include <iterator> #include <functional> @@ -480,6 +481,14 @@ class STLTest : public CxxTest::TestSuite // Code wont compile if this doesn't work std::vector< std::vector<int> > v = { {},{1},{1,2,3} }; std::list< std::list<int> > l = { {},{1},{1,2,3} }; + std::array<int, 5> a1 { {1,2,3,4,5} }; + std::array<int, 5> a2 = {1,2,3,4,5}; + // Compiler warns that std::arrays are unused, so compare their + // sizes + if (a1.size() != a2.size()) + { + TS_FAIL("testInitListCompile(): std::array sizes do not match"); + } } void testEmplace() @@ -557,5 +566,179 @@ class STLTest : public CxxTest::TestSuite } } + void testCstyleArraySwap() + { + size_t m[5] = {1,2,3,4,5}; + size_t n[5] = {6,7,8,9,10}; + std::swap(m,n); + for (size_t i = 0; i < 5; ++i) + { + if( m[i] != i+6 || n[i] != i+1) + { + TS_FAIL("testCstyleArraySwap: swap failed"); + } + } + } + + /** + * Modifies each index of std::array to be (i_curVal + i_inc*i) + * @param[in] container to update + * @param[in] value to start setting container to [default 1] + * @param[in] increment amount [default 1] + */ + template <class T, size_t N> + void sequentialArrayReset(std::array<T, N> &i_arr, + int i_curVal = 1, int i_inc = 1) + { + for (size_t i = 0; i < i_arr.size(); ++i) + { + i_arr.at(i) = i_curVal; + i_curVal += i_inc; + } + } + + void testArray () + { + const size_t N = 5; + + // Arrays to manipulate, swap, and test with + std::array<int, N> a { {1,2,3,4,5} }; + std::array<int, N> b { {1,2,3,4,5} }; + std::array<int, 0> c; + // Const arrays to check if a and b were manipulated correctly + const std::array<int, 5> d = { {1,2,3,4,5} }; + const std::array<int, 5> e = { {6,7,8,9,10} }; + + // Test empty operator + if (a.empty()) + { + TS_FAIL("testArray(): std::array did not initialize properly size = 0"); + } + // Test size operator + if (a.size() != N) + { + TS_FAIL("testArray(): std::array.size() failed"); + } + // Test max size operator + if (a.max_size() != N) + { + TS_FAIL("testArray(): std::array.max_size() failed"); + } + // Test [] operator + if (a[0] != 1 + || a[1] != 2 + || a[2] != 3 + || a[3] != 4 + || a[4] != 5) + { + TS_FAIL("testArray(): std::array [] operator failed"); + } + // Test at() operator + if (a.at(0) != 1 + || a.at(1) != 2 + || a.at(2) != 3 + || a.at(3) != 4 + || a.at(4) != 5) + { + TS_FAIL("testArray(): std::array.at() failed"); + } + // Test front() + if (a.front() != 1 || a.front() != a.at(0)) + { + TS_FAIL("testArray(): std::array.front() failed"); + } + // Test back() + if (a.back() != 5 || a.back() != a.at(4)) + { + TS_FAIL("testArray(): std::array.back() failed"); + } + // Test data() + if (a.data() != &a.elems[0]) + { + TS_FAIL("testArray(): std::array.data() failed"); + } + + // Test helper functions - Change b to have values 6-10 + sequentialArrayReset(b, 6); + if ( b != e ) + { + TS_FAIL("testArray(): test helper sequentialArrayReset() failed"); + } + + // Test Swap + std::swap(a,b); + if ( a!=e || b!=d ) + { + TS_FAIL("testArray(): swap(std::array,std::array) failed"); + } + + // Test begin/end iterators and fill() + if ( (a.end() - a.begin()) != a.size()) + { + TS_FAIL("testArray(): std::array.begin()/end() not correct"); + } + a.fill(9); + for (auto it = a.begin(); it < a.end(); ++it) + { + if(*it != 9) + { + TS_FAIL("testArray(): std::array.fill() failed"); + } + } + + // Test overload operators + if (a <= b ) + { + TS_FAIL("testArray(): std::array overload <= failed"); + } + if (b > a ) + { + TS_FAIL("testArray(): std::array overload > failed"); + } + b.fill(9); + if ( a != b ) + { + TS_FAIL("testArray(): std::array overload != failed"); + } + + // Test 0 size array + if (c.begin() != c.end()) + { + TS_FAIL("testArray(): 0 sized std::array bad begin()/end() ptrs"); + } + if (!c.empty()) + { + TS_FAIL("testArray(): 0 sized std::array not empty"); + } + + // Test get functions + // Force a to not match then ensure std::get works to modify correctly + sequentialArrayReset(a, 6); + if (a != e) + { + TS_FAIL("testArray(): test std::get() helper sequentialArrayReset(a,6) failed"); + } + std::get<0>(a) = 1; + std::get<1>(a) = 2; + std::get<2>(a) = 3; + std::get<3>(a) = 4; + std::get<4>(a) = 5; + // Force b to match then ensure std::get works to modify correctly + sequentialArrayReset(b); + if (b != d) + { + TS_FAIL("testArray(): test std::get() helper sequentialArrayReset(b) failed"); + } + std::get<0>(b) = 6; + std::get<1>(b) = 7; + std::get<2>(b) = 8; + std::get<3>(b) = 9; + std::get<4>(b) = 10; + if ( a != d || b != e ) + { + TS_FAIL("testArray(): arrays not equal after using std::get to set arrays to be equal"); + } + } + }; #endif |