Adding missing C++20 std::erase implementations (#5735)
There were already implementations for std::erase_if. This adds the counterpart AZStd::erase versions resolves #5734 Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
14ad3b025a
commit
97106f9e60
@@ -1233,6 +1233,14 @@ namespace AZStd
|
||||
right.swap(AZStd::forward<this_type>(left));
|
||||
}
|
||||
|
||||
template<class T, class Allocator, AZStd::size_t NumElementsPerBlock, AZStd::size_t MinMapSize, class U>
|
||||
decltype(auto) erase(deque<T, Allocator, NumElementsPerBlock, MinMapSize>& container, const U& value)
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), value);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
template<class T, class Allocator, AZStd::size_t NumElementsPerBlock, AZStd::size_t MinMapSize, class Predicate>
|
||||
decltype(auto) erase_if(deque<T, Allocator, NumElementsPerBlock, MinMapSize>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -974,4 +974,22 @@ namespace AZStd
|
||||
{
|
||||
return !operator<(a, b);
|
||||
}
|
||||
|
||||
// C++20 erase free functions
|
||||
template<class T, size_t Capacity, class U>
|
||||
constexpr decltype(auto) erase(fixed_vector<T, Capacity>& container, const U& value)
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), value);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
template<class T, size_t Capacity, class Predicate>
|
||||
constexpr decltype(auto) erase_if(fixed_vector<T, Capacity>& container, Predicate predicate)
|
||||
{
|
||||
auto iter = AZStd::remove_if(container.begin(), container.end(), predicate);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,6 +1275,11 @@ namespace AZStd
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
template<class T, class Allocator, class U>
|
||||
decltype(auto) erase(forward_list<T, Allocator>& container, const U& value)
|
||||
{
|
||||
return container.remove(value);
|
||||
}
|
||||
template<class T, class Allocator, class Predicate>
|
||||
decltype(auto) erase_if(forward_list<T, Allocator>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -1340,6 +1340,11 @@ namespace AZStd
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
template<class T, class Allocator, class U>
|
||||
decltype(auto) erase(list<T, Allocator>& container, const U& value)
|
||||
{
|
||||
return container.remove(value);
|
||||
}
|
||||
template<class T, class Allocator, class Predicate>
|
||||
decltype(auto) erase_if(list<T, Allocator>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -1387,6 +1387,14 @@ namespace AZStd
|
||||
}
|
||||
//#pragma endregion
|
||||
|
||||
template<class T, class Allocator, class U>
|
||||
decltype(auto) erase(vector<T, Allocator>& container, const U& value)
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), value);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
template<class T, class Allocator, class Predicate>
|
||||
decltype(auto) erase_if(vector<T, Allocator>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -465,6 +465,15 @@ namespace AZStd
|
||||
template<class Element, size_t MaxElementCount, class Traits>
|
||||
constexpr bool operator>=(const Element* lhs, const basic_fixed_string<Element, MaxElementCount, Traits>& rhs);
|
||||
|
||||
// C++20 erase helpers
|
||||
template<class Element, size_t MaxElementCount, class Traits, class U>
|
||||
constexpr auto erase(basic_fixed_string<Element, MaxElementCount, Traits>& container, const U& element)
|
||||
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type;
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits, class Predicate>
|
||||
constexpr auto erase_if(basic_fixed_string<Element, MaxElementCount, Traits>& container, Predicate predicate)
|
||||
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type;
|
||||
|
||||
template<class T>
|
||||
struct hash;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <AzCore/std/typetraits/is_integral.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
|
||||
#include <AzCore/std/string/fixed_string_Platform.inl>
|
||||
|
||||
@@ -1680,6 +1680,26 @@ namespace AZStd
|
||||
return !operator<(lhs, rhs);
|
||||
}
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits, class U>
|
||||
inline constexpr auto erase(basic_fixed_string<Element, MaxElementCount, Traits>& container, const U& element)
|
||||
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), element);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits, class Predicate>
|
||||
inline constexpr auto erase_if(basic_fixed_string<Element, MaxElementCount, Traits>& container, Predicate predicate)
|
||||
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type
|
||||
{
|
||||
auto iter = AZStd::remove_if(container.begin(), container.end(), predicate);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits>
|
||||
struct hash<basic_fixed_string<Element, MaxElementCount, Traits>>
|
||||
{
|
||||
|
||||
@@ -1955,6 +1955,16 @@ namespace AZStd
|
||||
{
|
||||
return basic_string<Element, Traits, Allocator>(lhs).compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
template<class Element, class Traits, class Allocator, class U>
|
||||
decltype(auto) erase(basic_string<Element, Traits, Allocator>& container, const U& element)
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), element);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
|
||||
template<class Element, class Traits, class Allocator, class Predicate>
|
||||
decltype(auto) erase_if(basic_string<Element, Traits, Allocator>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -2376,17 +2376,52 @@ namespace UnitTest
|
||||
static_assert(AZStd::wildcard_match_case(filter1, blahValue));
|
||||
}
|
||||
|
||||
TEST_F(String, StringEraseIf_Succeeds)
|
||||
TEST_F(String, StringCXX20Erase_Succeeds)
|
||||
{
|
||||
|
||||
AZStd::string eraseIfTest = "ABC CBA";
|
||||
auto eraseCount = AZStd::erase_if(eraseIfTest, [](AZStd::string::value_type ch)
|
||||
{
|
||||
return ch == 'C';
|
||||
});
|
||||
auto erasePredicate = [](AZStd::string::value_type ch)
|
||||
{
|
||||
return ch == 'C';
|
||||
};
|
||||
auto eraseCount = AZStd::erase_if(eraseIfTest, erasePredicate);
|
||||
EXPECT_EQ(2, eraseCount);
|
||||
EXPECT_EQ(5, eraseIfTest.size());
|
||||
EXPECT_STREQ("AB BA", eraseIfTest.c_str());
|
||||
|
||||
// Now erase the letter 'A';
|
||||
eraseCount = AZStd::erase(eraseIfTest, 'A');
|
||||
EXPECT_EQ(2, eraseCount);
|
||||
EXPECT_EQ(3, eraseIfTest.size());
|
||||
EXPECT_EQ("B B", eraseIfTest);
|
||||
}
|
||||
|
||||
TEST_F(String, FixedStringCXX20Erase_Succeeds)
|
||||
{
|
||||
// Erase 'l' from the phrase "Hello" World"
|
||||
constexpr auto eraseTest = [](const char* testString) constexpr
|
||||
{
|
||||
AZStd::fixed_string<16> testResult{ testString };
|
||||
AZStd::erase(testResult, 'l');
|
||||
return testResult;
|
||||
}("HelloWorld");
|
||||
|
||||
static_assert(eraseTest == "HeoWord");
|
||||
EXPECT_EQ("HeoWord", eraseTest);
|
||||
|
||||
// Use erase_if to erase both 'H' and 'e' from the remaining eraseTest string
|
||||
constexpr auto eraseIfTest = [](AZStd::string_view testString) constexpr
|
||||
{
|
||||
AZStd::fixed_string<16> testResult{ testString };
|
||||
auto erasePredicate = [](char ch)
|
||||
{
|
||||
return ch == 'H' || ch == 'e';
|
||||
};
|
||||
AZStd::erase_if(testResult, erasePredicate);
|
||||
return testResult;
|
||||
}(eraseTest);
|
||||
|
||||
static_assert(eraseIfTest == "oWord");
|
||||
EXPECT_EQ("oWord", eraseIfTest);
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
|
||||
@@ -796,6 +796,37 @@ namespace UnitTest
|
||||
EXPECT_GT(greaterVectorDifferentSize, lessVector);
|
||||
}
|
||||
|
||||
TEST_F(Arrays, FixedVectorCXX20Erase_Succeeds)
|
||||
{
|
||||
// Erase 'l' from the phrase "Hello" World"
|
||||
auto eraseTest = [](AZStd::initializer_list<char> testInit) constexpr
|
||||
{
|
||||
AZStd::fixed_vector<char, 16> testResult{ testInit };
|
||||
AZStd::erase(testResult, 'l');
|
||||
return testResult;
|
||||
}({ 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' });
|
||||
|
||||
constexpr AZStd::string_view expectedEraseString = "HeoWord";
|
||||
AZStd::string_view testEraseString{ eraseTest.begin(), eraseTest.end() };
|
||||
EXPECT_EQ(expectedEraseString, testEraseString);
|
||||
|
||||
// Use erase_if to erase both 'H' and 'e' from the remaining eraseTest string
|
||||
auto eraseIfTest = [](const AZStd::fixed_vector<char, 16>& testVector) constexpr
|
||||
{
|
||||
AZStd::fixed_vector<char, 16> testResult{ testVector };
|
||||
auto erasePredicate = [](char ch)
|
||||
{
|
||||
return ch == 'H' || ch == 'e';
|
||||
};
|
||||
AZStd::erase_if(testResult, erasePredicate);
|
||||
return testResult;
|
||||
}(testEraseString);
|
||||
|
||||
constexpr AZStd::string_view expectedEraseIfString = "oWord";
|
||||
AZStd::string_view testEraseIfString{ eraseIfTest.begin(), eraseIfTest.end() };
|
||||
EXPECT_EQ(expectedEraseIfString, testEraseIfString);
|
||||
}
|
||||
|
||||
TEST_F(Arrays, VectorSwap)
|
||||
{
|
||||
vector<void*> vec1(42, nullptr);
|
||||
|
||||
Reference in New Issue
Block a user