Skip to content

Commit

Permalink
bsl::list return numof removed elems. (#4728)
Browse files Browse the repository at this point in the history
  • Loading branch information
cppguru authored and GitHub Enterprise committed May 10, 2024
1 parent 2c52f74 commit b56b954
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 48 deletions.
80 changes: 46 additions & 34 deletions groups/bsl/bslstl/bslstl_list.2.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2314,7 +2314,7 @@ void TestDriver2<TYPE,ALLOC>::test28_sortComp()
s_spec[j] = SPECS[i][LENGTH - j - 1];
}
s_spec[LENGTH] = '\0';
const char* const S_SPEC = s_spec; // (reverse) sorted spec.
const char * const S_SPEC = s_spec; // (reverse) sorted spec.

char spec[MAX_SPEC_LEN + 1];
std::strcpy(spec, S_SPEC);
Expand Down Expand Up @@ -2378,7 +2378,7 @@ void TestDriver2<TYPE,ALLOC>::test28_sortComp()
xi = X.begin();
for (int j = 0; j < LENGTH; ++j) {
// Find index of iterator in saved iterator array
const_iterator* p = std::find(save_iters,
const_iterator *p = std::find(save_iters,
save_iters + LENGTH,
xi);
ptrdiff_t save_idx = p - save_iters;
Expand Down Expand Up @@ -2493,7 +2493,7 @@ void TestDriver2<TYPE,ALLOC>::test28_sortComp()
// unspecified in the case of an exception, and is thus not tested.
for (xi = X.begin(); xi != X.end(); ++xi) {
// Find index of iterator in saved iterator array
const_iterator* p = std::find(save_iters,
const_iterator *p = std::find(save_iters,
save_iters + EH_SPEC_LEN,
xi);
ptrdiff_t save_idx = p - save_iters;
Expand Down Expand Up @@ -2618,8 +2618,8 @@ void TestDriver2<TYPE,ALLOC>::test28_sortNoComp()
if (verbose) printf("Testing sort()\n");

for (int i = 0; i < NUM_SPECS; ++i) {
const char* const S_SPEC = SPECS[i]; // Sorted spec.
const int LENGTH = static_cast<int>(std::strlen(S_SPEC));
const char * const S_SPEC = SPECS[i]; // Sorted spec.
const int LENGTH = static_cast<int>(std::strlen(S_SPEC));
ASSERT(MAX_SPEC_LEN >= LENGTH);

char spec[MAX_SPEC_LEN + 1];
Expand Down Expand Up @@ -2671,7 +2671,7 @@ void TestDriver2<TYPE,ALLOC>::test28_sortNoComp()
xi = X.begin();
for (int j = 0; j < LENGTH; ++j) {
// Find index of iterator in saved iterator array
const_iterator* p = std::find(save_iters,
const_iterator *p = std::find(save_iters,
save_iters + LENGTH,
xi);
long save_idx = p - save_iters;
Expand Down Expand Up @@ -2788,10 +2788,10 @@ void TestDriver2<TYPE,ALLOC>::test27_mergeComp()
}
for (SortedSpecGen xgen; xgen; ++xgen) {
for (SortedSpecGen ygen; ygen; ++ygen) {
const char* const X_SPEC = xgen.reverse_spec();
const int X_SPEC_LEN = xgen.len();
const char* const Y_SPEC = ygen.reverse_spec();
const int Y_SPEC_LEN = ygen.len();
const char * const X_SPEC = xgen.reverse_spec();
const int X_SPEC_LEN = xgen.len();
const char * const Y_SPEC = ygen.reverse_spec();
const int Y_SPEC_LEN = ygen.len();

Obj mX(xoa); const Obj& X = gg(&mX, X_SPEC);
Obj mY(xoa); const Obj& Y = gg(&mY, Y_SPEC);
Expand Down Expand Up @@ -3027,7 +3027,7 @@ void TestDriver2<TYPE,ALLOC>::test27_mergeComp()
char prev_val = 'Z';
for (const_iterator xi = X.begin(); xi != X.end(); ++xi) {
// Find index of iterator in saved iterator array
const_iterator* p = std::find(save_iters,
const_iterator *p = std::find(save_iters,
save_iters + MERGED_SPEC_LEN,
xi);
ptrdiff_t save_idx = p - save_iters;
Expand All @@ -3047,7 +3047,7 @@ void TestDriver2<TYPE,ALLOC>::test27_mergeComp()
prev_val = 'Z';
for (const_iterator yi = Y.begin(); yi != Y.end(); ++yi) {
// Find index of iterator in saved iterator array
const_iterator* p = std::find(save_iters,
const_iterator *p = std::find(save_iters,
save_iters + MERGED_SPEC_LEN,
yi);
ptrdiff_t save_idx = p - save_iters;
Expand Down Expand Up @@ -3144,8 +3144,8 @@ void TestDriver2<TYPE,ALLOC>::test27_mergeNoComp()
bool first5X = true;

for (SortedSpecGen xgen; xgen; ++xgen) {
const char* const X_SPEC = xgen.spec();
const int X_SPEC_LEN = xgen.len();
const char * const X_SPEC = xgen.spec();
const int X_SPEC_LEN = xgen.len();

if (5 == X_SPEC_LEN && first5X) {
first5X = false;
Expand All @@ -3157,8 +3157,8 @@ void TestDriver2<TYPE,ALLOC>::test27_mergeNoComp()
bool first5Y = true;

for (SortedSpecGen ygen; ygen; ++ygen) {
const char* const Y_SPEC = ygen.spec();
const int Y_SPEC_LEN = ygen.len();
const char * const Y_SPEC = ygen.spec();
const int Y_SPEC_LEN = ygen.len();

if (5 == Y_SPEC_LEN && first5Y) {
first5Y = false;
Expand Down Expand Up @@ -3541,6 +3541,8 @@ void TestDriver2<TYPE,ALLOC>::test25_remove()
//: remain valid after removal.
//:
//: 8 The non-'E' elements retain their relative order.
//:
//: 9 The methods return the number of removed elements.
//
// Plan:
//: 1 For concern 1, perform the same tests for both 'remove' and
Expand All @@ -3565,6 +3567,7 @@ void TestDriver2<TYPE,ALLOC>::test25_remove()
//: o The iterating over the remaining elements produces a sequence of
//: values and iterators matching those saved before the remove
//: operation.
//: o The return value was indeed the number of removed elements.
//
// Testing:
// void remove(const T& val);
Expand All @@ -3579,7 +3582,7 @@ void TestDriver2<TYPE,ALLOC>::test25_remove()

// Specifications from 0 to 10 elements long, none of which have the value
// 'E'.
const char* const SPECS[] = {
const char * const SPECS[] = {
"", "A", "AB", "ABA", "ABCD", "AAAA", "ABCDF", "ABCDFGHDAB"
};

Expand Down Expand Up @@ -3607,8 +3610,8 @@ void TestDriver2<TYPE,ALLOC>::test25_remove()
}

for (int i = 0; i < NUM_SPECS; ++i) {
const char* const SPEC = SPECS[i];
const int LEN = static_cast<int>(std::strlen(SPEC));
const char * const SPEC = SPECS[i];
const int LEN = static_cast<int>(std::strlen(SPEC));

ASSERT(MAX_SPEC_LEN >= LEN);

Expand Down Expand Up @@ -3657,9 +3660,14 @@ void TestDriver2<TYPE,ALLOC>::test25_remove()

if (veryVeryVerbose) { T_; printf("Before: "); P_(X); }

size_t removedCount = static_cast<size_t>(-1);
switch (op) {
case OP_REMOVE: mX.remove(E); break;
case OP_REMOVE_IF: mX.remove_if(VPred(E)); break;
case OP_REMOVE: {
removedCount = mX.remove(E);
} break;
case OP_REMOVE_IF: {
removedCount = mX.remove_if(VPred(E));
} break;
}

if (veryVeryVerbose) { printf("After: "); P(X); }
Expand All @@ -3673,6 +3681,11 @@ void TestDriver2<TYPE,ALLOC>::test25_remove()
const int ASSIGN_AFTER = numAssignmentCalls;
const int DTORS_AFTER = numDestructorCalls;

// Verify the return value (number of removed elements)
ASSERTV(SPEC, res_spec,
removedCount, LEN, X.size(),
LEN - X.size() == removedCount);

// Test result value
ASSERTV(SPEC, res_spec, X, checkIntegrity(X, res_len));
ASSERTV(SPEC, res_spec, X, (int) X.size() == res_len);
Expand All @@ -3699,7 +3712,6 @@ void TestDriver2<TYPE,ALLOC>::test25_remove()
ASSERTV(SPEC, res_spec,
DTORS_AFTER == DTORS_BEFORE + (LEN-res_len));
}

} // end for (mask)
} // end for (i)
} // end for (op)
Expand Down Expand Up @@ -3747,7 +3759,7 @@ void TestDriver2<TYPE,ALLOC>::test24_splice()
bslma::TestAllocator oa("object", veryVeryVeryVerbose);
ALLOC xoa(&oa);

const char* const SPECS[] = {
const char * const SPECS[] = {
"", "A", "AB", "ABC", "ABCD", "ABCDE"
};

Expand Down Expand Up @@ -3793,10 +3805,10 @@ void TestDriver2<TYPE,ALLOC>::test24_splice()
}

for (int i = 0; i < NUM_SPECS * NUM_SPECS; ++i) {
const char* const X_SPEC = SPECS[i / NUM_SPECS ];
const int X_LEN = static_cast<int>(std::strlen(X_SPEC));
const char* const Y_SPEC = SPECS[i % NUM_SPECS ];
const int Y_LEN = static_cast<int>(std::strlen(Y_SPEC));
const char * const X_SPEC = SPECS[i / NUM_SPECS ];
const int X_LEN = static_cast<int>(std::strlen(X_SPEC));
const char * const Y_SPEC = SPECS[i % NUM_SPECS ];
const int Y_LEN = static_cast<int>(std::strlen(Y_SPEC));

if (veryVerbose) { P_(X_SPEC); P(Y_SPEC); }

Expand Down Expand Up @@ -3839,15 +3851,15 @@ void TestDriver2<TYPE,ALLOC>::test24_splice()

// iterators and pointers to elements -- BEFORE
iterator BX_iters[MAX_SPEC_LEN + 1];
const TYPE* BX_ptrs[MAX_SPEC_LEN];
const TYPE *BX_ptrs[MAX_SPEC_LEN];
iterator BY_iters[MAX_SPEC_LEN + 1];
const TYPE* BY_ptrs[MAX_SPEC_LEN];
const TYPE *BY_ptrs[MAX_SPEC_LEN];

// iterators and pointers to elements -- AFTER
iterator AX_iters[2*MAX_SPEC_LEN + 1];
const TYPE* AX_ptrs[2*MAX_SPEC_LEN];
const TYPE *AX_ptrs[2*MAX_SPEC_LEN];
iterator AY_iters[MAX_SPEC_LEN + 1];
const TYPE* AY_ptrs[MAX_SPEC_LEN];
const TYPE *AY_ptrs[MAX_SPEC_LEN];

// Save iterators and pointers into BEFORE arrays
iterator xi = mX.begin();
Expand Down Expand Up @@ -4028,8 +4040,8 @@ void TestDriver2<TYPE,ALLOC>::test23_reverse()

struct {
int d_line;
const char* d_specBefore_p;
const char* d_specAfter_p;
const char *d_specBefore_p;
const char *d_specAfter_p;
} const DATA[] = {
{ L_, "", "" },
{ L_, "A", "A" },
Expand Down Expand Up @@ -5052,7 +5064,7 @@ void TestDriver2<TYPE,ALLOC>::test18_erase()
// Iterate through the operations
for (int op = TEST_FIRST; op < TEST_LAST; ++op) {

const char* opname = "<unknown>";
const char *opname = "<unknown>";

switch (op) {
case TEST_ERASE1: opname = "erase(iterator)"; break;
Expand Down
23 changes: 16 additions & 7 deletions groups/bsl/bslstl/bslstl_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -1642,13 +1642,14 @@ class list {
// provided by 'comparator', and unless both 'other' and this list use
// the same allocator.

void remove(const value_type& value);
// Erase all the elements having the specified 'value' from this list.
size_type remove(const value_type& value);
// Erase all the elements having the specified 'value' from this list
// and return the number of erased elements.

template <class PREDICATE>
void remove_if(PREDICATE predicate);
// Remove and destroy all elements in this list for which the specified
// unary 'predicate' returns 'true'.
size_type remove_if(PREDICATE predicate);
// Erase all the elements in this list for which the specified unary
// 'predicate' returns 'true' and return the number of erased elements.

void reverse() BSLS_KEYWORD_NOEXCEPT;
// Reverse the order of the elements in this list.
Expand Down Expand Up @@ -3093,8 +3094,10 @@ void list<VALUE, ALLOCATOR>::merge(
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::remove(const VALUE& value)
typename list<VALUE, ALLOCATOR>::size_type
list<VALUE, ALLOCATOR>::remove(const VALUE& value)
{
const size_type origSize = this->size();
const const_iterator e = cend();
for (const_iterator i = cbegin(); e != i; ) {
// Standard says to use 'operator==', not 'std::equal_to'.
Expand All @@ -3106,12 +3109,16 @@ void list<VALUE, ALLOCATOR>::remove(const VALUE& value)
++i;
}
}

return origSize - this->size();
}

template <class VALUE, class ALLOCATOR>
template <class PREDICATE>
void list<VALUE, ALLOCATOR>::remove_if(PREDICATE predicate)
typename list<VALUE, ALLOCATOR>::size_type
list<VALUE, ALLOCATOR>::remove_if(PREDICATE predicate)
{
const size_type origSize = this->size();
const iterator e = end();
for (iterator i = begin(); e != i; ) {
if (predicate(*i)) {
Expand All @@ -3121,6 +3128,8 @@ void list<VALUE, ALLOCATOR>::remove_if(PREDICATE predicate)
++i;
}
}

return origSize - this->size();
}

template <class VALUE, class ALLOCATOR>
Expand Down
23 changes: 16 additions & 7 deletions groups/bsl/bslstl/bslstl_list_cpp03.h
Original file line number Diff line number Diff line change
Expand Up @@ -1512,13 +1512,14 @@ class list {
// provided by 'comparator', and unless both 'other' and this list use
// the same allocator.

void remove(const value_type& value);
// Erase all the elements having the specified 'value' from this list.
size_type remove(const value_type& value);
// Erase all the elements having the specified 'value' from this list
// and return the number of erased elements.

template <class PREDICATE>
void remove_if(PREDICATE predicate);
// Remove and destroy all elements in this list for which the specified
// unary 'predicate' returns 'true'.
size_type remove_if(PREDICATE predicate);
// Erase all the elements in this list for which the specified unary
// 'predicate' returns 'true' and return the number of erased elements.

void reverse() BSLS_KEYWORD_NOEXCEPT;
// Reverse the order of the elements in this list.
Expand Down Expand Up @@ -3875,8 +3876,10 @@ void list<VALUE, ALLOCATOR>::merge(
}

template <class VALUE, class ALLOCATOR>
void list<VALUE, ALLOCATOR>::remove(const VALUE& value)
typename list<VALUE, ALLOCATOR>::size_type
list<VALUE, ALLOCATOR>::remove(const VALUE& value)
{
const size_type origSize = this->size();
const const_iterator e = cend();
for (const_iterator i = cbegin(); e != i; ) {
// Standard says to use 'operator==', not 'std::equal_to'.
Expand All @@ -3888,12 +3891,16 @@ void list<VALUE, ALLOCATOR>::remove(const VALUE& value)
++i;
}
}

return origSize - this->size();
}

template <class VALUE, class ALLOCATOR>
template <class PREDICATE>
void list<VALUE, ALLOCATOR>::remove_if(PREDICATE predicate)
typename list<VALUE, ALLOCATOR>::size_type
list<VALUE, ALLOCATOR>::remove_if(PREDICATE predicate)
{
const size_type origSize = this->size();
const iterator e = end();
for (iterator i = begin(); e != i; ) {
if (predicate(*i)) {
Expand All @@ -3903,6 +3910,8 @@ void list<VALUE, ALLOCATOR>::remove_if(PREDICATE predicate)
++i;
}
}

return origSize - this->size();
}

template <class VALUE, class ALLOCATOR>
Expand Down

0 comments on commit b56b954

Please sign in to comment.