Skip to content

Commit

Permalink
Update API for std::begin and std::end
Browse files Browse the repository at this point in the history
Extended std::begin() and std::end() to support
containers that support c.begin() and c.end(),
beyond just C-style array support for use in
existing STL libraries such as std::copy().
Included unit tests testing std::vector and
std::map containers.

Change-Id: I4569eb86955b6bb72009cc92558168689fda0336
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/94122
Reviewed-by: Zachary Clark <zach@ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Luis P Fernandez <luis.fernandez@ibm.com>
Reviewed-by: Nicholas E Bofferding <bofferdn@us.ibm.com>
  • Loading branch information
aamarin authored and Nicholas E Bofferding committed Apr 15, 2020
1 parent 085223b commit f30db09
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 4 deletions.
74 changes: 71 additions & 3 deletions src/include/iterator
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* Contributors Listed Below - COPYRIGHT 2012,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -182,7 +182,8 @@ back_insert_iterator<BackInsertionSequence>

/**
* 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};
Expand All @@ -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<int> 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<int> 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};
Expand All @@ -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<int> 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<int> 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

Expand Down
64 changes: 63 additions & 1 deletion src/usr/testcore/lib/stltest.H
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* Contributors Listed Below - COPYRIGHT 2011,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -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<int> 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<int> 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<int, int> 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<int, int> 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

0 comments on commit f30db09

Please sign in to comment.