diff --git a/src/include/iterator b/src/include/iterator index dbd712b9e23..e86231eb297 100644 --- a/src/include/iterator +++ b/src/include/iterator @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2019 */ +/* Contributors Listed Below - COPYRIGHT 2012,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -182,7 +182,8 @@ back_insert_iterator /** * begin(array) - * Returns pointer to beginning of array + * @param[in] c_array - an array of arbitrary type + * @return Returns pointer to beginning of array * * Example: * int c_array[] = {0, 1, 2}; @@ -194,9 +195,42 @@ T* begin(T (&c_array)[size]) return &c_array[0]; } +/** + * begin(container) + * @param[in] c - a container with a begin method + * @return Returns an iterator to the beginning of the sequence represented by c + * + * Example: + * std::vector v = { 3, 1, 4 }; + * auto vi = std::begin(v); + * std::cout << *vi << '\n'; + */ +template< typename C > +auto begin(const C& c) -> decltype(c.begin()) +{ + return c.begin(); +} + +/** + * begin(container) + * @param[in] c - a container with a begin method + * @return Returns an iterator to the beginning of the sequence represented by c + * + * Example: + * std::vector v = { 3, 1, 4 }; + * auto vi = std::begin(v); + * std::cout << *vi << '\n'; + */ +template< typename C > +auto begin(C& c) -> decltype(c.begin()) +{ + return c.begin(); +} + /** * end(array) - * Returns pointer to end of array (i.e. the element after the last element) + * @param[in] c_array - an array of arbitrary type + * @return Returns pointer to end of array (i.e. the element after the last element) * * Example: * int c_array[] = {0, 1, 2}; @@ -208,6 +242,40 @@ T* end(T (&c_array)[size]) return &c_array[0] + size; } +/** + * end(container) + * @param[in] c - a container with an end method + * @return Returns an iterator to the ending of the sequence represented by c + * + * Example: + * std::vector v = { 3, 1, 4 }; + * if (std::find(std::begin(v), std::end(v), 5) != std::end(v)) { + * std::cout << "found a 5 in vector v!\n"; + * } + */ +template< typename C > +auto end(const C& c) -> decltype(c.end()) +{ + return c.end(); +} + +/** + * end(container) + * @param[in] c - a container with an end method + * @return Returns an iterator to the ending of the sequence represented by c + * + * Example: + * std::vector v = { 3, 1, 4 }; + * if (std::find(std::begin(v), std::end(v), 5) != std::end(v)) { + * std::cout << "found a 5 in vector v!\n"; + * } + */ +template< typename C > +auto end(C& c) -> decltype(c.end()) +{ + return c.end(); +} + }; // namespace std. #endif diff --git a/src/usr/testcore/lib/stltest.H b/src/usr/testcore/lib/stltest.H index 34cb64d4abd..4c55ca89a3a 100644 --- a/src/usr/testcore/lib/stltest.H +++ b/src/usr/testcore/lib/stltest.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2019 */ +/* Contributors Listed Below - COPYRIGHT 2011,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -812,5 +812,67 @@ class STLTest : public CxxTest::TestSuite } } } + + /// Test std::begin() and std::end() on a vector + void testVectorTypeBeginEnd() + { + constexpr size_t MAX_ENTRIES = 1025; + std::vector baseA(MAX_ENTRIES, 0); // base-type array + + // Initialize base array to known values + for (size_t i = 0; i < baseA.size(); i++) + { + baseA[i] = i; + } + + // use std::begin() and std::end() to copy base-type array to vector + std::vector baseV ( std::begin(baseA), std::end(baseA)); + + if (baseV.size() != MAX_ENTRIES) + { + TS_FAIL("testVectorTypeBeginEnd: expected %d elements, found %d in vector", + MAX_ENTRIES, baseV.size()); + } + + for (size_t i = 0; i < MAX_ENTRIES; i++) + { + if (baseA[i] != baseV[i]) + { + TS_FAIL("testVectorTypeBeginEnd: No match at index %d (base %d vs vector %d)", + i, baseA[i], baseV[i]); + } + } + } + + /// Test std::begin() and std::end() on a map + void testMapTypeBeginEnd() + { + constexpr size_t MAX_ENTRIES = 1025; + std::map baseA; // base-type map + + // Initialize base array to known values + for (size_t i = 0; i < MAX_ENTRIES; i++) + { + baseA[i] = i; + } + + // use std::begin() and std::end() to copy base map to map + std::map baseV ( std::begin(baseA), std::end(baseA)); + + if (baseV.size() != MAX_ENTRIES) + { + TS_FAIL("testMapTypeBeginEnd: expected %d elements, found %d in vector", + MAX_ENTRIES, baseV.size()); + } + + for (size_t i = 0; i < MAX_ENTRIES; i++) + { + if (baseA[i] != baseV[i]) + { + TS_FAIL("testMapTypeBeginEnd: No match at index %d (base %d vs vector %d)", + i, baseA[i], baseV[i]); + } + } + } }; #endif