aboutsummaryrefslogtreecommitdiff
path: root/EASTL/test
diff options
context:
space:
mode:
Diffstat (limited to 'EASTL/test')
-rw-r--r--EASTL/test/CMakeLists.txt3
-rw-r--r--EASTL/test/source/EASTLTest.h2
-rw-r--r--EASTL/test/source/TestAlgorithm.cpp235
-rw-r--r--EASTL/test/source/TestAllocator.cpp2
-rw-r--r--EASTL/test/source/TestArray.cpp47
-rw-r--r--EASTL/test/source/TestChrono.cpp11
-rw-r--r--EASTL/test/source/TestDeque.cpp44
-rw-r--r--EASTL/test/source/TestExtra.cpp610
-rw-r--r--EASTL/test/source/TestFixedString.cpp52
-rw-r--r--EASTL/test/source/TestFunctional.cpp34
-rw-r--r--EASTL/test/source/TestHash.cpp12
-rw-r--r--EASTL/test/source/TestIterator.cpp111
-rw-r--r--EASTL/test/source/TestList.cpp103
-rw-r--r--EASTL/test/source/TestMap.cpp65
-rw-r--r--EASTL/test/source/TestMap.h30
-rw-r--r--EASTL/test/source/TestMemory.cpp44
-rw-r--r--EASTL/test/source/TestNumericLimits.cpp5
-rw-r--r--EASTL/test/source/TestOptional.cpp42
-rw-r--r--EASTL/test/source/TestSList.cpp114
-rw-r--r--EASTL/test/source/TestSet.cpp48
-rw-r--r--EASTL/test/source/TestSmartPtr.cpp39
-rw-r--r--EASTL/test/source/TestSort.cpp42
-rw-r--r--EASTL/test/source/TestString.inl40
-rw-r--r--EASTL/test/source/TestStringView.cpp19
-rw-r--r--EASTL/test/source/TestStringView.inl80
-rw-r--r--EASTL/test/source/TestTuple.cpp51
-rw-r--r--EASTL/test/source/TestTypeTraits.cpp304
-rw-r--r--EASTL/test/source/TestUtility.cpp293
-rw-r--r--EASTL/test/source/TestVariant.cpp139
-rw-r--r--EASTL/test/source/TestVector.cpp94
-rw-r--r--EASTL/test/source/main.cpp2
31 files changed, 2567 insertions, 150 deletions
diff --git a/EASTL/test/CMakeLists.txt b/EASTL/test/CMakeLists.txt
index 3fac51f..ff16189 100644
--- a/EASTL/test/CMakeLists.txt
+++ b/EASTL/test/CMakeLists.txt
@@ -17,6 +17,9 @@ add_definitions(-D_SCL_SECURE_NO_WARNINGS)
add_definitions(-DEASTL_OPENSOURCE=1)
add_definitions(-D_CHAR16T)
add_definitions(-DEASTL_THREAD_SUPPORT_AVAILABLE=0)
+if (EASTL_STD_ITERATOR_CATEGORY_ENABLED)
+ add_definitions(-DEASTL_STD_ITERATOR_CATEGORY_ENABLED=1)
+endif()
#-------------------------------------------------------------------------------------------
# Compiler Flags
diff --git a/EASTL/test/source/EASTLTest.h b/EASTL/test/source/EASTLTest.h
index 1908f5f..fca6b2c 100644
--- a/EASTL/test/source/EASTLTest.h
+++ b/EASTL/test/source/EASTLTest.h
@@ -1261,6 +1261,8 @@ public:
activeAllocatedMemory = 0;
}
+ virtual ~CountingAllocator() = default;
+
static uint64_t activeAllocCount;
static uint64_t totalAllocCount;
static uint64_t totalDeallocCount;
diff --git a/EASTL/test/source/TestAlgorithm.cpp b/EASTL/test/source/TestAlgorithm.cpp
index 142d45e..a0f64da 100644
--- a/EASTL/test/source/TestAlgorithm.cpp
+++ b/EASTL/test/source/TestAlgorithm.cpp
@@ -1509,6 +1509,82 @@ int TestAlgorithm()
EATEST_VERIFY( b);
}
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ // <compairison_category> lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare compare)
+
+ int intArray1[6] = {0, 1, 2, 3, 4, 5};
+ int intArray2[6] = {0, 1, 2, 3, 4, 6};
+ int intArray3[5] = {0, 1, 2, 3, 4};
+ int intArray4[5] = {4, 3, 2, 1, 0};
+
+ // strong ordering
+ auto compare_strong = [](int first, int second)
+ {
+ return (first < second) ? std::strong_ordering::less :
+ (first > second) ? std::strong_ordering::greater :
+ std::strong_ordering::equal;
+ };
+
+ auto b = lexicographical_compare_three_way(intArray1, intArray1 + 6, intArray2, intArray2 + 6, compare_strong);
+ EATEST_VERIFY(b == std::strong_ordering::less);
+ b = lexicographical_compare_three_way(intArray3, intArray3 + 5, intArray2, intArray2 + 6, compare_strong);
+ EATEST_VERIFY(b == std::strong_ordering::less);
+ b = lexicographical_compare_three_way(intArray3, intArray3 + 5, intArray2, intArray2 + 6, synth_three_way{});
+ EATEST_VERIFY(b == std::strong_ordering::less);
+
+ b = lexicographical_compare_three_way(intArray2, intArray2 + 6, intArray1, intArray1 + 6, compare_strong);
+ EATEST_VERIFY(b == std::strong_ordering::greater);
+ b = lexicographical_compare_three_way(intArray2, intArray2 + 6, intArray1, intArray1 + 6, synth_three_way{});
+ EATEST_VERIFY(b == std::strong_ordering::greater);
+
+ b = lexicographical_compare_three_way(intArray1, intArray1 + 6, intArray3, intArray3 + 5, compare_strong);
+ EATEST_VERIFY(b == std::strong_ordering::greater);
+ b = lexicographical_compare_three_way(intArray1, intArray1 + 6, intArray3, intArray3 + 5, synth_three_way{});
+ EATEST_VERIFY(b == std::strong_ordering::greater);
+
+ b = lexicographical_compare_three_way(intArray1, intArray1, intArray2, intArray2, compare_strong); // Test empty range.
+ EATEST_VERIFY(b == std::strong_ordering::equal);
+ b = lexicographical_compare_three_way(intArray1, intArray1, intArray2, intArray2, synth_three_way{}); // Test empty range.
+ EATEST_VERIFY(b == std::strong_ordering::equal);
+
+ // weak ordering
+ auto compare_weak = [](int first, int second)
+ {
+ return (first < second) ? std::weak_ordering::less :
+ (first > second) ? std::weak_ordering::greater :
+ std::weak_ordering::equivalent;
+ };
+
+ auto c = lexicographical_compare_three_way(intArray3, intArray3 + 5, intArray4, intArray4 + 5, compare_weak);
+ EATEST_VERIFY(c == std::weak_ordering::less);
+ c = lexicographical_compare_three_way(intArray4, intArray4 + 5, intArray3, intArray3 + 5, compare_weak);
+ EATEST_VERIFY(c == std::weak_ordering::greater);
+ c = lexicographical_compare_three_way(intArray3, intArray3 + 5, intArray4, intArray4 + 5, synth_three_way{});
+ EATEST_VERIFY(c == std::weak_ordering::less);
+ c = lexicographical_compare_three_way(intArray4, intArray4 + 5, intArray3, intArray3 + 5, synth_three_way{});
+ EATEST_VERIFY(c == std::weak_ordering::greater);
+ }
+
+ {
+ EATEST_VERIFY(synth_three_way{}(1, 1) == std::strong_ordering::equal);
+ EATEST_VERIFY(synth_three_way{}(2, 1) == std::strong_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(1, 2) == std::strong_ordering::less);
+
+ struct weak_struct
+ {
+ int val;
+ inline std::weak_ordering operator<=>(const weak_struct& b) const
+ {
+ return val <=> b.val;
+ }
+ };
+
+ EATEST_VERIFY(synth_three_way{}(weak_struct{1}, weak_struct{2}) == std::weak_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(weak_struct{2}, weak_struct{1}) == std::weak_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(weak_struct{1}, weak_struct{1}) == std::weak_ordering::equivalent);
+ }
+#endif
{
// ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value)
@@ -1815,7 +1891,164 @@ int TestAlgorithm()
}
- {
+ {
+ // ForwardIterator apply_and_remove(ForwardIterator first, ForwardIterator last, Function function, const T&
+ // value) ForwardIterator apply_and_remove_if(ForwardIterator first, ForwardIterator last, Function function,
+ // Predicate predicate)
+
+ // Test for empty range and full container range
+ {
+ int intArray[12] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ int* pInt = apply_and_remove(intArray, intArray, func, 1);
+ EATEST_VERIFY(pInt == intArray);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove", 0, 0, 1, 1, 0, 0, 1, 1, 0,
+ 0, 1, 1, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", -1));
+ pInt = apply_and_remove(intArray, intArray + 12, func, 1);
+ EATEST_VERIFY(pInt == intArray + 6);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "apply_and_remove", 0, 0, 0, 0, 0, 0, -1));
+ EATEST_VERIFY(
+ VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", 1, 1, 1, 1, 1, 1, -1));
+ }
+
+ // Test for no match on empty range and full container range
+ {
+ int intArray[12] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ int* pInt = apply_and_remove(intArray, intArray, func, 1);
+ EATEST_VERIFY(pInt == intArray);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove", 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", -1));
+ pInt = apply_and_remove(intArray, intArray + 12, func, 1);
+ EATEST_VERIFY(pInt == intArray + 12);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove", 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", -1));
+ }
+
+ // Test for empty range and full container range
+ {
+ int intArray[12] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ int* pInt = apply_and_remove_if(intArray, intArray, func, bind2nd(equal_to<int>(), (int)1));
+ EATEST_VERIFY(pInt == intArray);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove_if", 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 1, 1, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", -1));
+ pInt = apply_and_remove_if(intArray, intArray + 12, func, bind2nd(equal_to<int>(), (int)1));
+ EATEST_VERIFY(pInt == intArray + 6);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "apply_and_remove_if", 0, 0, 0, 0, 0, 0, -1));
+ EATEST_VERIFY(
+ VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", 1, 1, 1, 1, 1, 1, -1));
+ }
+
+ // Test for no match on empty range and full container range
+ {
+ int intArray[12] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ int* pInt = apply_and_remove_if(intArray, intArray, func, bind2nd(equal_to<int>(), (int)1));
+ EATEST_VERIFY(pInt == intArray);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove_if", 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", -1));
+ pInt = apply_and_remove_if(intArray, intArray + 12, func, bind2nd(equal_to<int>(), (int)1));
+ EATEST_VERIFY(pInt == intArray + 12);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove_if", 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", -1));
+ }
+
+ auto even = [](int a) { return (a % 2) == 0; };
+ // Test to verify that the remaining element have stable ordering
+ {
+ int intArray[12] = {7, 8, 2, 3, 4, 5, 6, 0, 1, 9, 10, 11};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ int* pInt = apply_and_remove_if(intArray, intArray + 12, func, even);
+ EATEST_VERIFY(pInt == intArray + 6);
+ EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "apply_and_remove_if", 7, 3, 5, 1, 9, 11, -1));
+ EATEST_VERIFY(
+ VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", 8, 2, 4, 6, 0, 10, -1));
+ }
+ {
+ int intArray[12] = {7, 8, 0, 0, 4, 5, 6, 0, 1, 9, 0, 11};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ int* pInt = apply_and_remove(intArray, intArray + 12, func, 0);
+ EATEST_VERIFY(pInt == intArray + 8);
+ EATEST_VERIFY(
+ VerifySequence(intArray, intArray + 8, int(), "apply_and_remove", 7, 8, 4, 5, 6, 1, 9, 11, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", 0, 0, 0, 0, -1));
+ }
+
+ // Tests on a list (i.e. non-contiguous memory container)
+ {
+ list<int> intList = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ auto listIter = apply_and_remove_if(intList.begin(), intList.begin(), func, even);
+ EATEST_VERIFY(listIter == intList.begin());
+ EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "apply_and_remove_if", 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", -1));
+ listIter = apply_and_remove_if(intList.begin(), intList.end(), func, even);
+ EATEST_VERIFY(listIter == next(intList.begin(), 6));
+ EATEST_VERIFY(
+ VerifySequence(intList.begin(), listIter, int(), "apply_and_remove_if", 1, 3, 5, 7, 9, 11, -1));
+ EATEST_VERIFY(
+ VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", 0, 2, 4, 6, 8, 10, -1));
+ }
+ {
+ list<int> intList = {0, 4, 2, 3, 4, 5, 6, 4, 4, 4, 10, 11};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ auto listIter = apply_and_remove(intList.begin(), intList.begin(), func, 4);
+ EATEST_VERIFY(listIter == intList.begin());
+ EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "apply_and_remove", 0, 4, 2, 3, 4, 5, 6,
+ 4, 4, 4, 10, 11, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", -1));
+ listIter = apply_and_remove(intList.begin(), intList.end(), func, 4);
+ EATEST_VERIFY(listIter == next(intList.begin(), 7));
+ EATEST_VERIFY(
+ VerifySequence(intList.begin(), listIter, int(), "apply_and_remove", 0, 2, 3, 5, 6, 10, 11, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", 4, 4, 4, 4, 4, -1));
+ }
+
+ // Tests on a part of a container
+ {
+ vector<int> intVector = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ auto vectorIter = apply_and_remove_if(next(intVector.begin(), 3), prev(intVector.end(), 2), func, even);
+ EATEST_VERIFY(vectorIter == next(intVector.begin(), 7));
+ EATEST_VERIFY(
+ VerifySequence(intVector.begin(), vectorIter, int(), "apply_and_remove_if", 0, 1, 2, 3, 5, 7, 9, -1));
+ EATEST_VERIFY(
+ VerifySequence(prev(intVector.end(), 2), intVector.end(), int(), "apply_and_remove_if", 10, 11, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", 4, 6, 8, -1));
+ }
+ {
+ vector<int> intVector = {5, 1, 5, 3, 4, 5, 5, 7, 8, 5, 10, 5};
+ vector<int> output;
+ auto func = [&output](int a) { output.push_back(a); };
+ auto vectorIter = apply_and_remove(next(intVector.begin(), 2), prev(intVector.end(), 3), func, 5);
+ EATEST_VERIFY(vectorIter == next(intVector.begin(), 6));
+ EATEST_VERIFY(
+ VerifySequence(intVector.begin(), vectorIter, int(), "apply_and_remove", 5, 1, 3, 4, 7, 8, -1));
+ EATEST_VERIFY(
+ VerifySequence(prev(intVector.end(), 3), intVector.end(), int(), "apply_and_remove", 5, 10, 5, -1));
+ EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", 5, 5, 5, -1));
+ }
+ }
+
+
+ {
// OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value)
// OutputIterator replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate, const T& new_value)
diff --git a/EASTL/test/source/TestAllocator.cpp b/EASTL/test/source/TestAllocator.cpp
index 85f5adf..2a28c07 100644
--- a/EASTL/test/source/TestAllocator.cpp
+++ b/EASTL/test/source/TestAllocator.cpp
@@ -151,6 +151,8 @@ static int TestFixedAllocator()
{
EATEST_VERIFY(buffer1[i].mValue == TEST_VALUE);
}
+
+ intList1.clear();
}
{ // fixed_allocator_with_overflow
diff --git a/EASTL/test/source/TestArray.cpp b/EASTL/test/source/TestArray.cpp
index 3db95b9..ca05b67 100644
--- a/EASTL/test/source/TestArray.cpp
+++ b/EASTL/test/source/TestArray.cpp
@@ -125,6 +125,22 @@ int TestArray()
VERIFY(!(a >= c));
VERIFY(!(a > c));
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ VERIFY( (a <=> b) == 0);
+ VERIFY(!((a <=> b) != 0));
+ VERIFY(!((a <=> b) < 0));
+ VERIFY( (a <=> b) <= 0);
+ VERIFY( (a <=> b) >= 0);
+ VERIFY(!((a <=> b) > 0));
+
+ VERIFY(!((a <=> c) == 0));
+ VERIFY( (a <=> c) != 0);
+ VERIFY( (a <=> c) < 0);
+ VERIFY( (a <=> c) <= 0);
+ VERIFY(!((a <=> c) >= 0));
+ VERIFY(!((a <=> c) > 0));
+#endif
+
// deduction guides
#ifdef __cpp_deduction_guides
array deduced {1,2,3,4,5};
@@ -132,6 +148,37 @@ int TestArray()
static_assert(eastl::is_same_v<decltype(deduced)::value_type, int>, "deduced array value_type mismatch");
VERIFY(deduced.size() == 5);
#endif
+
+ // structured binding
+
+ {
+ eastl::array<int, 5> aCopy = a;
+ auto&& [a0, a1, a2, a3, a4] = aCopy;
+
+ VERIFY(a0 == aCopy[0]);
+ VERIFY(a1 == aCopy[1]);
+ VERIFY(a2 == aCopy[2]);
+ VERIFY(a3 == aCopy[3]);
+ VERIFY(a4 == aCopy[4]);
+
+ a0 = 100;
+ VERIFY(aCopy[0] == 100);
+
+ a4 = 0;
+ VERIFY(aCopy[4] == 0);
+
+ // The deduced type may or may not be a reference type; it is an aliased type,
+ // as per https://en.cppreference.com/w/cpp/language/structured_binding:
+ // > Like a reference, a structured binding is an alias to an existing object. Unlike a reference,
+ // the type of a structured binding does not have to be a reference type.
+ // Any reference specifier is thus removed to check only the type & its const qualifier
+ static_assert(eastl::is_same_v<eastl::remove_reference_t<decltype(a0)>, int>);
+
+ const eastl::array<int, 5> aConstCopy = a;
+ auto&& [aConst0, aConst1, aConst2, aConst3, aConst4] = aConstCopy;
+
+ static_assert(eastl::is_same_v<eastl::remove_reference_t<decltype(aConst0)>, const int>);
+ }
}
// constexpr tests
diff --git a/EASTL/test/source/TestChrono.cpp b/EASTL/test/source/TestChrono.cpp
index 6a698e9..a56b934 100644
--- a/EASTL/test/source/TestChrono.cpp
+++ b/EASTL/test/source/TestChrono.cpp
@@ -89,12 +89,15 @@ int TestDuration()
microseconds us = 2 * ms; // 6000 microseconds constructed from 3 milliseconds
VERIFY(us.count() == 6000);
+
+ microseconds us2 = ms * 2; // 6000 microseconds constructed from 3 milliseconds
+ VERIFY(us2.count() == 6000);
- microseconds us2 = us / 2;
- VERIFY(us2.count() == 3000);
+ microseconds us3 = us / 2;
+ VERIFY(us3.count() == 3000);
- microseconds us3 = us % 2;
- VERIFY(us3.count() == 0);
+ microseconds us4 = us % 2;
+ VERIFY(us4.count() == 0);
}
}
diff --git a/EASTL/test/source/TestDeque.cpp b/EASTL/test/source/TestDeque.cpp
index 99076ff..e3f4ab6 100644
--- a/EASTL/test/source/TestDeque.cpp
+++ b/EASTL/test/source/TestDeque.cpp
@@ -1063,29 +1063,61 @@ int TestDeque()
{
eastl::deque<int> d = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- eastl::erase(d, 2);
+ auto numErased = eastl::erase(d, 2);
VERIFY((d == eastl::deque<int>{1, 3, 4, 5, 6, 7, 8, 9}));
+ VERIFY(numErased == 1);
- eastl::erase(d, 7);
+ numErased = eastl::erase(d, 7);
VERIFY((d == eastl::deque<int>{1, 3, 4, 5, 6, 8, 9}));
+ VERIFY(numErased == 1);
- eastl::erase(d, 9);
+ numErased = eastl::erase(d, 9);
VERIFY((d == eastl::deque<int>{1, 3, 4, 5, 6, 8}));
+ VERIFY(numErased == 1);
- eastl::erase(d, 5);
+ numErased = eastl::erase(d, 5);
VERIFY((d == eastl::deque<int>{1, 3, 4, 6, 8}));
+ VERIFY(numErased == 1);
- eastl::erase(d, 3);
+ numErased = eastl::erase(d, 3);
VERIFY((d == eastl::deque<int>{1, 4, 6, 8}));
+ VERIFY(numErased == 1);
}
{
eastl::deque<int> d = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- eastl::erase_if(d, [](auto i) { return i % 2 == 0; });
+ auto numErased = eastl::erase_if(d, [](auto i) { return i % 2 == 0; });
VERIFY((d == eastl::deque<int>{1, 3, 5, 7, 9}));
+ VERIFY(numErased == 4);
}
}
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+
+ { // Test <=>
+ eastl::deque<int> d1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ eastl::deque<int> d2 = {9, 8, 7, 6, 5, 4, 3, 2, 1};
+ eastl::deque<int> d3 = {1, 2, 3, 4, 5};
+ eastl::deque<int> d4 = {10};
+
+ VERIFY(d1 != d2);
+ VERIFY(d1 < d2);
+ VERIFY(d1 != d3);
+ VERIFY(d1 > d3);
+ VERIFY(d4 > d1);
+ VERIFY(d4 > d2);
+ VERIFY(d4 > d3);
+
+ VERIFY((d1 <=> d2) != 0);
+ VERIFY((d1 <=> d2) < 0);
+ VERIFY((d1 <=> d3) != 0);
+ VERIFY((d1 <=> d3) > 0);
+ VERIFY((d4 <=> d1) > 0);
+ VERIFY((d4 <=> d2) > 0);
+ VERIFY((d4 <=> d3) > 0);
+ }
+#endif
+
return nErrorCount;
}
diff --git a/EASTL/test/source/TestExtra.cpp b/EASTL/test/source/TestExtra.cpp
index 03f7b41..52fbd62 100644
--- a/EASTL/test/source/TestExtra.cpp
+++ b/EASTL/test/source/TestExtra.cpp
@@ -66,6 +66,7 @@ namespace eastl
#include <EASTL/string.h>
#include <EASTL/hash_set.h>
#include <EASTL/random.h>
+#include <EASTL/bit.h>
#include <EASTL/core_allocator_adapter.h>
#include <EASTL/bonus/call_traits.h>
#include <EASTL/bonus/compressed_pair.h>
@@ -292,7 +293,6 @@ static int TestQueue()
EATEST_VERIFY(!(toListQueue < toListQueue2));
EATEST_VERIFY(!(toListQueue > toListQueue2));
-
// bool empty() const;
// size_type size() const;
EATEST_VERIFY(toListQueue.empty());
@@ -356,6 +356,103 @@ static int TestQueue()
EATEST_VERIFY(intQueue.front() == 5);
}
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ // queue(const Sequence& x = Sequence());
+ queue<TestObject, list<TestObject>> toListQueue;
+ queue<TestObject, list<TestObject>> toListQueue2;
+
+
+ // global operators
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) == 0));
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) != 0));
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) <= 0));
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) >= 0));
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) < 0));
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) > 0));
+
+ // bool empty() const;
+ // size_type size() const;
+ EATEST_VERIFY(toListQueue.empty());
+ EATEST_VERIFY(toListQueue.size() == 0);
+
+ // Verify toListQueue > toListQueue2
+ toListQueue.push(TestObject(0));
+ toListQueue.push(TestObject(1));
+ toListQueue2.push(TestObject(0));
+
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) == 0));
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) != 0));
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) >= 0));
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) <= 0));
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) > 0));
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) < 0));
+
+ // Verify toListQueue2 > toListQueue by element size
+ toListQueue2.push(TestObject(3));
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) == 0));
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) != 0));
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) <= 0));
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) >= 0));
+ EATEST_VERIFY( ((toListQueue <=> toListQueue2) < 0));
+ EATEST_VERIFY(!((toListQueue <=> toListQueue2) > 0));
+
+ queue<TestObject, list<TestObject>> toListQueue3;
+ queue<TestObject, list<TestObject>> toListQueue4;
+
+ for (int i = 0; i < 10; i++)
+ {
+ toListQueue3.push(TestObject(i));
+ if (i < 5)
+ toListQueue4.push(TestObject(i));
+ }
+
+ // Verify toListQueue4 is a strict subset of toListQueue3
+ EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) == 0));
+ EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) != 0));
+ EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) >= 0));
+ EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) <= 0));
+ EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) > 0));
+ EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) < 0));
+
+ // Verify that even thoughn toListQueue4 has a smaller size, it's lexicographically larger
+ toListQueue4.push(TestObject(11));
+ EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) == 0));
+ EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) != 0));
+ EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) <= 0));
+ EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) >= 0));
+ EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) < 0));
+ EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) > 0));
+
+ }
+
+ {
+ queue<TestObject, list<TestObject>> toListQueue1;
+ queue<TestObject, list<TestObject>> toListQueue2;
+ queue<TestObject, list<TestObject>> toListQueue3;
+
+ for (int i = 0; i < 10; i++)
+ {
+ toListQueue1.push(TestObject(i));
+ toListQueue2.push(TestObject(9-i));
+ if (i < 5)
+ toListQueue3.push(TestObject(i));
+ }
+
+ struct weak_ordering_queue
+ {
+ queue<TestObject, list<TestObject>> queue;
+ inline std::weak_ordering operator<=>(const weak_ordering_queue& b) const { return queue <=> b.queue; }
+ };
+
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue1}, weak_ordering_queue{toListQueue2}) == std::weak_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue3}, weak_ordering_queue{toListQueue1}) == std::weak_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue2}, weak_ordering_queue{toListQueue1}) == std::weak_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue2}, weak_ordering_queue{toListQueue3}) == std::weak_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue1}, weak_ordering_queue{toListQueue1}) == std::weak_ordering::equivalent);
+ }
+ #endif
+
{
vector<TestObject> toVector;
for(int i = 0; i < 100; i++)
@@ -620,7 +717,6 @@ static int TestStack()
EATEST_VERIFY(!(toListStack < toListStack2));
EATEST_VERIFY(!(toListStack > toListStack2));
-
// void push(const value_type& value);
// reference top();
// const_reference top() const;
@@ -665,6 +761,101 @@ static int TestStack()
#endif
}
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ // stack(const Sequence& x = Sequence());
+ stack<TestObject, list<TestObject> > toListStack;
+ stack<TestObject, list<TestObject> > toListStack2;
+
+ // bool empty() const;
+ // size_type size() const;
+ EATEST_VERIFY(toListStack.empty());
+ EATEST_VERIFY(toListStack.size() == 0);
+
+
+ // global operators
+ EATEST_VERIFY( ((toListStack <=> toListStack2) == 0));
+ EATEST_VERIFY(!((toListStack <=> toListStack2) != 0));
+ EATEST_VERIFY( ((toListStack <=> toListStack2) <= 0));
+ EATEST_VERIFY( ((toListStack <=> toListStack2) >= 0));
+ EATEST_VERIFY(!((toListStack <=> toListStack2) < 0));
+ EATEST_VERIFY(!((toListStack <=> toListStack2) > 0));
+
+ toListStack.push(TestObject(0));
+ toListStack.push(TestObject(1));
+ toListStack2.push(TestObject(0));
+
+ EATEST_VERIFY(!((toListStack <=> toListStack2) == 0));
+ EATEST_VERIFY( ((toListStack <=> toListStack2) != 0));
+ EATEST_VERIFY( ((toListStack <=> toListStack2) >= 0));
+ EATEST_VERIFY(!((toListStack <=> toListStack2) <= 0));
+ EATEST_VERIFY( ((toListStack <=> toListStack2) > 0));
+ EATEST_VERIFY(!((toListStack <=> toListStack2) < 0));
+
+ // Verify toListStack2 > toListStack by element size
+ toListStack2.push(TestObject(3));
+ EATEST_VERIFY(!((toListStack <=> toListStack2) == 0));
+ EATEST_VERIFY( ((toListStack <=> toListStack2) != 0));
+ EATEST_VERIFY( ((toListStack <=> toListStack2) <= 0));
+ EATEST_VERIFY(!((toListStack <=> toListStack2) >= 0));
+ EATEST_VERIFY( ((toListStack <=> toListStack2) < 0));
+ EATEST_VERIFY(!((toListStack <=> toListStack2) > 0));
+
+ stack<TestObject, list<TestObject> > toListStack3;
+ stack<TestObject, list<TestObject> > toListStack4;
+
+ for (int i = 0; i < 10; i++)
+ {
+ toListStack3.push(TestObject(i));
+ if (i < 5)
+ toListStack4.push(TestObject(i));
+ }
+
+ // Verify toListStack4 is a strict subset of toListStack3
+ EATEST_VERIFY(!((toListStack3 <=> toListStack4) == 0));
+ EATEST_VERIFY( ((toListStack3 <=> toListStack4) != 0));
+ EATEST_VERIFY( ((toListStack3 <=> toListStack4) >= 0));
+ EATEST_VERIFY(!((toListStack3 <=> toListStack4) <= 0));
+ EATEST_VERIFY( ((toListStack3 <=> toListStack4) > 0));
+ EATEST_VERIFY(!((toListStack3 <=> toListStack4) < 0));
+
+ // Verify that even thoughn toListQueue4 has a smaller size, it's lexicographically larger
+ toListStack4.push(TestObject(11));
+ EATEST_VERIFY(!((toListStack3 <=> toListStack4) == 0));
+ EATEST_VERIFY( ((toListStack3 <=> toListStack4) != 0));
+ EATEST_VERIFY( ((toListStack3 <=> toListStack4) <= 0));
+ EATEST_VERIFY(!((toListStack3 <=> toListStack4) >= 0));
+ EATEST_VERIFY( ((toListStack3 <=> toListStack4) < 0));
+ EATEST_VERIFY(!((toListStack3 <=> toListStack4) > 0));
+ }
+
+ {
+ stack<TestObject, list<TestObject> > toListStack1;
+ stack<TestObject, list<TestObject> > toListStack2;
+ stack<TestObject, list<TestObject> > toListStack3;
+
+ for (int i = 0; i < 10; i++)
+ {
+ toListStack1.push(TestObject(i));
+ toListStack2.push(TestObject(9-i));
+ if (i < 5)
+ toListStack3.push(TestObject(i));
+ }
+
+ struct weak_ordering_stack
+ {
+ stack<TestObject, list<TestObject> > stack;
+ inline std::weak_ordering operator<=>(const weak_ordering_stack& b) const { return stack <=> b.stack; }
+ };
+
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack1}, weak_ordering_stack{toListStack2}) == std::weak_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack3}, weak_ordering_stack{toListStack1}) == std::weak_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack2}, weak_ordering_stack{toListStack1}) == std::weak_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack2}, weak_ordering_stack{toListStack3}) == std::weak_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack1}, weak_ordering_stack{toListStack1}) == std::weak_ordering::equivalent);
+ }
+#endif
+
{
vector<TestObject> toVector;
@@ -862,6 +1053,281 @@ static int TestNumeric()
return nErrorCount;
}
+#if defined(EA_COMPILER_CPP20_ENABLED)
+template <typename T>
+static constexpr int SignedIntMidpoint()
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::midpoint(T(0), T(0)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(0), T(2)) == T(1));
+ EATEST_VERIFY(eastl::midpoint(T(0), T(4)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(0), T(8)) == T(4));
+ EATEST_VERIFY(eastl::midpoint(T(2), T(0)) == T(1));
+ EATEST_VERIFY(eastl::midpoint(T(4), T(0)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(8), T(0)) == T(4));
+
+ EATEST_VERIFY(eastl::midpoint(T(1), T(1)) == T(1));
+ EATEST_VERIFY(eastl::midpoint(T(1), T(3)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(3), T(1)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(2), T(6)) == T(4));
+ EATEST_VERIFY(eastl::midpoint(T(6), T(2)) == T(4));
+
+ EATEST_VERIFY(eastl::midpoint(T(-1), T(-1)) == T(-1));
+ EATEST_VERIFY(eastl::midpoint(T(-1), T(-3)) == T(-2));
+ EATEST_VERIFY(eastl::midpoint(T(-3), T(-1)) == T(-2));
+ EATEST_VERIFY(eastl::midpoint(T(-2), T(-6)) == T(-4));
+ EATEST_VERIFY(eastl::midpoint(T(-6), T(-2)) == T(-4));
+
+ EATEST_VERIFY(eastl::midpoint(T(-0), T(0)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(0), T(-0)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(-0), T(-0)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(-1), T(1)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(-10), T(10)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(-3), T(7)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(-7), T(3)) == T(-2));
+ EATEST_VERIFY(eastl::midpoint(T(-2), T(6)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(-6), T(2)) == T(-2));
+ EATEST_VERIFY(eastl::midpoint(T(2), T(-6)) == T(-2));
+ EATEST_VERIFY(eastl::midpoint(T(6), T(-2)) == T(2));
+
+ // If an odd sum, midpoint should round towards the LHS operand.
+ EATEST_VERIFY(eastl::midpoint(T(0), T(5)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(5), T(0)) == T(3));
+ EATEST_VERIFY(eastl::midpoint(T(1), T(4)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(4), T(1)) == T(3));
+ EATEST_VERIFY(eastl::midpoint(T(7), T(10)) == T(8));
+ EATEST_VERIFY(eastl::midpoint(T(10), T(7)) == T(9));
+ EATEST_VERIFY(eastl::midpoint(T(-1), T(2)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(2), T(-1)) == T(1));
+ EATEST_VERIFY(eastl::midpoint(T(-5), T(4)) == T(-1));
+ EATEST_VERIFY(eastl::midpoint(T(4), T(-5)) == T(0));
+
+ // Test absolute limits
+ constexpr T MIN = eastl::numeric_limits<T>::min();
+ constexpr T MAX = eastl::numeric_limits<T>::max();
+
+ EATEST_VERIFY(eastl::midpoint(MIN, MIN) == MIN);
+ EATEST_VERIFY(eastl::midpoint(MAX, MAX) == MAX);
+ EATEST_VERIFY(eastl::midpoint(MIN, MAX) == T(-1));
+ EATEST_VERIFY(eastl::midpoint(MAX, MIN) == T(0));
+ EATEST_VERIFY(eastl::midpoint(MIN, T(0)) == MIN / 2);
+ EATEST_VERIFY(eastl::midpoint(T(0), MIN) == MIN / 2);
+ EATEST_VERIFY(eastl::midpoint(MAX, T(0)) == (MAX / 2) + 1);
+ EATEST_VERIFY(eastl::midpoint(T(0), MAX) == (MAX / 2));
+
+ EATEST_VERIFY(eastl::midpoint(MIN, T(10)) == (MIN / 2) + 5);
+ EATEST_VERIFY(eastl::midpoint(T(10), MIN) == (MIN / 2) + 5);
+ EATEST_VERIFY(eastl::midpoint(MAX, T(10)) == (MAX / 2) + 5 + 1);
+ EATEST_VERIFY(eastl::midpoint(T(10), MAX) == (MAX / 2) + 5);
+ EATEST_VERIFY(eastl::midpoint(MIN, T(-10)) == (MIN / 2) - 5);
+ EATEST_VERIFY(eastl::midpoint(T(-10), MIN) == (MIN / 2) - 5);
+ EATEST_VERIFY(eastl::midpoint(MAX, T(-10)) == (MAX / 2) - 5 + 1);
+ EATEST_VERIFY(eastl::midpoint(T(-10), MAX) == (MAX / 2) - 5);
+
+ return nErrorCount;
+}
+
+template <typename T>
+static constexpr int UnsignedIntMidpoint()
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::midpoint(T(0), T(0)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(0), T(2)) == T(1));
+ EATEST_VERIFY(eastl::midpoint(T(0), T(4)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(0), T(8)) == T(4));
+ EATEST_VERIFY(eastl::midpoint(T(2), T(0)) == T(1));
+ EATEST_VERIFY(eastl::midpoint(T(4), T(0)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(8), T(0)) == T(4));
+
+ EATEST_VERIFY(eastl::midpoint(T(1), T(1)) == T(1));
+ EATEST_VERIFY(eastl::midpoint(T(1), T(3)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(3), T(1)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(2), T(6)) == T(4));
+ EATEST_VERIFY(eastl::midpoint(T(6), T(2)) == T(4));
+
+ // If an odd sum, midpoint should round towards the LHS operand.
+ EATEST_VERIFY(eastl::midpoint(T(0), T(5)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(5), T(0)) == T(3));
+ EATEST_VERIFY(eastl::midpoint(T(1), T(4)) == T(2));
+ EATEST_VERIFY(eastl::midpoint(T(4), T(1)) == T(3));
+ EATEST_VERIFY(eastl::midpoint(T(7), T(10)) == T(8));
+ EATEST_VERIFY(eastl::midpoint(T(10), T(7)) == T(9));
+
+ // Test absolute limits
+ constexpr T MIN = eastl::numeric_limits<T>::min();
+ constexpr T MAX = eastl::numeric_limits<T>::max();
+
+ EATEST_VERIFY(eastl::midpoint(MIN, MIN) == MIN);
+ EATEST_VERIFY(eastl::midpoint(MAX, MAX) == MAX);
+ EATEST_VERIFY(eastl::midpoint(MIN, MAX) == MAX / 2);
+ EATEST_VERIFY(eastl::midpoint(MAX, MIN) == (MAX / 2) + 1);
+ EATEST_VERIFY(eastl::midpoint(MIN, T(0)) == T(0));
+ EATEST_VERIFY(eastl::midpoint(T(0), MIN) == T(0));
+
+ EATEST_VERIFY(eastl::midpoint(MIN, T(10)) == (MIN / 2) + 5);
+ EATEST_VERIFY(eastl::midpoint(T(10), MIN) == (MIN / 2) + 5);
+ EATEST_VERIFY(eastl::midpoint(MAX, T(10)) == (MAX / 2) + 5 + 1);
+ EATEST_VERIFY(eastl::midpoint(T(10), MAX) == (MAX / 2) + 5);
+
+ return nErrorCount;
+}
+
+template <typename T>
+static constexpr int FloatMidpoint()
+{
+ // for use with floats, double, long doubles.
+ int nErrorCount = 0;
+ EATEST_VERIFY(eastl::midpoint(T(0.0), T(0.0)) == T(0.0));
+ EATEST_VERIFY(eastl::midpoint(T(0.0), T(2.0)) == T(1.0));
+ EATEST_VERIFY(eastl::midpoint(T(0.0), T(4.0)) == T(2.0));
+ EATEST_VERIFY(eastl::midpoint(T(2.0), T(0.0)) == T(1.0));
+ EATEST_VERIFY(eastl::midpoint(T(4.0), T(0.0)) == T(2.0));
+
+ EATEST_VERIFY(eastl::midpoint(T(0.5), T(0.5)) == T(0.5));
+ EATEST_VERIFY(eastl::midpoint(T(0.0), T(0.5)) == T(0.25));
+ EATEST_VERIFY(eastl::midpoint(T(0.5), T(0.0)) == T(0.25));
+ EATEST_VERIFY(eastl::midpoint(T(0.5), T(1.0)) == T(0.75));
+ EATEST_VERIFY(eastl::midpoint(T(1.0), T(0.5)) == T(0.75));
+
+ EATEST_VERIFY(eastl::midpoint(T(-0.0), T(0.0)) == T(0.0));
+ EATEST_VERIFY(eastl::midpoint(T(0.0), T(-0.0)) == T(0.0));
+ EATEST_VERIFY(eastl::midpoint(T(-0.0), T(-0.0)) == T(0.0));
+ EATEST_VERIFY(eastl::midpoint(T(-1.0), T(2.0)) == T(0.5));
+ EATEST_VERIFY(eastl::midpoint(T(-2.0), T(1)) == T(-0.5));
+ EATEST_VERIFY(eastl::midpoint(T(-3.0), T(6.0)) == T(1.5));
+ EATEST_VERIFY(eastl::midpoint(T(-6.0), T(3.0)) == T(-1.5));
+
+ // Test absolute limits
+ const T MIN = eastl::numeric_limits<T>::min();
+ const T MAX = eastl::numeric_limits<T>::max();
+
+ EATEST_VERIFY(eastl::midpoint(MIN, MIN) == MIN);
+ EATEST_VERIFY(eastl::midpoint(MAX, MAX) == MAX);
+ EATEST_VERIFY(eastl::midpoint(MIN, MAX) == MAX / 2);
+ EATEST_VERIFY(eastl::midpoint(MAX, MIN) == MAX / 2);
+ EATEST_VERIFY(eastl::midpoint(-MAX, MIN) == -MAX / 2);
+
+ EATEST_VERIFY(eastl::midpoint(MIN, T(9.0)) == T(4.5));
+ EATEST_VERIFY(eastl::midpoint(MIN, T(-9.0)) == T(-4.5));
+ EATEST_VERIFY(eastl::midpoint(T(9.0), MIN) == T(4.5));
+ EATEST_VERIFY(eastl::midpoint(T(-9.0), MIN) == T(-4.5));
+ EATEST_VERIFY(eastl::midpoint(MAX, T(9.0)) == MAX / 2 + T(4.5));
+ EATEST_VERIFY(eastl::midpoint(MAX, T(-9.0)) == MAX / 2 - T(4.5));
+ EATEST_VERIFY(eastl::midpoint(T(9.0), MAX) == MAX / 2 + T(4.5));
+ EATEST_VERIFY(eastl::midpoint(T(-9.0), MAX) == MAX / 2 - T(4.5));
+
+ return nErrorCount;
+}
+
+template <typename T>
+static constexpr int PointerMidpoint()
+{
+ int nErrorCount = 0;
+
+ const T ARR[100] = {};
+
+ EATEST_VERIFY(eastl::midpoint(ARR, ARR) == ARR);
+ EATEST_VERIFY(eastl::midpoint(ARR, ARR + 100) == ARR + 50);
+ EATEST_VERIFY(eastl::midpoint(ARR + 100, ARR) == ARR + 50);
+ EATEST_VERIFY(eastl::midpoint(ARR, ARR + 25) == ARR + 12);
+ EATEST_VERIFY(eastl::midpoint(ARR + 25, ARR) == ARR + 13);
+ EATEST_VERIFY(eastl::midpoint(ARR, ARR + 13) == ARR + 6);
+ EATEST_VERIFY(eastl::midpoint(ARR + 13, ARR) == ARR + 7);
+ EATEST_VERIFY(eastl::midpoint(ARR + 50, ARR + 100) == ARR + 75);
+ EATEST_VERIFY(eastl::midpoint(ARR + 100, ARR + 50) == ARR + 75);
+
+ return nErrorCount;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// TestMidpoint
+//
+static int TestMidpoint()
+{
+ int nErrorCount = 0;
+
+ // template <typename T>
+ // constexpr eastl::enable_if_t<eastl::is_arithmetic_v<T> && !eastl::is_same_v<eastl::remove_cv_t<T>, bool>, T>
+ // midpoint(const T lhs, const T rhs) EA_NOEXCEPT
+ nErrorCount += SignedIntMidpoint<int>();
+ nErrorCount += SignedIntMidpoint<char>();
+ nErrorCount += SignedIntMidpoint<short>();
+ nErrorCount += SignedIntMidpoint<long>();
+ nErrorCount += SignedIntMidpoint<long long>();
+
+ nErrorCount += UnsignedIntMidpoint<unsigned int>();
+ nErrorCount += UnsignedIntMidpoint<unsigned char>();
+ nErrorCount += UnsignedIntMidpoint<unsigned short>();
+ nErrorCount += UnsignedIntMidpoint<unsigned long>();
+ nErrorCount += UnsignedIntMidpoint<unsigned long long>();
+
+ nErrorCount += FloatMidpoint<float>();
+ nErrorCount += FloatMidpoint<double>();
+ nErrorCount += FloatMidpoint<long double>();
+
+ // template <typename T>
+ // constexpr eastl::enable_if_t<eastl::is_object_v<T>, const T*> midpoint(const T* lhs, const T* rhs)
+ nErrorCount += PointerMidpoint<int>();
+ nErrorCount += PointerMidpoint<char>();
+ nErrorCount += PointerMidpoint<short>();
+ nErrorCount += PointerMidpoint<float>();
+ nErrorCount += PointerMidpoint<double>();
+ nErrorCount += PointerMidpoint<long double>();
+
+ return nErrorCount;
+}
+
+
+template <typename T>
+static constexpr int FloatLerp()
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::lerp(T(0.0), T(0.0), T(0.0)) == T(0.0));
+ EATEST_VERIFY(eastl::lerp(T(1.0), T(0.0), T(0.0)) == T(1.0));
+ EATEST_VERIFY(eastl::lerp(T(-1.0), T(0.0), T(0.0)) == T(-1.0));
+ EATEST_VERIFY(eastl::lerp(T(0.0), T(1.0), T(0.0)) == T(0.0));
+ EATEST_VERIFY(eastl::lerp(T(0.0), T(-1.0), T(0.0)) == T(0.0));
+ EATEST_VERIFY(eastl::lerp(T(-1.0), T(1.0), T(1.0)) == T(1.0));
+ EATEST_VERIFY(eastl::lerp(T(1.0), T(-1.0), T(1.0)) == T(-1.0));
+ EATEST_VERIFY(eastl::lerp(T(-1.0), T(1.0), T(0.5)) == T(0.0));
+ EATEST_VERIFY(eastl::lerp(T(1.0), T(-1.0), T(0.5)) == T(0.0));
+ EATEST_VERIFY(eastl::lerp(T(5.0), T(5.0), T(0.5)) == T(5.0));
+ EATEST_VERIFY(eastl::lerp(T(-5.0), T(-5.0), T(0.5)) == T(-5.0));
+ EATEST_VERIFY(eastl::lerp(T(1.0), T(2.0), T(1.0)) == T(2.0));
+ EATEST_VERIFY(eastl::lerp(T(2.0), T(1.0), T(1.0)) == T(1.0));
+ EATEST_VERIFY(eastl::lerp(T(1.0), T(2.0), T(1.0)) == T(2.0));
+ EATEST_VERIFY(eastl::lerp(T(1.0), T(2.0), T(2.0)) == T(3.0));
+ EATEST_VERIFY(eastl::lerp(T(2.0), T(1.0), T(2.0)) == T(0.0));
+ EATEST_VERIFY(eastl::lerp(T(1.0), T(-2.0), T(2.0)) == T(-5.0));
+ EATEST_VERIFY(eastl::lerp(T(-1.0), T(2.0), T(2.0)) == T(5.0));
+ EATEST_VERIFY(eastl::lerp(T(-1.5), T(1.5), T(0.75)) == T(0.75));
+ EATEST_VERIFY(eastl::lerp(T(0.125), T(1.75), T(0.25)) == T(0.53125));
+ EATEST_VERIFY(eastl::lerp(T(-0.125), T(-1.75), T(0.5)) == T(-0.9375));
+ EATEST_VERIFY(eastl::lerp(T(-0.125), T(1.5), T(2.5)) == T(3.9375));
+
+ return nErrorCount;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// TestLerp
+//
+static int TestLerp()
+{
+ int nErrorCount = 0;
+
+ // template <class T>
+ // constexpr T lerp(const T a, const T b, const T t) EA_NOEXCEPT
+ nErrorCount += FloatLerp<float>();
+ nErrorCount += FloatLerp<double>();
+ nErrorCount += FloatLerp<long double>();
+
+ return nErrorCount;
+}
+#endif
///////////////////////////////////////////////////////////////////////////////
@@ -914,7 +1380,142 @@ static int TestAdaptors()
return nErrorCount;
}
+#if defined(EA_COMPILER_CPP20_ENABLED)
+template <typename T>
+int TestHasSingleBit()
+{
+ int nErrorCount = 0;
+
+ VERIFY(eastl::has_single_bit(T(0)) == false);
+ VERIFY(eastl::has_single_bit(T(1)) == true);
+ VERIFY(eastl::has_single_bit(T(2)) == true);
+ VERIFY(eastl::has_single_bit(T(3)) == false);
+
+ VERIFY(eastl::has_single_bit(eastl::numeric_limits<T>::min()) == false);
+ VERIFY(eastl::has_single_bit(eastl::numeric_limits<T>::max()) == false);
+ for (int i = 4; i < eastl::numeric_limits<T>::digits; i++)
+ {
+ T power_of_two = static_cast<T>(T(1U) << i);
+ VERIFY(eastl::has_single_bit(power_of_two));
+ VERIFY(eastl::has_single_bit(static_cast<T>(power_of_two - 1)) == false);
+ }
+
+ return nErrorCount;
+}
+
+template <typename T>
+static int TestBitCeil()
+{
+ int nErrorCount = 0;
+
+ VERIFY(eastl::bit_ceil(T(0)) == T(1));
+ VERIFY(eastl::bit_ceil(T(1)) == T(1));
+ VERIFY(eastl::bit_ceil(T(2)) == T(2));
+ VERIFY(eastl::bit_ceil(T(3)) == T(4));
+
+ EA_CONSTEXPR auto DIGITS = eastl::numeric_limits<T>::digits;
+ EA_CONSTEXPR auto MIN = eastl::numeric_limits<T>::min();
+ EA_CONSTEXPR auto MAX = static_cast<T>(T(1) << (DIGITS - 1));
+
+ VERIFY(eastl::bit_ceil(MAX) == MAX);
+ VERIFY(eastl::bit_ceil(static_cast<T>(MAX - 1)) == MAX);
+ VERIFY(eastl::bit_ceil(MIN) == T(1));
+
+ for (int i = 4; i < eastl::numeric_limits<T>::digits; i++)
+ {
+ T power_of_two = static_cast<T>(T(1U) << i);
+ VERIFY(eastl::bit_ceil(power_of_two) == power_of_two);
+ VERIFY(eastl::bit_ceil(static_cast<T>(power_of_two - 1)) == power_of_two);
+ }
+
+ return nErrorCount;
+}
+
+template <typename T>
+static int TestBitFloor()
+{
+ int nErrorCount = 0;
+ VERIFY(eastl::bit_floor(T(0)) == T(0));
+ VERIFY(eastl::bit_floor(T(1)) == T(1));
+ VERIFY(eastl::bit_floor(T(2)) == T(2));
+ VERIFY(eastl::bit_floor(T(3)) == T(2));
+
+ EA_CONSTEXPR auto DIGITS = eastl::numeric_limits<T>::digits;
+ EA_CONSTEXPR auto MIN = eastl::numeric_limits<T>::min();
+ EA_CONSTEXPR auto MAX = eastl::numeric_limits<T>::max();
+
+ VERIFY(eastl::bit_floor(MAX) == T(1) << (DIGITS - 1));
+ VERIFY(eastl::bit_floor(MIN) == T(0));
+
+ for (int i = 4; i < eastl::numeric_limits<T>::digits; i++)
+ {
+ T power_of_two = static_cast<T>(T(1U) << i);
+ VERIFY(eastl::bit_floor(power_of_two) == power_of_two);
+ VERIFY(eastl::bit_floor(static_cast<T>(power_of_two + 1)) == power_of_two);
+ }
+ return nErrorCount;
+}
+
+template <typename T>
+static int TestBitWidth()
+{
+ int nErrorCount = 0;
+
+ VERIFY(eastl::bit_width(T(0)) == T(0));
+ VERIFY(eastl::bit_width(T(1)) == T(1));
+ VERIFY(eastl::bit_width(T(2)) == T(2));
+ VERIFY(eastl::bit_width(T(3)) == T(2));
+
+ EA_CONSTEXPR auto DIGITS = eastl::numeric_limits<T>::digits;
+ EA_CONSTEXPR auto MIN = eastl::numeric_limits<T>::min();
+ EA_CONSTEXPR auto MAX = eastl::numeric_limits<T>::max();
+
+ VERIFY(eastl::bit_width(MIN) == 0);
+ VERIFY(eastl::bit_width(MAX) == DIGITS);
+
+ for (int i = 4; i < eastl::numeric_limits<T>::digits; i++)
+ {
+ T power_of_two = static_cast<T>(T(1U) << i);
+ VERIFY(eastl::bit_width(power_of_two) == static_cast<T>(i + 1));
+ }
+
+ return nErrorCount;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// TestPowerofTwo
+//
+static int TestPowerOfTwo()
+{
+ int nErrorCount = 0;
+ nErrorCount += TestHasSingleBit<unsigned int>();
+ nErrorCount += TestHasSingleBit<unsigned char>();
+ nErrorCount += TestHasSingleBit<unsigned short>();
+ nErrorCount += TestHasSingleBit<unsigned long>();
+ nErrorCount += TestHasSingleBit<unsigned long long>();
+
+ nErrorCount += TestBitCeil<unsigned int>();
+ nErrorCount += TestBitCeil<unsigned char>();
+ nErrorCount += TestBitCeil<unsigned short>();
+ nErrorCount += TestBitCeil<unsigned long>();
+ nErrorCount += TestBitCeil<unsigned long long>();
+
+ nErrorCount += TestBitFloor<unsigned int>();
+ nErrorCount += TestBitFloor<unsigned char>();
+ nErrorCount += TestBitFloor<unsigned short>();
+ nErrorCount += TestBitFloor<unsigned long>();
+ nErrorCount += TestBitFloor<unsigned long long>();
+
+ nErrorCount += TestBitWidth<unsigned int>();
+ nErrorCount += TestBitWidth<unsigned char>();
+ nErrorCount += TestBitWidth<unsigned short>();
+ nErrorCount += TestBitWidth<unsigned long>();
+ nErrorCount += TestBitWidth<unsigned long long>();
+
+ return nErrorCount;
+}
+#endif
///////////////////////////////////////////////////////////////////////////////
// TestExtra
@@ -931,6 +1532,11 @@ int TestExtra()
nErrorCount += TestCallTraits();
nErrorCount += TestNumeric();
nErrorCount += TestAdaptors();
+#if defined(EA_COMPILER_CPP20_ENABLED)
+ nErrorCount += TestMidpoint();
+ nErrorCount += TestLerp();
+ nErrorCount += TestPowerOfTwo();
+#endif
return nErrorCount;
}
diff --git a/EASTL/test/source/TestFixedString.cpp b/EASTL/test/source/TestFixedString.cpp
index a7f7bd9..8528dc7 100644
--- a/EASTL/test/source/TestFixedString.cpp
+++ b/EASTL/test/source/TestFixedString.cpp
@@ -131,6 +131,58 @@ int TestFixedSubstring()
EATEST_VERIFY(str == "");
}
+
+ {
+ // Check that copies/moves don't become independent strings.
+ // They should all point to the same sub-string.
+ string str = "hello world";
+ fixed_substring<char> sub(str, 2, 5);
+
+ EATEST_VERIFY(sub.size() == 5);
+ EATEST_VERIFY(sub[0] == 'l');
+ EATEST_VERIFY(sub == "llo w");
+
+ vector<fixed_substring<char>> v;
+ for (eastl_size_t i = 0; i < 1000; ++i) {
+ v.push_back(sub);
+ }
+
+ sub[0] = 'g';
+ EATEST_VERIFY(str == "heglo world");
+ EATEST_VERIFY(sub == "glo w");
+
+ for (const auto& s : v){
+ EATEST_VERIFY(s == "glo w");
+ }
+
+ // copy construct
+ fixed_substring<char> sub2 = sub;
+
+ // copy assign
+ fixed_substring<char> sub3;
+ sub3 = sub;
+
+ // move construct
+ fixed_substring<char> sub4 = eastl::move(sub);
+
+ // move assign
+ fixed_substring<char> sub_again(str, 2, 5);
+ fixed_substring<char> sub5;
+ sub5 = eastl::move(sub_again);
+
+ EATEST_VERIFY(sub2 == "glo w");
+ EATEST_VERIFY(sub3 == "glo w");
+ EATEST_VERIFY(sub4 == "glo w");
+ EATEST_VERIFY(sub5 == "glo w");
+
+ str[5] = 'g';
+ EATEST_VERIFY(sub2 == "glogw");
+ EATEST_VERIFY(sub3 == "glogw");
+ EATEST_VERIFY(sub4 == "glogw");
+ EATEST_VERIFY(sub5 == "glogw");
+
+ }
+
return nErrorCount;
}
diff --git a/EASTL/test/source/TestFunctional.cpp b/EASTL/test/source/TestFunctional.cpp
index 63b3516..1e25200 100644
--- a/EASTL/test/source/TestFunctional.cpp
+++ b/EASTL/test/source/TestFunctional.cpp
@@ -1491,5 +1491,39 @@ struct TestInvokeResult
};
template struct eastl::invoke_result<decltype(&TestInvokeResult::f), TestInvokeResult, void>;
+
static_assert(!eastl::is_invocable<decltype(&TestInvokeResult::f), TestInvokeResult, void>::value, "incorrect value for is_invocable");
+static_assert(!eastl::is_invocable<decltype(&TestInvokeResult::f), TestInvokeResult, int, int>::value, "incorrect value for is_invocable");
static_assert(eastl::is_invocable<decltype(&TestInvokeResult::f), TestInvokeResult, int>::value, "incorrect value for is_invocable");
+
+static_assert(!eastl::is_invocable_r<int, decltype(&TestInvokeResult::f), TestInvokeResult, void>::value, "incorrect value for is_invocable_r");
+static_assert(!eastl::is_invocable_r<void, decltype(&TestInvokeResult::f), TestInvokeResult, int, int>::value, "incorrect value for is_invocable_r");
+static_assert(eastl::is_invocable_r<void, decltype(&TestInvokeResult::f), TestInvokeResult, int>::value, "incorrect value for is_invocable_r");
+static_assert(eastl::is_invocable_r<int, decltype(&TestInvokeResult::f), TestInvokeResult, int>::value, "incorrect value for is_invocable_r");
+
+struct TestCallableInvokeResult
+{
+ int operator()(int i) {return i;}
+};
+
+template struct eastl::invoke_result<TestCallableInvokeResult, void>;
+
+static_assert(!eastl::is_invocable<TestCallableInvokeResult, void>::value, "incorrect value for is_invocable");
+static_assert(!eastl::is_invocable<TestCallableInvokeResult, int, int>::value, "incorrect value for is_invocable");
+static_assert(eastl::is_invocable<TestCallableInvokeResult, int>::value, "incorrect value for is_invocable");
+
+static_assert(!eastl::is_invocable_r<int, TestCallableInvokeResult, void>::value, "incorrect value for is_invocable_r");
+static_assert(!eastl::is_invocable_r<void, TestCallableInvokeResult, int, int>::value, "incorrect value for is_invocable_r");
+static_assert(eastl::is_invocable_r<void, TestCallableInvokeResult, int>::value, "incorrect value for is_invocable_r");
+static_assert(eastl::is_invocable_r<int, TestCallableInvokeResult, int>::value, "incorrect value for is_invocable_r");
+
+typedef decltype(eastl::ref(eastl::declval<TestCallableInvokeResult&>())) TestCallableRefInvokeResult;
+
+static_assert(!eastl::is_invocable<TestCallableRefInvokeResult, void>::value, "incorrect value for is_invocable");
+static_assert(!eastl::is_invocable<TestCallableRefInvokeResult, int, int>::value, "incorrect value for is_invocable");
+static_assert(eastl::is_invocable<TestCallableRefInvokeResult, int>::value, "incorrect value for is_invocable");
+
+static_assert(!eastl::is_invocable_r<int, TestCallableRefInvokeResult, void>::value, "incorrect value for is_invocable_r");
+static_assert(!eastl::is_invocable_r<void, TestCallableRefInvokeResult, int, int>::value, "incorrect value for is_invocable_r");
+static_assert(eastl::is_invocable_r<void, TestCallableRefInvokeResult, int>::value, "incorrect value for is_invocable_r");
+static_assert(eastl::is_invocable_r<int, TestCallableRefInvokeResult, int>::value, "incorrect value for is_invocable_r");
diff --git a/EASTL/test/source/TestHash.cpp b/EASTL/test/source/TestHash.cpp
index 9c9bf9d..1bcf996 100644
--- a/EASTL/test/source/TestHash.cpp
+++ b/EASTL/test/source/TestHash.cpp
@@ -746,14 +746,16 @@ int TestHash()
{ // hash_set erase_if
hash_set<int> m = {0, 1, 2, 3, 4};
- eastl::erase_if(m, [](auto i) { return i % 2 == 0; });
+ auto numErased = eastl::erase_if(m, [](auto i) { return i % 2 == 0; });
VERIFY((m == hash_set<int>{1, 3}));
+ VERIFY(numErased == 3);
}
{ // hash_multiset erase_if
hash_multiset<int> m = {0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4};
- eastl::erase_if(m, [](auto i) { return i % 2 == 0; });
+ auto numErased = eastl::erase_if(m, [](auto i) { return i % 2 == 0; });
VERIFY((m == hash_multiset<int>{1, 1, 1, 3}));
+ VERIFY(numErased == 12);
}
@@ -943,15 +945,17 @@ int TestHash()
{ // hash_map erase_if
hash_map<int, int> m = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}};
- eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
+ auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
VERIFY((m == hash_map<int, int>{{1, 1}, {3, 3}}));
+ VERIFY(numErased == 3);
}
{ // hash_multimap erase_if
hash_multimap<int, int> m = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2},
{2, 2}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {4, 4}};
- eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
+ auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
VERIFY((m == hash_multimap<int, int>{{1, 1}, {3, 3}, {3, 3}}));
+ VERIFY(numErased == 9);
}
diff --git a/EASTL/test/source/TestIterator.cpp b/EASTL/test/source/TestIterator.cpp
index 02aa1d4..b6c6f76 100644
--- a/EASTL/test/source/TestIterator.cpp
+++ b/EASTL/test/source/TestIterator.cpp
@@ -4,6 +4,7 @@
#include "EASTLTest.h"
+#include <EASTL/deque.h>
#include <EASTL/iterator.h>
#include <EASTL/vector.h>
#include <EASTL/set.h>
@@ -21,6 +22,8 @@ EA_DISABLE_ALL_VC_WARNINGS()
#include <string.h>
EA_RESTORE_ALL_VC_WARNINGS()
+template <class T>
+using detect_iterator_traits_reference = typename eastl::iterator_traits<T>::reference;
// This is used below, though is currently disabled as documented below.
struct IListNode : public eastl::intrusive_list_node{};
@@ -181,7 +184,7 @@ int TestIterator_moveIterator()
// Check that we support iterators yielding plain value (typically a proxy-iterator).
struct FakeProxyIterator
{
- using iterator_category = eastl::forward_iterator_tag;
+ using iterator_category = EASTL_ITC_NS::forward_iterator_tag;
using difference_type = ptrdiff_t;
using value_type = int;
using pointer = int; // Note that we are yielding by value.
@@ -250,6 +253,34 @@ int TestIterator()
}
{
+ // Regression bug with assign/insert combined with reverse iterator.
+ eastl::vector<int> a;
+ for (int i = 0; i < 10; ++i) {
+ a.push_back(i);
+ }
+
+ eastl::deque<int> d;
+ d.assign(a.rbegin(), a.rend());
+ for (int i = 0; i < 10; ++i) {
+ EATEST_VERIFY(a[i] == d[a.size() - i - 1]);
+ }
+ d.insert(d.end(), a.rbegin(), a.rend());
+ for (int i = 0; i < 10; ++i) {
+ EATEST_VERIFY(a[i] == d[d.size() - i - 1]);
+ }
+
+ eastl::vector<int> b;
+ b.assign(a.rbegin(), a.rend());
+ for (int i = 0; i < 10; ++i) {
+ EATEST_VERIFY(a[i] == b[a.size() - i - 1]);
+ }
+ b.insert(b.end(), a.rbegin(), a.rend());
+ for (int i = 0; i < 10; ++i) {
+ EATEST_VERIFY(a[i] == b[b.size() - i - 1]);
+ }
+ }
+
+ {
// move_iterator
// move_iterator<Iterator> make_move_iterator(Iterator mi)
typedef eastl::vector<eastl::string> StringArray;
@@ -421,13 +452,17 @@ int TestIterator()
{
// is_iterator_wrapper
- static_assert((eastl::is_iterator_wrapper<void>::value == false), "is_iterator_wrapper failure");
- static_assert((eastl::is_iterator_wrapper<int>::value == false), "is_iterator_wrapper failure");
- static_assert((eastl::is_iterator_wrapper<int*>::value == false), "is_iterator_wrapper failure");
- static_assert((eastl::is_iterator_wrapper<eastl::array<char>*>::value == false), "is_iterator_wrapper failure");
- static_assert((eastl::is_iterator_wrapper<eastl::vector<char> >::value == false), "is_iterator_wrapper failure");
- static_assert((eastl::is_iterator_wrapper<eastl::generic_iterator<int*> >::value == true), "is_iterator_wrapper failure");
- static_assert((eastl::is_iterator_wrapper<eastl::move_iterator<eastl::array<int>::iterator> >::value == true), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<void>::value == false), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<int>::value == false), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<int*>::value == false), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<eastl::array<int>::iterator>::value == false), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<eastl::array<char>*>::value == false), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<eastl::vector<char> >::value == false), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<eastl::generic_iterator<int*> >::value == true), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<eastl::move_iterator<eastl::array<int>::iterator> >::value == true), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<eastl::reverse_iterator<eastl::array<int>::iterator> >::value == false), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<eastl::reverse_iterator<int*> >::value == false), "is_iterator_wrapper failure");
+ static_assert((eastl::is_iterator_wrapper<eastl::reverse_iterator<eastl::move_iterator<int*>> >::value == true), "is_iterator_wrapper failure");
}
@@ -455,6 +490,61 @@ int TestIterator()
intVector[0] = 20;
EATEST_VERIFY(*itVector == 20);
static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(miIntVector)), eastl::vector<int>::iterator>::value == true), "unwrap_iterator failure");
+
+ eastl::reverse_iterator<eastl::vector<int>::iterator> riIntVector = intVector.rbegin();
+ eastl::reverse_iterator<eastl::vector<int>::iterator> riUnwrapped = eastl::unwrap_iterator(riIntVector);
+ EATEST_VERIFY(*riUnwrapped == 19);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(riIntVector)), eastl::reverse_iterator<eastl::vector<int>::iterator>>::value == true), "unwrap_iterator failure");
+
+ eastl::reverse_iterator<eastl::move_iterator<eastl::vector<int>::iterator>> rimiIntVec(miIntVector);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(rimiIntVec)), eastl::reverse_iterator<eastl::vector<int>::iterator>>::value == true), "unwrap_iterator failure");
+
+ eastl::reverse_iterator<eastl::generic_iterator<int*>> rigiIntArray(giIntArray);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(rigiIntArray)), eastl::reverse_iterator<int*>>::value == true), "unwrap_iterator failure");
+
+ eastl::deque<int> intDeque(3);
+ eastl::deque<int>::iterator begin = intDeque.begin();
+ eastl::generic_iterator<eastl::deque<int>::iterator> giWrappedBegin(begin);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(giWrappedBegin)), eastl::deque<int>::iterator>::value == true), "unwrap_iterator failure");
+
+ eastl::deque<int>::iterator unwrappedBegin = eastl::unwrap_iterator(giWrappedBegin);
+ EATEST_VERIFY(begin == unwrappedBegin);
+ }
+
+ {
+ // unwrap_generic_iterator
+ int intArray[2] = {0, 1};
+ eastl::generic_iterator<int*> giIntArray(intArray);
+ int* pInt = eastl::unwrap_generic_iterator(giIntArray);
+ EATEST_VERIFY(*pInt == 0);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_generic_iterator(giIntArray)), int*>::value == true), "unwrap_iterator failure");
+
+ eastl::move_iterator<int*> miIntArray(intArray);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_generic_iterator(miIntArray)), eastl::move_iterator<int*>>::value == true), "unwrap_iterator failure");
+
+ eastl::vector<int> intVector(1, 1);
+ eastl::generic_iterator<eastl::vector<int>::iterator> giVectorInt(intVector.begin());
+ eastl::vector<int>::iterator it = unwrap_generic_iterator(giVectorInt);
+ EATEST_VERIFY(*it == 1);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_generic_iterator(giVectorInt)), eastl::vector<int>::iterator>::value == true), "unwrap_iterator failure");
+ }
+
+ {
+ // unwrap_move_iterator
+ int intArray[2] = {0, 1};
+ eastl::move_iterator<int*> miIntArray(intArray);
+ int* pInt = eastl::unwrap_move_iterator(miIntArray);
+ EATEST_VERIFY(*pInt == 0);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_move_iterator(miIntArray)), int*>::value == true), "unwrap_iterator failure");
+
+ eastl::generic_iterator<int*> giIntArray(intArray);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_move_iterator(giIntArray)), eastl::generic_iterator<int*>>::value == true), "unwrap_iterator failure");
+
+ eastl::vector<int> intVector(1, 1);
+ eastl::move_iterator<eastl::vector<int>::iterator> miVectorInt(intVector.begin());
+ eastl::vector<int>::iterator it = unwrap_move_iterator(miVectorInt);
+ EATEST_VERIFY(*it == 1);
+ static_assert((eastl::is_same<decltype(eastl::unwrap_move_iterator(miVectorInt)), eastl::vector<int>::iterator>::value == true), "unwrap_iterator failure");
}
{
@@ -468,6 +558,11 @@ int TestIterator()
EATEST_VERIFY(dist == 3);
}
+ {
+ // Regression test that ensure N3844 is working correctly.
+ static_assert(!eastl::is_detected<detect_iterator_traits_reference, int>::value, "detecting iterator_traits<int> should SFINAE gracefully.");
+ }
+
return nErrorCount;
}
diff --git a/EASTL/test/source/TestList.cpp b/EASTL/test/source/TestList.cpp
index 8a5e057..001b79a 100644
--- a/EASTL/test/source/TestList.cpp
+++ b/EASTL/test/source/TestList.cpp
@@ -975,20 +975,115 @@ int TestList()
{
eastl::list<int> l = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- eastl::erase(l, 3);
- eastl::erase(l, 5);
- eastl::erase(l, 7);
+ auto numErased = eastl::erase(l, 3);
+ VERIFY(numErased == 1);
+ numErased = eastl::erase(l, 5);
+ VERIFY(numErased == 1);
+ numErased = eastl::erase(l, 7);
+ VERIFY(numErased == 1);
VERIFY((l == eastl::list<int>{1, 2, 4, 6, 8, 9}));
}
{
eastl::list<int> l = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- eastl::erase_if(l, [](auto i) { return i % 2 == 0; });
+ auto numErased = eastl::erase_if(l, [](auto i) { return i % 2 == 0; });
VERIFY((l == eastl::list<int>{1, 3, 5, 7, 9}));
+ VERIFY(numErased == 4);
}
}
+ { // Test global operators
+ {
+ eastl::list<int> list1 = {0, 1, 2, 3, 4, 5};
+ eastl::list<int> list2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ eastl::list<int> list3 = {5, 6, 7, 8};
+
+ VERIFY(list1 == list1);
+ VERIFY(!(list1 != list1));
+
+ VERIFY(list1 != list2);
+ VERIFY(list2 != list3);
+ VERIFY(list1 != list3);
+
+ VERIFY(list1 < list2);
+ VERIFY(list1 <= list2);
+
+ VERIFY(list2 > list1);
+ VERIFY(list2 >= list1);
+
+ VERIFY(list3 > list1);
+ VERIFY(list3 > list2);
+ }
+
+ // three way comparison operator
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ eastl::list<int> list1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ eastl::list<int> list2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+ // Verify equality between list1 and list2
+ VERIFY((list1 <=> list2) == 0);
+ VERIFY(!((list1 <=> list2) != 0));
+ VERIFY((list1 <=> list2) <= 0);
+ VERIFY((list1 <=> list2) >= 0);
+ VERIFY(!((list1 <=> list2) < 0));
+ VERIFY(!((list1 <=> list2) > 0));
+
+ list1.push_back(100); // Make list1 less than list2.
+ list2.push_back(101);
+
+ // Verify list1 < list2
+ VERIFY(!((list1 <=> list2) == 0));
+ VERIFY((list1 <=> list2) != 0);
+ VERIFY((list1 <=> list2) <= 0);
+ VERIFY(!((list1 <=> list2) >= 0));
+ VERIFY(((list1 <=> list2) < 0));
+ VERIFY(!((list1 <=> list2) > 0));
+
+ for (int i = 0; i < 3; i++) // Make the length of list2 less than list1
+ list2.pop_back();
+
+ // Verify list2.size() < list1.size() and list2 is a subset of list1
+ VERIFY(!((list1 <=> list2) == 0));
+ VERIFY((list1 <=> list2) != 0);
+ VERIFY((list1 <=> list2) >= 0);
+ VERIFY(!((list1 <=> list2) <= 0));
+ VERIFY(((list1 <=> list2) > 0));
+ VERIFY(!((list1 <=> list2) < 0));
+ }
+
+ {
+ eastl::list<int> list1 = {1, 2, 3, 4, 5, 6, 7};
+ eastl::list<int> list2 = {7, 6, 5, 4, 3, 2, 1};
+ eastl::list<int> list3 = {1, 2, 3, 4};
+
+ struct weak_ordering_list
+ {
+ eastl::list<int> list;
+ inline std::weak_ordering operator<=>(const weak_ordering_list& b) const { return list <=> b.list; }
+ };
+
+ VERIFY(synth_three_way{}(weak_ordering_list{list1}, weak_ordering_list{list2}) == std::weak_ordering::less);
+ VERIFY(synth_three_way{}(weak_ordering_list{list3}, weak_ordering_list{list1}) == std::weak_ordering::less);
+ VERIFY(synth_three_way{}(weak_ordering_list{list2}, weak_ordering_list{list1}) == std::weak_ordering::greater);
+ VERIFY(synth_three_way{}(weak_ordering_list{list2}, weak_ordering_list{list3}) == std::weak_ordering::greater);
+ VERIFY(synth_three_way{}(weak_ordering_list{list1}, weak_ordering_list{list1}) == std::weak_ordering::equivalent);
+
+ struct strong_ordering_list
+ {
+ eastl::list<int> list;
+ inline std::strong_ordering operator<=>(const strong_ordering_list& b) const { return list <=> b.list; }
+ };
+
+ VERIFY(synth_three_way{}(strong_ordering_list{list1}, strong_ordering_list{list2}) == std::strong_ordering::less);
+ VERIFY(synth_three_way{}(strong_ordering_list{list3}, strong_ordering_list{list1}) == std::strong_ordering::less);
+ VERIFY(synth_three_way{}(strong_ordering_list{list2}, strong_ordering_list{list1}) == std::strong_ordering::greater);
+ VERIFY(synth_three_way{}(strong_ordering_list{list2}, strong_ordering_list{list3}) == std::strong_ordering::greater);
+ VERIFY(synth_three_way{}(strong_ordering_list{list1}, strong_ordering_list{list1}) == std::strong_ordering::equal);
+ }
+#endif
+ }
return nErrorCount;
}
diff --git a/EASTL/test/source/TestMap.cpp b/EASTL/test/source/TestMap.cpp
index e2eef2f..0df8c88 100644
--- a/EASTL/test/source/TestMap.cpp
+++ b/EASTL/test/source/TestMap.cpp
@@ -147,15 +147,23 @@ int TestMap()
{
typedef eastl::map<int, int> IntIntMap;
IntIntMap map1;
+ map1[1] = 1;
+ map1[3] = 3;
#if EASTL_EXCEPTIONS_ENABLED
EATEST_VERIFY_THROW(map1.at(0));
+ EATEST_VERIFY_THROW(map1.at(2));
+ EATEST_VERIFY_THROW(map1.at(4));
#endif
- map1[0]=1;
+ map1[0] = 1;
#if EASTL_EXCEPTIONS_ENABLED
EATEST_VERIFY_NOTHROW(map1.at(0));
+ EATEST_VERIFY_NOTHROW(map1.at(1));
+ EATEST_VERIFY_NOTHROW(map1.at(3));
#endif
EATEST_VERIFY(map1.at(0) == 1);
+ EATEST_VERIFY(map1.at(1) == 1);
+ EATEST_VERIFY(map1.at(3) == 3);
const IntIntMap map2;
const IntIntMap map3(map1);
@@ -223,16 +231,65 @@ int TestMap()
{ // Test erase_if
eastl::map<int, int> m = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}};
- eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
+ auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
VERIFY((m == eastl::map<int, int>{{1, 1},{3, 3}}));
+ VERIFY(numErased == 3);
}
{ // Test erase_if
eastl::multimap<int, int> m = {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}};
- eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
- VERIFY((m == eastl::multimap<int, int>{{1, 1}, {1, 1}, {3, 3}}));
+ auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
+ VERIFY((m == eastl::multimap<int, int>{{1, 1}, {1, 1}, {3, 3}}));;
+ VERIFY(numErased == 7);
}
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ { // Test map <=>
+ eastl::map<int, int> m1 = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}};
+ eastl::map<int, int> m2 = {{4, 4}, {3, 3}, {2, 2}, {1, 1}, {0, 0}};
+ eastl::map<int, int> m3 = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};
+ eastl::map<int, int> m4 = {{1, 0}, {3, 2}, {5, 4}, {7, 6}, {9, 8}};
+ eastl::map<int, int> m5 = {{0, 1}, {2, 3}, {4, 5}};
+
+ VERIFY(m1 == m2);
+ VERIFY(m1 != m3);
+ VERIFY(m3 != m4);
+ VERIFY(m3 < m4);
+ VERIFY(m5 < m4);
+ VERIFY(m5 < m3);
+
+
+ VERIFY((m1 <=> m2) == 0);
+ VERIFY((m1 <=> m3) != 0);
+ VERIFY((m3 <=> m4) != 0);
+ VERIFY((m3 <=> m4) < 0);
+ VERIFY((m5 <=> m4) < 0);
+ VERIFY((m5 <=> m3) < 0);
+ }
+
+ { // Test multimap <=>
+ eastl::multimap<int, int> m1 = {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {4, 4}, {4, 4}};
+ eastl::multimap<int, int> m2 = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {0, 0}};
+ eastl::multimap<int, int> m3 = {{0, 1}, {2, 3}, {4, 5}, {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};
+ eastl::multimap<int, int> m4 = {{1, 0}, {3, 2}, {5, 4}, {1, 0}, {3, 2}, {5, 4}, {7, 6}, {9, 8}};
+ eastl::multimap<int, int> m5 = {{10, 11}, {10, 11}};
+
+ VERIFY(m1 == m2);
+ VERIFY(m1 != m3);
+ VERIFY(m3 != m4);
+ VERIFY(m3 < m4);
+ VERIFY(m5 > m4);
+ VERIFY(m5 > m3);
+
+ VERIFY((m1 <=> m2) == 0);
+ VERIFY((m1 <=> m3) != 0);
+ VERIFY((m3 <=> m4) != 0);
+ VERIFY((m3 <=> m4) < 0);
+ VERIFY((m5 <=> m4) > 0);
+ VERIFY((m5 <=> m3) > 0);
+ }
+#endif
+
return nErrorCount;
}
diff --git a/EASTL/test/source/TestMap.h b/EASTL/test/source/TestMap.h
index 09353cd..8d480cf 100644
--- a/EASTL/test/source/TestMap.h
+++ b/EASTL/test/source/TestMap.h
@@ -1248,11 +1248,18 @@ int TestMapCpp17()
VERIFY(toMap.size() == 1);
}
+ auto ctorCount = TestObject::sTOCtorCount;
+
{ // verify duplicate not inserted
auto result = toMap.try_emplace(7, mapped_type(7)); // test fwding to copy-ctor
VERIFY(!result.second);
VERIFY(result.first->second == mapped_type(7));
VERIFY(toMap.size() == 1);
+
+ // we explicitly constructed an element for the parameter
+ // and one for the VERIFY check
+ ctorCount += 2;
+ VERIFY(ctorCount == TestObject::sTOCtorCount);
}
{ // verify duplicate not inserted
@@ -1261,6 +1268,9 @@ int TestMapCpp17()
VERIFY(result->first == 7);
VERIFY(result->second == mapped_type(7));
VERIFY(toMap.size() == 1);
+ // we explicitly constructed an element for the VERIFY check
+ ++ctorCount;
+ VERIFY(ctorCount == TestObject::sTOCtorCount);
}
{ // verify duplicate not inserted
@@ -1269,20 +1279,36 @@ int TestMapCpp17()
VERIFY(result->first == 7);
VERIFY(result->second == mapped_type(7));
VERIFY(toMap.size() == 1);
+
+ // we explicitly constructed an element for the parameter
+ // and one for the VERIFY check
+ ctorCount += 2;
+ VERIFY(ctorCount == TestObject::sTOCtorCount);
}
{
{
- auto result = toMap.try_emplace(8, 8);
+ auto result = toMap.try_emplace(8, 8);
+ // emplacing a new value should call exactly one constructor,
+ // when the value is constructed in place inside the container.
+ ++ctorCount;
VERIFY(result.second);
VERIFY(result.first->second == mapped_type(8));
+ // One more constructor for the temporary in the VERIFY
+ ++ctorCount;
VERIFY(toMap.size() == 2);
+ VERIFY(ctorCount == TestObject::sTOCtorCount);
}
{
- auto result = toMap.try_emplace(9, mapped_type(9));
+ auto result = toMap.try_emplace(9, mapped_type(9));
VERIFY(result.second);
VERIFY(result.first->second == mapped_type(9));
VERIFY(toMap.size() == 3);
+ // one more constructor for the temporary argument,
+ // one for moving it to the container, and one for the VERIFY
+ ctorCount += 3;
+ VERIFY(ctorCount == TestObject::sTOCtorCount);
+
}
}
}
diff --git a/EASTL/test/source/TestMemory.cpp b/EASTL/test/source/TestMemory.cpp
index 4e25738..77caf9f 100644
--- a/EASTL/test/source/TestMemory.cpp
+++ b/EASTL/test/source/TestMemory.cpp
@@ -133,6 +133,23 @@ eastl::late_constructed<LCTestObject, false, true> gLCTestObjectFalseTrue;
eastl::late_constructed<LCTestObject, false, false> gLCTestObjectFalseFalse;
eastl::late_constructed<LCTestObject, true, false> gLCTestObjectTrueFalse;
+struct TypeWithPointerTraits {};
+
+namespace eastl
+{
+ template <>
+ struct pointer_traits<TypeWithPointerTraits>
+ {
+ // Note: only parts of the traits we are interested to test are defined here.
+ static const int* to_address(TypeWithPointerTraits)
+ {
+ return &a;
+ }
+
+ inline static constexpr int a = 42;
+ };
+}
+
///////////////////////////////////////////////////////////////////////////////
// TestMemory
@@ -684,6 +701,33 @@ int TestMemory()
}
}
+ // to_address
+ {
+ // Normal pointers.
+ int a;
+ int* ptrA = &a;
+ EATEST_VERIFY(ptrA == to_address(ptrA));
+
+ // Smart pointer.
+ struct MockSmartPointer
+ {
+ const int* operator->() const
+ {
+ return &a;
+ }
+
+ int a = 42;
+ };
+
+ MockSmartPointer sp;
+ EATEST_VERIFY(&sp.a == to_address(sp));
+
+ // Type with specialized pointer_traits.
+ TypeWithPointerTraits t;
+ const int* result = to_address(t);
+ EATEST_VERIFY(result != nullptr && *result == 42);
+ }
+
{
// Test that align handles integral overflow correctly and returns NULL.
void* ptr;
diff --git a/EASTL/test/source/TestNumericLimits.cpp b/EASTL/test/source/TestNumericLimits.cpp
index 440715b..1964442 100644
--- a/EASTL/test/source/TestNumericLimits.cpp
+++ b/EASTL/test/source/TestNumericLimits.cpp
@@ -64,6 +64,11 @@ int TestNumericLimits()
EATEST_VERIFY(eastl::numeric_limits<wchar_t>::is_bounded);
EATEST_VERIFY(eastl::numeric_limits<wchar_t>::max() != 0);
+ #if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE
+ EATEST_VERIFY(eastl::numeric_limits<char8_t>::is_bounded);
+ EATEST_VERIFY(eastl::numeric_limits<char8_t>::max() != 0);
+ #endif
+
EATEST_VERIFY(eastl::numeric_limits<char16_t>::is_bounded);
EATEST_VERIFY(eastl::numeric_limits<char16_t>::max() != 0);
diff --git a/EASTL/test/source/TestOptional.cpp b/EASTL/test/source/TestOptional.cpp
index b4934a7..36307ad 100644
--- a/EASTL/test/source/TestOptional.cpp
+++ b/EASTL/test/source/TestOptional.cpp
@@ -18,12 +18,17 @@ struct IntStruct
int data;
};
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+auto operator<=>(const IntStruct& lhs, const IntStruct& rhs) { return lhs.data <=> rhs.data; }
+#else
bool operator<(const IntStruct& lhs, const IntStruct& rhs)
{ return lhs.data < rhs.data; }
+#endif
bool operator==(const IntStruct& lhs, const IntStruct& rhs)
{ return lhs.data == rhs.data; }
+
/////////////////////////////////////////////////////////////////////////////
struct destructor_test
{
@@ -476,6 +481,43 @@ int TestOptional()
VERIFY(o >= nullopt);
}
+ #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ optional<IntStruct> o(in_place, 10);
+ optional<IntStruct> e;
+
+ VERIFY((o <=> IntStruct(42)) < 0);
+ VERIFY((o <=> IntStruct(2)) >= 0);
+ VERIFY((o <=> IntStruct(10)) >= 0);
+ VERIFY((e <=> o) < 0);
+ VERIFY((e <=> IntStruct(10)) < 0);
+
+ VERIFY((o <=> IntStruct(4)) > 0);
+ VERIFY(o <=> IntStruct(42) <= 0);
+
+ VERIFY((o <=> IntStruct(4)) >= 0);
+ VERIFY((o <=> IntStruct(10)) >= 0);
+ VERIFY((IntStruct(4) <=> o) <= 0);
+ VERIFY((IntStruct(10) <=> o) <= 0);
+
+ VERIFY((o <=> IntStruct(10)) == 0);
+ VERIFY((o->data <=> IntStruct(10).data) == 0);
+
+ VERIFY((o <=> IntStruct(11)) != 0);
+ VERIFY((o->data <=> IntStruct(11).data) != 0);
+
+ VERIFY((e <=> nullopt) == 0);
+ VERIFY((nullopt <=> e) == 0);
+
+ VERIFY((o <=> nullopt) != 0);
+ VERIFY((nullopt <=> o) != 0);
+ VERIFY((nullopt <=> o) < 0);
+ VERIFY((o <=> nullopt) > 0);
+ VERIFY((nullopt <=> o) <= 0);
+ VERIFY((o <=> nullopt) >= 0);
+ }
+ #endif
+
// hash
{
{
diff --git a/EASTL/test/source/TestSList.cpp b/EASTL/test/source/TestSList.cpp
index d73f2bc..94a4d3a 100644
--- a/EASTL/test/source/TestSList.cpp
+++ b/EASTL/test/source/TestSList.cpp
@@ -795,36 +795,134 @@ int TestSList()
{
slist<int> l = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- eastl::erase(l, 5);
+ auto numErased = eastl::erase(l, 5);
VERIFY((l == slist<int>{0, 1, 2, 3, 4, 6, 7, 8, 9}));
+ VERIFY(numErased == 1);
- eastl::erase(l, 7);
+ numErased = eastl::erase(l, 7);
VERIFY((l == slist<int>{0, 1, 2, 3, 4, 6, 8, 9}));
+ VERIFY(numErased == 1);
- eastl::erase(l, 2);
+ numErased = eastl::erase(l, 2);
VERIFY((l == slist<int>{0, 1, 3, 4, 6, 8, 9}));
+ VERIFY(numErased == 1);
- eastl::erase(l, 0);
+ numErased = eastl::erase(l, 0);
VERIFY((l == slist<int>{1, 3, 4, 6, 8, 9}));
+ VERIFY(numErased == 1);
- eastl::erase(l, 4);
+ numErased = eastl::erase(l, 4);
VERIFY((l == slist<int>{1, 3, 6, 8, 9}));
+ VERIFY(numErased == 1);
}
{
slist<int> l = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- eastl::erase_if(l, [](auto e) { return e % 2 == 0; });
+ auto numErased = eastl::erase_if(l, [](auto e) { return e % 2 == 0; });
VERIFY((l == slist<int>{1, 3, 5, 7, 9}));
+ VERIFY(numErased == 5);
- eastl::erase_if(l, [](auto e) { return e == 5; });
+ numErased = eastl::erase_if(l, [](auto e) { return e == 5; });
VERIFY((l == slist<int>{1, 3, 7, 9}));
+ VERIFY(numErased == 1);
- eastl::erase_if(l, [](auto e) { return e % 3 == 0; });
+ numErased = eastl::erase_if(l, [](auto e) { return e % 3 == 0; });
VERIFY((l == slist<int>{1, 7}));
+ VERIFY(numErased == 2);
}
}
+ { // Test global operators
+ {
+ slist<int> list1 = {0, 1, 2, 3, 4, 5};
+ slist<int> list2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ slist<int> list3 = {5, 6, 7, 8};
+
+ VERIFY(list1 == list1);
+ VERIFY(!(list1 != list1));
+
+ VERIFY(list1 != list2);
+ VERIFY(list2 != list3);
+ VERIFY(list1 != list3);
+
+ VERIFY(list1 < list2);
+ VERIFY(list1 <= list2);
+
+ VERIFY(list2 > list1);
+ VERIFY(list2 >= list1);
+
+ VERIFY(list3 > list1);
+ VERIFY(list3 > list2);
+ }
+
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ slist<int> list1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ slist<int> list2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ slist<int> list3 = {-1, 0, 1, 2, 3, 4, 5};
+
+ // Verify equality between list1 and list2
+ VERIFY((list1 <=> list2) == 0);
+ VERIFY(!((list1 <=> list2) != 0));
+ VERIFY((list1 <=> list2) <= 0);
+ VERIFY((list1 <=> list2) >= 0);
+ VERIFY(!((list1 <=> list2) < 0));
+ VERIFY(!((list1 <=> list2) > 0));
+
+ list1.push_front(-2); // Make list1 less than list2.
+ list2.push_front(-1);
+
+ // Verify list1 < list2
+ VERIFY(!((list1 <=> list2) == 0));
+ VERIFY((list1 <=> list2) != 0);
+ VERIFY((list1 <=> list2) <= 0);
+ VERIFY(!((list1 <=> list2) >= 0));
+ VERIFY(((list1 <=> list2) < 0));
+ VERIFY(!((list1 <=> list2) > 0));
+
+
+ // Verify list3.size() < list2.size() and list3 is a subset of list2
+ VERIFY(!((list3 <=> list2) == 0));
+ VERIFY((list3 <=> list2) != 0);
+ VERIFY((list3 <=> list2) <= 0);
+ VERIFY(!((list3 <=> list2) >= 0));
+ VERIFY(((list3 <=> list2) < 0));
+ VERIFY(!((list3 <=> list2) > 0));
+ }
+
+ {
+ slist<int> list1 = {1, 2, 3, 4, 5, 6, 7};
+ slist<int> list2 = {7, 6, 5, 4, 3, 2, 1};
+ slist<int> list3 = {1, 2, 3, 4};
+
+ struct weak_ordering_slist
+ {
+ slist<int> slist;
+ inline std::weak_ordering operator<=>(const weak_ordering_slist& b) const { return slist <=> b.slist; }
+ };
+
+ VERIFY(synth_three_way{}(weak_ordering_slist{list1}, weak_ordering_slist{list2}) == std::weak_ordering::less);
+ VERIFY(synth_three_way{}(weak_ordering_slist{list3}, weak_ordering_slist{list1}) == std::weak_ordering::less);
+ VERIFY(synth_three_way{}(weak_ordering_slist{list2}, weak_ordering_slist{list1}) == std::weak_ordering::greater);
+ VERIFY(synth_three_way{}(weak_ordering_slist{list2}, weak_ordering_slist{list3}) == std::weak_ordering::greater);
+ VERIFY(synth_three_way{}(weak_ordering_slist{list1}, weak_ordering_slist{list1}) == std::weak_ordering::equivalent);
+
+ struct strong_ordering_slist
+ {
+ slist<int> slist;
+ inline std::strong_ordering operator<=>(const strong_ordering_slist& b) const { return slist <=> b.slist; }
+ };
+
+ VERIFY(synth_three_way{}(strong_ordering_slist{list1}, strong_ordering_slist{list2}) == std::strong_ordering::less);
+ VERIFY(synth_three_way{}(strong_ordering_slist{list3}, strong_ordering_slist{list1}) == std::strong_ordering::less);
+ VERIFY(synth_three_way{}(strong_ordering_slist{list2}, strong_ordering_slist{list1}) == std::strong_ordering::greater);
+ VERIFY(synth_three_way{}(strong_ordering_slist{list2}, strong_ordering_slist{list3}) == std::strong_ordering::greater);
+ VERIFY(synth_three_way{}(strong_ordering_slist{list1}, strong_ordering_slist{list1}) == std::strong_ordering::equal);
+ }
+#endif
+ }
+
return nErrorCount;
}
diff --git a/EASTL/test/source/TestSet.cpp b/EASTL/test/source/TestSet.cpp
index 1adc12f..9a590c2 100644
--- a/EASTL/test/source/TestSet.cpp
+++ b/EASTL/test/source/TestSet.cpp
@@ -162,16 +162,60 @@ int TestSet()
{ // set erase_if tests
set<int> s = {0, 1, 2, 3, 4};
- eastl::erase_if(s, [](auto i) { return i % 2 == 0;});
+ auto numErased = eastl::erase_if(s, [](auto i) { return i % 2 == 0;});
VERIFY((s == set<int>{1,3}));
+ VERIFY(numErased == 3);
}
{ // multiset erase_if tests
multiset<int> s = {0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4};
- eastl::erase_if(s, [](auto i) { return i % 2 == 0;});
+ auto numErased = eastl::erase_if(s, [](auto i) { return i % 2 == 0;});
VERIFY((s == multiset<int>{1, 1, 1, 3, 3, 3}));
+ VERIFY(numErased == 7);
}
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ { // Test set <=>
+ set<int> s1 = {0, 1, 2, 3, 4};
+ set<int> s2 = {4, 3, 2, 1, 0};
+ set<int> s3 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ set<int> s4 = {1, 2, 3, 4, 5, 6};
+ set<int> s5 = {9};
+
+ VERIFY(s1 == s2);
+ VERIFY(s1 != s3);
+ VERIFY(s3 > s4);
+ VERIFY(s5 > s4);
+ VERIFY(s5 > s3);
+
+ VERIFY((s1 <=> s2) == 0);
+ VERIFY((s1 <=> s3) != 0);
+ VERIFY((s3 <=> s4) > 0);
+ VERIFY((s5 <=> s4) > 0);
+ VERIFY((s5 <=> s3) > 0);
+ }
+
+ { // Test multiset <=>
+ multiset<int> s1 = {0, 0, 0, 1, 1, 2, 3, 3, 4};
+ multiset<int> s2 = {4, 3, 3, 2, 1, 1, 0, 0, 0};
+ multiset<int> s3 = {1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9};
+ multiset<int> s4 = {1, 1, 2, 2, 3, 4, 5, 5, 6};
+ multiset<int> s5 = {9};
+
+ VERIFY(s1 == s2);
+ VERIFY(s1 != s3);
+ VERIFY(s3 > s4);
+ VERIFY(s5 > s4);
+ VERIFY(s5 > s3);
+
+ VERIFY((s1 <=> s2) == 0);
+ VERIFY((s1 <=> s3) != 0);
+ VERIFY((s3 <=> s4) > 0);
+ VERIFY((s5 <=> s4) > 0);
+ VERIFY((s5 <=> s3) > 0);
+ }
+#endif
+
{
// user reported regression: ensure container elements are NOT
// moved from during the eastl::set construction process.
diff --git a/EASTL/test/source/TestSmartPtr.cpp b/EASTL/test/source/TestSmartPtr.cpp
index dc94b96..8052392 100644
--- a/EASTL/test/source/TestSmartPtr.cpp
+++ b/EASTL/test/source/TestSmartPtr.cpp
@@ -8,6 +8,7 @@
#include "GetTypeName.h"
#include <EAStdC/EAString.h>
#include <EAStdC/EAStopwatch.h>
+#include <EASTL/atomic.h>
#include <EASTL/core_allocator_adapter.h>
#include <EASTL/core_allocator.h>
#include <EASTL/intrusive_ptr.h>
@@ -800,6 +801,38 @@ static int Test_unique_ptr()
}
#endif
+ #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ unique_ptr<int> pT1(new int(5));
+ unique_ptr<int> pT2(new int(10));
+ unique_ptr<int> pT3(new int(0));
+
+ EATEST_VERIFY((pT1 <=> pT2) != 0);
+ EATEST_VERIFY((pT2 <=> pT1) != 0);
+
+ EATEST_VERIFY((pT1 <=> pT2) < 0);
+ EATEST_VERIFY((pT1 <=> pT2) <= 0);
+ EATEST_VERIFY((pT2 <=> pT1) > 0);
+ EATEST_VERIFY((pT2 <=> pT1) >= 0);
+
+ EATEST_VERIFY((pT3 <=> pT1) < 0);
+ EATEST_VERIFY((pT3 <=> pT2) < 0);
+ EATEST_VERIFY((pT1 <=> pT3) > 0);
+ EATEST_VERIFY((pT2 <=> pT3) > 0);
+
+ unique_ptr<A> pT4(new A(5));
+ unique_ptr<A> pT5(new A(10));
+
+ EATEST_VERIFY((pT4 <=> pT5) != 0);
+ EATEST_VERIFY((pT5 <=> pT4) != 0);
+
+ EATEST_VERIFY((pT4 <=> pT5) < 0);
+ EATEST_VERIFY((pT4 <=> pT5) <= 0);
+ EATEST_VERIFY((pT5 <=> pT4) > 0);
+ EATEST_VERIFY((pT5 <=> pT4) >= 0);
+ }
+ #endif
+
// ToDo: Test move assignment between two convertible types with an is_assignable deleter_type
//{
// struct Base {};
@@ -1351,7 +1384,7 @@ static int Test_shared_ptr()
{
EA::Thread::ThreadParameters mThreadParams;
EA::Thread::Thread mThread;
- volatile bool mbShouldContinue;
+ eastl::atomic<bool> mbShouldContinue;
int mnErrorCount;
eastl::shared_ptr<TestObject>* mpSPTO;
eastl::weak_ptr<TestObject>* mpWPTO;
@@ -1364,7 +1397,7 @@ static int Test_shared_ptr()
{
int& nErrorCount = mnErrorCount; // declare nErrorCount so that EATEST_VERIFY can work, as it depends on it being declared.
- while(mbShouldContinue)
+ while(mbShouldContinue.load(eastl::memory_order_relaxed))
{
EA::UnitTest::ThreadSleepRandom(1, 10);
@@ -1419,7 +1452,7 @@ static int Test_shared_ptr_thread()
EA::UnitTest::ThreadSleep(2000);
for(size_t i = 0; i < EAArrayCount(thread); i++)
- thread[i].mbShouldContinue = false;
+ thread[i].mbShouldContinue.store(false, eastl::memory_order_relaxed);
for(size_t i = 0; i < EAArrayCount(thread); i++)
{
diff --git a/EASTL/test/source/TestSort.cpp b/EASTL/test/source/TestSort.cpp
index 2d0116f..114a73b 100644
--- a/EASTL/test/source/TestSort.cpp
+++ b/EASTL/test/source/TestSort.cpp
@@ -177,8 +177,22 @@ namespace eastl
return x;
}
};
+
+ struct TestNoLessOperator
+ {
+ int i {};
+ };
} // namespace Internal
+ template <>
+ struct less<Internal::TestNoLessOperator>
+ {
+ bool operator()(const Internal::TestNoLessOperator& lhs, const Internal::TestNoLessOperator& rhs) const noexcept
+ {
+ return lhs.i < rhs.i;
+ }
+ };
+
} // namespace eastl
int TestSort()
@@ -630,6 +644,13 @@ int TestSort()
radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>>(begin(input), end(input), buffer);
EATEST_VERIFY(is_sorted(begin(input), end(input)));
}
+ {
+ // Test case for bug where the last histogram bucket was not being cleared to zero
+ uint32_t input[] = { 0xff00, 0xff };
+ uint32_t buffer[EAArrayCount(input)];
+ radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>>(begin(input), end(input), buffer);
+ EATEST_VERIFY(is_sorted(begin(input), end(input)));
+ }
}
{
@@ -793,7 +814,7 @@ int TestSort()
}
{
- // EATEST_VERIFY deque sorting can compile.
+ // Test checking that deque sorting can compile.
deque<int> intDeque;
vector<int> intVector;
@@ -801,6 +822,25 @@ int TestSort()
stable_sort(intVector.begin(), intVector.end());
}
+ {
+ // Test checking that sorting containers having elements of a type without an operator< compiles correctly
+
+ vector<TestNoLessOperator> noLessVector;
+
+ stable_sort(noLessVector.begin(), noLessVector.end());
+ bubble_sort(noLessVector.begin(), noLessVector.end());
+ shaker_sort(noLessVector.begin(), noLessVector.end());
+ insertion_sort(noLessVector.begin(), noLessVector.end());
+ selection_sort(noLessVector.begin(), noLessVector.end());
+ shell_sort(noLessVector.begin(), noLessVector.end());
+ comb_sort(noLessVector.begin(), noLessVector.end());
+ heap_sort(noLessVector.begin(), noLessVector.end());
+ merge_sort(noLessVector.begin(), noLessVector.end(), *get_default_allocator(nullptr));
+ quick_sort(noLessVector.begin(), noLessVector.end());
+
+ vector<TestNoLessOperator> buffer;
+ tim_sort_buffer(noLessVector.begin(), noLessVector.end(), buffer.data());
+}
{
// Test sorting of a container of pointers to objects as opposed to a container of objects themselves.
diff --git a/EASTL/test/source/TestString.inl b/EASTL/test/source/TestString.inl
index 08fb924..3a59e68 100644
--- a/EASTL/test/source/TestString.inl
+++ b/EASTL/test/source/TestString.inl
@@ -2024,19 +2024,25 @@ int TEST_STRING_NAME()
// test eastl::erase
{
StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz"));
- eastl::erase(str, LITERAL('a'));
- eastl::erase(str, LITERAL('f'));
- eastl::erase(str, LITERAL('l'));
- eastl::erase(str, LITERAL('w'));
- eastl::erase(str, LITERAL('y'));
+ auto numErased = eastl::erase(str, LITERAL('a'));
+ VERIFY(numErased == 1);
+ numErased = eastl::erase(str, LITERAL('f'));
+ VERIFY(numErased == 1);
+ numErased = eastl::erase(str, LITERAL('l'));
+ VERIFY(numErased == 1);
+ numErased = eastl::erase(str, LITERAL('w'));
+ VERIFY(numErased == 1);
+ numErased = eastl::erase(str, LITERAL('y'));
+ VERIFY(numErased == 1);
VERIFY(str == LITERAL("bcdeghijkmnopqrstuvxz"));
}
// test eastl::erase_if
{
StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz"));
- eastl::erase_if(str, [](auto c) { return c == LITERAL('a') || c == LITERAL('v'); });
+ auto numErased = eastl::erase_if(str, [](auto c) { return c == LITERAL('a') || c == LITERAL('v'); });
VERIFY(str == LITERAL("bcdefghijklmnopqrstuwxyz"));
+ VERIFY(numErased == 2);
}
// template<> struct hash<eastl::string>;
@@ -2064,6 +2070,28 @@ int TEST_STRING_NAME()
VERIFY(LocalHash(sw2) == LocalHash(sw3));
}
+ // test <=> operator
+ #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ StringType sw1(LITERAL("Test String "));
+ StringType sw2(LITERAL("Test String 1"));
+ StringType sw3(LITERAL("Test String 2"));
+ StringType sw4(LITERAL("abcdef"));
+
+ VERIFY((sw1 <=> sw2) != 0);
+ VERIFY((sw1 <=> sw3) != 0);
+ VERIFY((sw2 <=> sw3) != 0);
+ VERIFY((sw1 <=> sw2) < 0);
+ VERIFY((sw1 <=> sw3) < 0);
+ VERIFY((sw2 <=> sw2) == 0);
+ VERIFY((sw2 <=> sw3) < 0);
+ VERIFY((sw2 <=> sw4) < 0);
+ VERIFY((sw4 <=> sw2) > 0);
+ VERIFY((sw4 <=> sw3) > 0);
+ VERIFY((sw3 <=> sw2) > 0);
+ }
+ #endif
+
return nErrorCount;
}
diff --git a/EASTL/test/source/TestStringView.cpp b/EASTL/test/source/TestStringView.cpp
index 835488c..23e6e51 100644
--- a/EASTL/test/source/TestStringView.cpp
+++ b/EASTL/test/source/TestStringView.cpp
@@ -5,6 +5,7 @@
#include "EASTLTest.h"
#include <EABase/eabase.h>
#include <EASTL/numeric_limits.h>
+#include <EASTL/string.h>
#include <EASTL/string_view.h>
// Verify char8_t support is present if the test build requested it.
@@ -78,12 +79,18 @@ int TestStringView()
static_assert(eastl::is_same_v<decltype(U"abcdef"_sv), eastl::u32string_view>, "string_view literal type mismatch");
static_assert(eastl::is_same_v<decltype(L"abcdef"_sv), eastl::wstring_view>, "string_view literal type mismatch");
- // TODO: Need to resolve this. Not sure why on Clang the user literal 'operator ""sv' can't be found.
- // VERIFY("cplusplus"sv.compare("cplusplus") == 0);
- // VERIFY(L"cplusplus"sv.compare(L"cplusplus") == 0);
- // VERIFY(u"cplusplus"sv.compare(u"cplusplus") == 0);
- // VERIFY(U"cplusplus"sv.compare(U"cplusplus") == 0);
- // VERIFY(u8"cplusplus"sv.compare(u8"cplusplus") == 0);
+
+ VERIFY("cplusplus"sv.compare("cplusplus") == 0);
+ VERIFY(L"cplusplus"sv.compare(L"cplusplus") == 0);
+ VERIFY(u"cplusplus"sv.compare(u"cplusplus") == 0);
+ VERIFY(U"cplusplus"sv.compare(U"cplusplus") == 0);
+ VERIFY(u8"cplusplus"sv.compare(u8"cplusplus") == 0);
+
+ static_assert(eastl::is_same_v<decltype("abcdef"sv), eastl::string_view>, "string_view literal type mismatch");
+ static_assert(eastl::is_same_v<decltype(u8"abcdef"sv), eastl::u8string_view>, "string_view literal type mismatch");
+ static_assert(eastl::is_same_v<decltype(u"abcdef"sv), eastl::u16string_view>, "string_view literal type mismatch");
+ static_assert(eastl::is_same_v<decltype(U"abcdef"sv), eastl::u32string_view>, "string_view literal type mismatch");
+ static_assert(eastl::is_same_v<decltype(L"abcdef"sv), eastl::wstring_view>, "string_view literal type mismatch");
}
#endif
diff --git a/EASTL/test/source/TestStringView.inl b/EASTL/test/source/TestStringView.inl
index 14472fb..cd4214e 100644
--- a/EASTL/test/source/TestStringView.inl
+++ b/EASTL/test/source/TestStringView.inl
@@ -5,6 +5,8 @@
template<typename StringViewT>
int TEST_STRING_NAME()
{
+ using StringT = eastl::basic_string<typename StringViewT::value_type>;
+
int nErrorCount = 0;
{
// EA_CONSTEXPR basic_string_view()
@@ -476,6 +478,84 @@ int TEST_STRING_NAME()
VERIFY(sw1 <= sw2);
VERIFY(sw2 > sw1);
VERIFY(sw2 >= sw1);
+
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ VERIFY((sw1 <=> StringViewT(LITERAL("AAAAABBBBBCCCDDDDDEEEEEFFFGGH"))) == 0);
+ VERIFY((sw1 <=> StringViewT(LITERAL("abcdefghijklmnopqrstuvwxyz"))) != 0);
+ VERIFY((sw1 <=> sw2) < 0);
+ VERIFY((sw1 <=> sw2) <= 0);
+ VERIFY((sw2 <=> sw1) > 0);
+ VERIFY((sw2 <=> sw1) >= 0);
+#endif
+ }
+
+ {
+ auto s = LITERAL("Hello, World");
+ StringViewT sv(s);
+
+ VERIFY(s == sv);
+ VERIFY(sv == s);
+
+ VERIFY(s <= sv);
+ VERIFY(sv <= s);
+ VERIFY(s >= sv);
+ VERIFY(sv >= s);
+ VERIFY(!(s != sv));
+ VERIFY(!(sv != s));
+ VERIFY(!(s < sv));
+ VERIFY(!(sv < s));
+ VERIFY(!(s > sv));
+ VERIFY(!(sv > s));
+
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ VERIFY((s <=> sv) == 0);
+ VERIFY((sv <=> s) == 0);
+
+ VERIFY((s <=> sv) <= 0);
+ VERIFY((sv <=> s) <= 0);
+ VERIFY((s <=> sv) >= 0);
+ VERIFY((sv <=> s) >= 0);
+ VERIFY(!((s <=> sv) != 0));
+ VERIFY(!((sv <=> s) != 0));
+ VERIFY(!((s <=> sv) > 0));
+ VERIFY(!((sv <=> s) < 0));
+#endif
+ }
+
+ // Regression comparison operators should work between basic_string_view and basic_string.
+ // The idea is that type_identity_t on some overloads will force basic_string::operator basic_string_view() to kick in.
+ {
+ StringT s(LITERAL("Hello, Stockholm"));
+ StringViewT sv(s);
+
+ VERIFY(s == sv);
+ VERIFY(sv == s);
+
+ // All the operators bellow used to not work.
+ VERIFY(s <= sv);
+ VERIFY(sv <= s);
+ VERIFY(s >= sv);
+ VERIFY(sv >= s);
+ VERIFY(!(s != sv));
+ VERIFY(!(sv != s));
+ VERIFY(!(s < sv));
+ VERIFY(!(sv < s));
+ VERIFY(!(s > sv));
+ VERIFY(!(sv > s));
+
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ VERIFY((s <=> sv) == 0);
+ VERIFY((sv <=> s) == 0);
+
+ VERIFY((s <=> sv) <= 0);
+ VERIFY((sv <=> s) <= 0);
+ VERIFY((s <=> sv) >= 0);
+ VERIFY((sv <=> s) >= 0);
+ VERIFY(!((s <=> sv) != 0));
+ VERIFY(!((sv <=> s) != 0));
+ VERIFY(!((s <=> sv) > 0));
+ VERIFY(!((sv <=> s) < 0));
+#endif
}
// template<> struct hash<std::string_view>;
diff --git a/EASTL/test/source/TestTuple.cpp b/EASTL/test/source/TestTuple.cpp
index 8c1b48a..6a7647e 100644
--- a/EASTL/test/source/TestTuple.cpp
+++ b/EASTL/test/source/TestTuple.cpp
@@ -227,11 +227,27 @@ int TestTuple()
EATEST_VERIFY(aTuple != aDefaultInitTuple);
EATEST_VERIFY(aDefaultInitTuple < aTuple);
+ #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ EATEST_VERIFY((aTuple <=> anotherTuple) == 0);
+ EATEST_VERIFY((aTuple <=> anotherTuple) >= 0);
+ EATEST_VERIFY((anotherTuple <=> aTuple) >= 0);
+ EATEST_VERIFY((aTuple <=> aDefaultInitTuple) != 0);
+ EATEST_VERIFY((aDefaultInitTuple <=> aTuple) < 0);
+ #endif
+
tuple<int, int, int> lesserTuple(1, 2, 3);
tuple<int, int, int> greaterTuple(1, 2, 4);
EATEST_VERIFY(lesserTuple < greaterTuple && !(greaterTuple < lesserTuple) && greaterTuple > lesserTuple &&
!(lesserTuple > greaterTuple));
+ #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ EATEST_VERIFY((lesserTuple <=> greaterTuple) != 0);
+ EATEST_VERIFY((lesserTuple <=> greaterTuple) < 0);
+ EATEST_VERIFY((lesserTuple <=> greaterTuple) <= 0);
+ EATEST_VERIFY((greaterTuple <=> lesserTuple) > 0);
+ EATEST_VERIFY((greaterTuple <=> lesserTuple) >= 0);
+ #endif
+
tuple<int, float, TestObject> valTup(2, 2.0f, TestObject(2));
tuple<int&, float&, TestObject&> refTup(valTup);
tuple<const int&, const float&, const TestObject&> constRefTup(valTup);
@@ -272,6 +288,20 @@ int TestTuple()
}
{
+ // Test construction of tuple containing r-value references
+ int x = 42;
+ TestObject object{1337};
+
+ tuple<int&&, TestObject&&> aTupleWithRValueReference(eastl::move(x), eastl::move(object));
+ static_assert(is_same<decltype(get<0>(aTupleWithRValueReference)), int&>::value, "wrong return type for get when using r-value reference.");
+ static_assert(is_same<decltype(get<1>(aTupleWithRValueReference)), TestObject&>::value, "wrong return type for get when using r-value reference.");
+ EATEST_VERIFY(get<0>(aTupleWithRValueReference) == 42);
+ EATEST_VERIFY(get<1>(aTupleWithRValueReference).mX == 1337);
+
+ static_assert(!is_constructible<decltype(aTupleWithRValueReference), int&, TestObject&>::value, "it shouldn't be possible to assign r-value references with l-values.");
+ }
+
+ {
// Tuple helpers
// make_tuple
@@ -481,6 +511,27 @@ int TestTuple()
#endif
}
+ // Compilation test to make sure that we can handle reference to forward-declared types
+ {
+ struct ForwardDeclared;
+
+ auto fill_tuple = [](ForwardDeclared& f) {
+ eastl::tuple<ForwardDeclared&, const ForwardDeclared&> t{f, f};
+ return t;
+ };
+
+ struct ForwardDeclared
+ {
+ int x;
+ };
+
+ ForwardDeclared f{666};
+ auto t = fill_tuple(f);
+
+ EATEST_VERIFY(get<0>(t).x == 666);
+ EATEST_VERIFY(get<1>(t).x == 666);
+ }
+
#ifndef EA_COMPILER_NO_STRUCTURED_BINDING
// tuple structured bindings test
{
diff --git a/EASTL/test/source/TestTypeTraits.cpp b/EASTL/test/source/TestTypeTraits.cpp
index 0353be9..2670e24 100644
--- a/EASTL/test/source/TestTypeTraits.cpp
+++ b/EASTL/test/source/TestTypeTraits.cpp
@@ -173,15 +173,16 @@ struct NonPod2
virtual void Function(){}
};
-#if EASTL_VARIABLE_TEMPLATES_ENABLED
- struct HasIncrementOperator { HasIncrementOperator& operator++() { return *this; } };
+struct HasIncrementOperator { HasIncrementOperator& operator++() { return *this; } };
- template<typename, typename = eastl::void_t<>>
- struct has_increment_operator : eastl::false_type {};
+template <class T>
+using has_increment_operator_detection = decltype(++eastl::declval<T>());
- template <typename T>
- struct has_increment_operator<T, eastl::void_t<decltype(++eastl::declval<T>())>> : eastl::true_type {};
-#endif
+template<typename, typename = eastl::void_t<>>
+struct has_increment_operator_using_void_t : eastl::false_type {};
+
+template <typename T>
+struct has_increment_operator_using_void_t<T, eastl::void_t<has_increment_operator_detection<T>>> : eastl::true_type {};
// We use this for the is_copy_constructible test in order to verify that
@@ -359,13 +360,19 @@ struct NonPolymorphic1
void Function(){}
};
+// Disable the following warning:
+// warning: ‘struct Abstract’ has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor]
+// We explicitly want this class not to have a virtual destructor to test our type traits.
+EA_DISABLE_VC_WARNING(4265)
+EA_DISABLE_CLANG_WARNING(-Wnon-virtual-dtor)
+EA_DISABLE_GCC_WARNING(-Wnon-virtual-dtor)
struct Abstract
{
- #if defined(EA_COMPILER_GNUC) // GCC warns about this, so we include it for this class, even though for this compiler it partly defeats the purpose of its usage.
- virtual ~Abstract(){}
- #endif
virtual void Function() = 0;
};
+EA_RESTORE_GCC_WARNING()
+EA_RESTORE_CLANG_WARNING()
+EA_RESTORE_VC_WARNING()
struct AbstractWithDtor
{
@@ -542,6 +549,7 @@ int TestTypeTraits()
EATEST_VERIFY(GetType(is_integral<float>()) == false);
static_assert(is_integral<bool>::value, "is_integral failure");
+ static_assert(is_integral<char8_t>::value, "is_integral failure");
static_assert(is_integral<char16_t>::value, "is_integral failure");
static_assert(is_integral<char32_t>::value, "is_integral failure");
static_assert(is_integral<char>::value, "is_integral failure");
@@ -616,6 +624,42 @@ int TestTypeTraits()
EATEST_VERIFY(GetType(is_array<uint32_t*>()) == false);
+ //is_bounded_array
+ static_assert(is_bounded_array<Array>::value == true, "is_bounded_array failure");
+ EATEST_VERIFY(GetType(is_bounded_array<Array>()) == true);
+
+ static_assert(is_bounded_array<ArrayConst>::value == true, "is_bounded_array failure");
+ EATEST_VERIFY(GetType(is_bounded_array<ArrayConst>()) == true);
+
+ static_assert(is_bounded_array<int>::value == false, "is_bounded_array failure");
+ static_assert(is_bounded_array<int[32]>::value == true, "is_bounded_array failure");
+ static_assert(is_bounded_array<int[]>::value == false, "is_bounded_array failure");
+
+ static_assert(is_bounded_array<uint32_t>::value == false, "is_bounded_array failure");
+ EATEST_VERIFY(GetType(is_bounded_array<uint32_t>()) == false);
+
+ static_assert(is_bounded_array<uint32_t*>::value == false, "is_bounded_array failure");
+ EATEST_VERIFY(GetType(is_bounded_array<uint32_t*>()) == false);
+
+
+ //is_unbounded_array
+ static_assert(is_unbounded_array<Array>::value == false, "is_unbounded_array failure");
+ EATEST_VERIFY(GetType(is_unbounded_array<Array>()) == false);
+
+ static_assert(is_unbounded_array<ArrayConst>::value == false, "is_unbounded_array failure");
+ EATEST_VERIFY(GetType(is_unbounded_array<ArrayConst>()) == false);
+
+ static_assert(is_unbounded_array<int>::value == false, "is_unbounded_array failure");
+ static_assert(is_unbounded_array<int[32]>::value == false, "is_unbounded_array failure");
+ static_assert(is_unbounded_array<int[]>::value == true, "is_unbounded_array failure");
+
+ static_assert(is_unbounded_array<uint32_t>::value == false, "is_unbounded_array failure");
+ EATEST_VERIFY(GetType(is_unbounded_array<uint32_t>()) == false);
+
+ static_assert(is_unbounded_array<uint32_t*>::value == false, "is_unbounded_array failure");
+ EATEST_VERIFY(GetType(is_unbounded_array<uint32_t*>()) == false);
+
+
// is_reference
static_assert(is_reference<Class&>::value == true, "is_reference failure");
EATEST_VERIFY(GetType(is_reference<Class&>()) == true);
@@ -640,6 +684,10 @@ int TestTypeTraits()
static_assert(is_member_function_pointer<int>::value == false, "is_member_function_pointer failure");
static_assert(is_member_function_pointer<int(Class::*)>::value == false, "is_member_function_pointer failure");
static_assert(is_member_function_pointer<int(Class::*)()>::value == true, "is_member_function_pointer failure");
+ static_assert(is_member_function_pointer<int(Class::*)(...)>::value == true, "is_member_function_pointer failure");
+ static_assert(is_member_function_pointer<int(Class::*)() noexcept>::value == true, "is_member_function_pointer failure");
+ static_assert(is_member_function_pointer<int(Class::*)() &>::value == true, "is_member_function_pointer failure");
+ static_assert(is_member_function_pointer<int(Class::*)() &&>::value == true, "is_member_function_pointer failure");
// is_member_object_pointer
@@ -652,6 +700,9 @@ int TestTypeTraits()
static_assert(is_member_pointer<int>::value == false, "is_member_pointer failure");
static_assert(is_member_pointer<int(Class::*)>::value == true, "is_member_pointer failure");
static_assert(is_member_pointer<int(Class::*)()>::value == true, "is_member_pointer failure");
+ static_assert(is_member_pointer<int(Class::* const)>::value == true, "is_member_pointer failure");
+ static_assert(is_member_pointer<int(Class::* volatile)>::value == true, "is_member_pointer failure");
+ static_assert(is_member_pointer<int(Class::* const volatile)>::value == true, "is_member_pointer failure");
// is_pointer
@@ -719,7 +770,7 @@ int TestTypeTraits()
// is_function
static_assert(is_function<void>::value == false, "is_function failure");
static_assert(is_function<FunctionVoidVoid>::value == true, "is_function failure");
- static_assert(is_function<FunctionVoidVoid&>::value == false, "is_function failure");
+ static_assert(is_function<FunctionVoidVoid&>::value == false, "is_function failure");
static_assert(is_function<FunctionIntVoid>::value == true, "is_function failure");
static_assert(is_function<FunctionIntFloat>::value == true, "is_function failure");
static_assert(is_function<FunctionVoidVoidPtr>::value == false, "is_function failure");
@@ -731,6 +782,16 @@ int TestTypeTraits()
// typedef int PrintfConst(const char*, ...) const;
static_assert(is_function<int (const char*, ...)>::value == true, "is_function failure"); // This is the signature of printf.
#endif
+
+ static_assert(is_function<int (float)>::value == true, "is_function failure");
+ static_assert(is_function<int (float) const>::value == true, "is_function failure");
+ static_assert(is_function<int(float) volatile>::value == true, "is_function failure");
+ static_assert(is_function<int(float) const volatile>::value == true, "is_function failure");
+ static_assert(is_function<int(float)&>::value == true, "is_function failure");
+ static_assert(is_function<int(float)&&>::value == true, "is_function failure");
+ static_assert(is_function<int(float) noexcept>::value == true, "is_function failure");
+ static_assert(is_function<FunctionIntFloat &>::value == false, "is_function failure"); // reference to function, not a l-value reference qualified function
+ static_assert(is_function<FunctionIntFloat &&>::value == false, "is_function failure");
static_assert(is_function_v<void> == false, "is_function failure");
static_assert(is_function_v<FunctionVoidVoid> == true, "is_function failure");
@@ -820,6 +881,8 @@ int TestTypeTraits()
static_assert(is_const<ConstVolatileIntReference>::value == false, "is_const failure"); // Note here that the int is const, not the reference to the int.
EATEST_VERIFY(GetType(is_const<ConstVolatileIntReference>()) == false);
+ static_assert(is_const<void() const>::value == false, "is_const failure");
+ EATEST_VERIFY(GetType(is_const<void() const>()) == false);
// is_volatile
static_assert(is_volatile<Int>::value == false, "is_volatile failure");
@@ -843,6 +906,9 @@ int TestTypeTraits()
static_assert(is_volatile<ConstVolatileIntReference>::value == false, "is_volatile failure"); // Note here that the int is volatile, not the reference to the int.
EATEST_VERIFY(GetType(is_volatile<ConstVolatileIntReference>()) == false);
+ static_assert(is_volatile<void() const>::value == false, "is_volatile failure");
+ EATEST_VERIFY(GetType(is_volatile<void() const>()) == false);
+
// underlying_type and to_underlying
#if EASTL_TYPE_TRAIT_underlying_type_CONFORMANCE && !defined(EA_COMPILER_NO_STRONGLY_TYPED_ENUMS) // If we can execute this test...
@@ -1067,7 +1133,24 @@ int TestTypeTraits()
static_assert(is_signed<double>::value == true, "is_signed failure ");
static_assert(is_signed_v<double> == true, "is_signed failure ");
EATEST_VERIFY(GetType(is_signed<double>()) == true);
-
+
+ static_assert(is_signed<char16_t>::value == false, "is_signed failure ");
+ static_assert(is_signed_v<char16_t> == false, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<char16_t>()) == false);
+
+ static_assert(is_signed<char32_t>::value == false, "is_signed failure ");
+ static_assert(is_signed_v<char32_t> == false, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<char32_t>()) == false);
+
+#if EASTL_GCC_STYLE_INT128_SUPPORTED
+ static_assert(is_signed<__int128_t>::value == true, "is_signed failure ");
+ static_assert(is_signed_v<__int128_t> == true, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<__int128_t>()) == true);
+
+ static_assert(is_signed<__uint128_t>::value == false, "is_signed failure ");
+ static_assert(is_signed_v<__uint128_t> == false, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<__uint128_t>()) == false);
+#endif
// is_unsigned
static_assert(is_unsigned<unsigned int>::value == true, "is_unsigned failure ");
@@ -1082,9 +1165,9 @@ int TestTypeTraits()
static_assert(is_unsigned_v<int32_t> == false, "is_unsigned failure ");
EATEST_VERIFY(GetType(is_unsigned<int32_t>()) == false);
- static_assert(is_unsigned<bool>::value == false, "is_unsigned failure ");
- static_assert(is_unsigned_v<bool> == false, "is_unsigned failure ");
- EATEST_VERIFY(GetType(is_unsigned<bool>()) == false);
+ static_assert(is_unsigned<bool>::value == true, "is_unsigned failure ");
+ static_assert(is_unsigned_v<bool> == true, "is_unsigned failure ");
+ EATEST_VERIFY(GetType(is_unsigned<bool>()) == true);
static_assert(is_unsigned<float>::value == false, "is_unsigned failure ");
static_assert(is_unsigned_v<float> == false, "is_unsigned failure ");
@@ -1093,6 +1176,24 @@ int TestTypeTraits()
static_assert(is_unsigned<double>::value == false, "is_unsigned failure ");
static_assert(is_unsigned_v<double> == false, "is_unsigned failure ");
EATEST_VERIFY(GetType(is_unsigned<double>()) == false);
+
+ static_assert(is_unsigned<char16_t>::value == true, "is_unsigned failure ");
+ static_assert(is_unsigned_v<char16_t> == true, "is_unsigned failure ");
+ EATEST_VERIFY(GetType(is_unsigned<char16_t>()) == true);
+
+ static_assert(is_unsigned<char32_t>::value == true, "is_unsigned failure ");
+ static_assert(is_unsigned_v<char32_t> == true, "is_unsigned failure ");
+ EATEST_VERIFY(GetType(is_unsigned<char32_t>()) == true);
+
+#if EASTL_GCC_STYLE_INT128_SUPPORTED
+ static_assert(is_unsigned<__int128_t>::value == false, "is_unsigned failure ");
+ static_assert(is_unsigned_v<__int128_t> == false, "is_unsigned failure ");
+ EATEST_VERIFY(GetType(is_unsigned<__int128_t>()) == false);
+
+ static_assert(is_unsigned<__uint128_t>::value == true, "is_unsigned failure ");
+ static_assert(is_unsigned_v<__uint128_t> == true, "is_unsigned failure ");
+ EATEST_VERIFY(GetType(is_unsigned<__uint128_t>()) == true);
+#endif
// is_lvalue_reference
@@ -1252,6 +1353,7 @@ int TestTypeTraits()
// is_trivially_copyable
static_assert(is_trivially_copyable<void>::value == false, "is_trivially_copyable failure");
+ EATEST_VERIFY(GetType(is_trivially_copyable<void>()) == false);
static_assert(is_trivially_copyable<int>::value == true, "is_trivially_copyable failure");
static_assert(is_trivially_copyable<int*>::value == true, "is_trivially_copyable failure");
static_assert(is_trivially_copyable<int[]>::value == true, "is_trivially_copyable failure");
@@ -1395,14 +1497,16 @@ int TestTypeTraits()
// is_destructible
static_assert(is_destructible<int>::value == true, "is_destructible failure");
+ static_assert(is_destructible<int&>::value == true, "is_destructible failure");
+ static_assert(is_destructible<int&&>::value == true, "is_destructible failure");
static_assert(is_destructible<char>::value == true, "is_destructible failure");
static_assert(is_destructible<char*>::value == true, "is_destructible failure");
static_assert(is_destructible<PodA>::value == true, "is_destructible failure");
static_assert(is_destructible<void>::value == false, "is_destructible failure");
static_assert(is_destructible<int[3]>::value == true, "is_destructible failure");
static_assert(is_destructible<int[]>::value == false, "is_destructible failure"); // You can't call operator delete on this class.
- static_assert(is_destructible<Abstract>::value == false, "is_destructible failure"); // You can't call operator delete on this class.
- static_assert(is_destructible<AbstractWithDtor>::value == false, "is_destructible failure"); // You can't call operator delete on this class.
+ static_assert(is_destructible<Abstract>::value == true, "is_destructible failure");
+ static_assert(is_destructible<AbstractWithDtor>::value == true, "is_destructible failure");
#if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
static_assert(is_destructible<DeletedDtor>::value == false, "is_destructible failure"); // You can't call operator delete on this class.
#endif
@@ -1420,18 +1524,25 @@ int TestTypeTraits()
static_assert(is_trivially_destructible<PodA>::value == true, "is_trivially_destructible failure");
static_assert(is_trivially_destructible<int[3]>::value == true, "is_trivially_destructible failure");
static_assert(is_trivially_destructible<int[]>::value == false, "is_trivially_destructible failure");
- static_assert(is_trivially_destructible<Abstract>::value == false, "is_trivially_destructible failure");
- static_assert(is_trivially_destructible<AbstractWithDtor>::value == false, "is_trivially_destructible failure");
+ static_assert(is_trivially_destructible<Abstract>::value == true, "is_trivially_destructible failure");
+ static_assert(is_trivially_destructible<AbstractWithDtor>::value == false, "is_trivially_destructible failure"); // Having a user-defined destructor make it non-trivial.
+ #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
static_assert(is_trivially_destructible<DeletedDtor>::value == false, "is_trivially_destructible failure");
+ #endif
static_assert(is_trivially_destructible<NonPod2>::value == false, "is_trivially_destructible failure"); // This case differs from is_destructible, because we have a declared destructor.
#endif
// is_nothrow_destructible
static_assert(is_nothrow_destructible<int>::value == true, "is_nothrow_destructible failure");
- static_assert(is_nothrow_destructible<int&>::value == true, "is_nothrow_destructible failure");
- static_assert(is_nothrow_destructible<int&&>::value == true, "is_nothrow_destructible failure");
+ static_assert(is_nothrow_destructible<int&>::value == true, "is_nothrow_destructible failure");
+ static_assert(is_nothrow_destructible<int&&>::value == true, "is_nothrow_destructible failure");
static_assert(is_nothrow_destructible<void>::value == false, "is_nothrow_destructible failure");
+ static_assert(is_nothrow_destructible<Abstract>::value == true, "is_nothrow_destructible failure");
+ static_assert(is_nothrow_destructible<AbstractWithDtor>::value == true, "is_nothrow_destructible failure");
+ #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
+ static_assert(is_nothrow_destructible<DeletedDtor>::value == false, "is_nothrow_destructible failure"); // You can't call operator delete on this class.
+ #endif
#if EASTL_TYPE_TRAIT_is_nothrow_destructible_CONFORMANCE
static_assert(is_nothrow_destructible<NonPod2>::value == true, "is_nothrow_destructible failure"); // NonPod2 is nothrow destructible because it has an empty destructor (makes no calls) which has no exception specification. Thus its exception specification defaults to noexcept(true) [C++11 Standard, 15.4 paragraph 14]
static_assert(is_nothrow_destructible<NoThrowDestructible>::value == true, "is_nothrow_destructible failure");
@@ -1669,7 +1780,7 @@ int TestTypeTraits()
static_assert(eastl::is_same_v<unsigned long, eastl::make_unsigned<unsigned long>::type>);
static_assert(eastl::is_same_v<unsigned long long, eastl::make_unsigned<unsigned long long>::type>);
- #if EASTL_INT128_SUPPORTED && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG))
+ #if EASTL_GCC_STYLE_INT128_SUPPORTED
static_assert(eastl::is_same_v<__uint128_t, eastl::make_unsigned<__int128_t>::type>);
static_assert(eastl::is_same_v<__uint128_t, eastl::make_unsigned<__uint128_t>::type>);
@@ -1680,13 +1791,18 @@ int TestTypeTraits()
// Char tests
static_assert(sizeof(char) == sizeof(eastl::make_signed<char>::type));
static_assert(sizeof(wchar_t) == sizeof(eastl::make_signed<wchar_t>::type));
+ static_assert(sizeof(char8_t) == sizeof(eastl::make_signed<char8_t>::type));
static_assert(sizeof(char16_t) == sizeof(eastl::make_signed<char16_t>::type));
static_assert(sizeof(char32_t) == sizeof(eastl::make_signed<char32_t>::type));
static_assert(sizeof(char) == sizeof(eastl::make_unsigned<char>::type));
static_assert(sizeof(wchar_t) == sizeof(eastl::make_unsigned<wchar_t>::type));
+ static_assert(sizeof(char8_t) == sizeof(eastl::make_unsigned<char8_t>::type));
static_assert(sizeof(char16_t) == sizeof(eastl::make_unsigned<char16_t>::type));
static_assert(sizeof(char32_t) == sizeof(eastl::make_unsigned<char32_t>::type));
+ static_assert(eastl::is_same_v<signed char, eastl::make_signed<char8_t>::type>);
+ static_assert(eastl::is_same_v<unsigned char, eastl::make_unsigned<char8_t>::type>);
+
// Enum tests
enum EnumUCharSize : unsigned char {};
enum EnumUShortSize : unsigned short {};
@@ -1833,6 +1949,28 @@ int TestTypeTraits()
yValue = 3;
EATEST_VERIFY(yValue == 3);
+ // ref to T
+ // -> T*
+ static_assert(is_same_v<add_pointer_t<int&>, int*>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<int(&)()>, int(*)()>, "add_pointer failure");
+
+ // object type (a (possibly cv-qualified) type other than function type, reference type or void), or
+ // a function type that is not cv- or ref-qualified, or a (possibly cv-qualified) void type
+ // -> T*
+ static_assert(is_same_v<add_pointer_t<int>, int*>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<int*>, int**>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<int()>, int(*)()>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<void>, void*>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<const void>, const void*>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<volatile void>, volatile void*>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<const volatile void>, const volatile void*>, "add_pointer failure");
+
+ // otherwise (cv- or ref-qualified function type)
+ // -> T
+ static_assert(is_same_v<add_pointer_t<int() const>, int() const>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<int() volatile>, int() volatile>, "add_pointer failure");
+ static_assert(is_same_v<add_pointer_t<int() const volatile>, int() const volatile>, "add_pointer failure");
+
// remove_extent
// If T is an array of some type X, provides the member typedef type equal to X, otherwise
// type is T. Note that if T is a multidimensional array, only the first dimension is removed.
@@ -1846,6 +1984,55 @@ int TestTypeTraits()
static_assert((eastl::is_same<Int2, int>::value == true), "remove_all_extents/is_same failure");
}
+ // add_lvalue_reference
+ {
+ // function type with no cv- or ref-qualifier
+ // -> T&
+ static_assert(is_same_v<add_lvalue_reference_t<void()>, void(&)()>, "add_lvalue_reference failure");
+
+ // object type (a (possibly cv-qualified) type other than function type, reference type or void)
+ // -> T&
+ static_assert(is_same_v<add_lvalue_reference_t<int>, int&>, "add_lvalue_reference failure");
+ static_assert(is_same_v<add_lvalue_reference_t<const int>, const int&>, "add_lvalue_reference failure");
+
+ // if T is an rvalue reference (to some type U)
+ // -> U&
+ static_assert(is_same_v<add_lvalue_reference_t<int&&>, int&>, "add_lvalue_reference failure");
+
+ // otherwise (cv- or ref-qualified function type, or reference type, or (possibly cv-qualified) void)
+ // -> T
+ static_assert(is_same_v<add_lvalue_reference_t<void() const>, void() const>, "add_lvalue_reference failure");
+ static_assert(is_same_v<add_lvalue_reference_t<void()&>, void()&>, "add_lvalue_reference failure");
+ static_assert(is_same_v<add_lvalue_reference_t<void()&&>, void()&&>, "add_lvalue_reference failure");
+ static_assert(is_same_v<add_lvalue_reference_t<int&>, int&>, "add_lvalue_reference failure");
+ static_assert(is_same_v<add_lvalue_reference_t<const int&>, const int&>, "add_lvalue_reference failure");
+ static_assert(is_same_v<add_lvalue_reference_t<void>, void>, "add_lvalue_reference failure");
+ static_assert(is_same_v<add_lvalue_reference_t<const void>, const void>, "add_lvalue_reference failure");
+ }
+
+ // add_rvalue_reference
+ {
+ // function type with no cv- or ref-qualifier
+ // -> T&&
+ static_assert(is_same_v<add_rvalue_reference_t<void()>, void(&&)()>, "add_rvalue_reference failure");
+
+ // object type (a (possibly cv-qualified) type other than function type, reference type or void)
+ // -> T&&
+ static_assert(is_same_v<add_rvalue_reference_t<int>, int&&>, "add_rvalue_reference failure");
+ static_assert(is_same_v<add_rvalue_reference_t<const int>, const int&&>, "add_rvalue_reference failure");
+
+ // otherwise (cv- or ref-qualified function type, or reference type, or (possibly cv-qualified) void)
+ // -> T
+ static_assert(is_same_v<add_rvalue_reference_t<void() const>, void() const>, "add_rvalue_reference failure");
+ static_assert(is_same_v<add_rvalue_reference_t<void()&>, void()&>, "add_rvalue_reference failure");
+ static_assert(is_same_v<add_rvalue_reference_t<void()&&>, void()&&>, "add_rvalue_reference failure");
+ static_assert(is_same_v<add_rvalue_reference_t<int&>, int&>, "add_rvalue_reference failure");
+ static_assert(is_same_v<add_rvalue_reference_t<int&&>, int&&>, "add_rvalue_reference failure");
+ static_assert(is_same_v<add_rvalue_reference_t<const int&>, const int&>, "add_rvalue_reference failure");
+ static_assert(is_same_v<add_rvalue_reference_t<void>, void>, "add_rvalue_reference failure");
+ static_assert(is_same_v<add_rvalue_reference_t<const void>, const void>, "add_rvalue_reference failure");
+ }
+
// decay
{
@@ -1979,26 +2166,71 @@ int TestTypeTraits()
}
// void_t
- #if EASTL_VARIABLE_TEMPLATES_ENABLED
{
{
- static_assert(is_same_v<void_t<void>, void>, "void_t failure");
- static_assert(is_same_v<void_t<int>, void>, "void_t failure");
- static_assert(is_same_v<void_t<short>, void>, "void_t failure");
- static_assert(is_same_v<void_t<long>, void>, "void_t failure");
- static_assert(is_same_v<void_t<long long>, void>, "void_t failure");
- static_assert(is_same_v<void_t<ClassEmpty>, void>, "void_t failure");
- static_assert(is_same_v<void_t<ClassNonEmpty>, void>, "void_t failure");
- static_assert(is_same_v<void_t<vector<int>>, void>, "void_t failure");
+ static_assert(is_same<void_t<void>, void>::value, "void_t failure");
+ static_assert(is_same<void_t<int>, void>::value, "void_t failure");
+ static_assert(is_same<void_t<short>, void>::value, "void_t failure");
+ static_assert(is_same<void_t<long>, void>::value, "void_t failure");
+ static_assert(is_same<void_t<long long>, void>::value, "void_t failure");
+ static_assert(is_same<void_t<ClassEmpty>, void>::value, "void_t failure");
+ static_assert(is_same<void_t<ClassNonEmpty>, void>::value, "void_t failure");
+ static_assert(is_same<void_t<vector<int>>, void>::value, "void_t failure");
}
// new sfinae mechansim test
{
- static_assert(has_increment_operator<HasIncrementOperator>::value, "void_t sfinae failure");
- static_assert(!has_increment_operator<ClassEmpty>::value, "void_t sfinae failure");
+ static_assert(has_increment_operator_using_void_t<HasIncrementOperator>::value, "void_t sfinae failure");
+ static_assert(!has_increment_operator_using_void_t<ClassEmpty>::value, "void_t sfinae failure");
}
}
+
+ // detected idiom
+ {
+ static_assert(is_detected<has_increment_operator_detection, HasIncrementOperator>::value, "is_detected failure.");
+ static_assert(!is_detected<has_increment_operator_detection, ClassEmpty>::value, "is_detected failure.");
+
+ static_assert(is_same<detected_t<has_increment_operator_detection, HasIncrementOperator>, HasIncrementOperator&>::value, "is_detected_t failure.");
+ static_assert(is_same<detected_t<has_increment_operator_detection, ClassEmpty>, nonesuch>::value, "is_detected_t failure.");
+
+ using detected_or_positive_result = detected_or<float, has_increment_operator_detection, HasIncrementOperator>;
+ using detected_or_negative_result = detected_or<float, has_increment_operator_detection, ClassEmpty>;
+ static_assert(detected_or_positive_result::value_t::value, "detected_or failure.");
+ static_assert(!detected_or_negative_result::value_t::value, "detected_or failure.");
+ static_assert(is_same<detected_or_positive_result::type, HasIncrementOperator&>::value, "detected_or failure.");
+ static_assert(is_same<detected_or_negative_result::type, float>::value, "detected_or failure.");
+
+ static_assert(is_same<detected_or_t<float, has_increment_operator_detection, HasIncrementOperator>, HasIncrementOperator&>::value, "detected_or_t failure.");
+ static_assert(is_same<detected_or_t<float, has_increment_operator_detection, ClassEmpty>, float>::value, "detected_or_t failure.");
+
+ static_assert(is_detected_exact<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_exact failure.");
+ static_assert(!is_detected_exact<float, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_exact failure.");
+ static_assert(is_detected_exact<nonesuch, has_increment_operator_detection, ClassEmpty>::value, "is_detected_exact failure.");
+ static_assert(!is_detected_exact<float, has_increment_operator_detection, ClassEmpty>::value, "is_detected_exact failure.");
+
+ static_assert(is_detected_convertible<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure.");
+ static_assert(is_detected_convertible<HasIncrementOperator, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure.");
+ static_assert(!is_detected_convertible<float, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure.");
+ static_assert(!is_detected_convertible<nonesuch, has_increment_operator_detection, ClassEmpty>::value, "is_detected_convertible failure.");
+ static_assert(!is_detected_convertible<float, has_increment_operator_detection, ClassEmpty>::value, "is_detected_convertible failure.");
+
+
+ #if EASTL_VARIABLE_TEMPLATES_ENABLED
+ static_assert(is_detected_v<has_increment_operator_detection, HasIncrementOperator>, "is_detected_v failure.");
+ static_assert(!is_detected_v<has_increment_operator_detection, ClassEmpty>, "is_detected_v failure.");
+
+ static_assert(is_detected_exact_v<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>, "is_detected_exact_v failure.");
+ static_assert(!is_detected_exact_v<float, has_increment_operator_detection, HasIncrementOperator>, "is_detected_exact_v failure.");
+ static_assert(is_detected_exact_v<nonesuch, has_increment_operator_detection, ClassEmpty>, "is_detected_exact_v failure.");
+ static_assert(!is_detected_exact_v<float, has_increment_operator_detection, ClassEmpty>, "is_detected_exact_v failure.");
+
+ static_assert(is_detected_convertible_v<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure.");
+ static_assert(is_detected_convertible_v<HasIncrementOperator, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure.");
+ static_assert(!is_detected_convertible_v<float, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure.");
+ static_assert(!is_detected_convertible_v<nonesuch, has_increment_operator_detection, ClassEmpty>, "is_detected_convertible_v failure.");
+ static_assert(!is_detected_convertible_v<float, has_increment_operator_detection, ClassEmpty>, "is_detected_convertible_v failure.");
#endif
+ }
// conjunction
{
@@ -2160,8 +2392,10 @@ int TestTypeTraits()
static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure");
}
- #ifndef EA_COMPILER_MSVC
- // NOTE(rparolin): MSVC is incorrectly categorizing the aggregate type in this test-case.
+ #if defined(EA_COMPILER_CPP11_ENABLED) && !defined(EA_COMPILER_CPP14_ENABLED)
+ // See https://en.cppreference.com/w/cpp/language/aggregate_initialization
+ // In C++11 the requirement was added to aggregate types that no default member initializers exist,
+ // however this requirement was removed in C++14.
{
struct NotAggregrate { int data = 42; }; // default member initializer
static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure");
diff --git a/EASTL/test/source/TestUtility.cpp b/EASTL/test/source/TestUtility.cpp
index 363f409..e9027e5 100644
--- a/EASTL/test/source/TestUtility.cpp
+++ b/EASTL/test/source/TestUtility.cpp
@@ -108,7 +108,7 @@ static int TestUtilityPair()
EATEST_VERIFY((p2.first == 0) && (p2.second == 1.f));
pair<const char*, int> p3 = eastl::make_pair("a", 1);
- EATEST_VERIFY((EA::StdC::Strcmp(p3.first, "a") == 0) && (p2.second == 1));
+ EATEST_VERIFY((EA::StdC::Strcmp(p3.first, "a") == 0) && (p3.second == 1));
pair<const char*, int> p4 = eastl::make_pair<const char*, int>("a", 1);
EATEST_VERIFY((EA::StdC::Strcmp(p4.first, "a") == 0) && (p4.second == 1));
@@ -116,6 +116,20 @@ static int TestUtilityPair()
pair<int, const char*> p5 = eastl::make_pair<int, const char*>(1, "b");
EATEST_VERIFY((p5.first == 1) && (EA::StdC::Strcmp(p5.second, "b") == 0));
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ pair<int, int> p6 = eastl::make_pair<int, int>(1, 2);
+ pair<int, int> p7 = eastl::make_pair<int, int>(2, 1);
+ pair<int, int> p8 = eastl::make_pair<int, int>(7, 8);
+ pair<int, int> p9 = eastl::make_pair<int, int>(10, 1);
+
+ EATEST_VERIFY( (p6 <=> p7) != 0);
+ EATEST_VERIFY( (p6 <=> p6) == 0);
+ EATEST_VERIFY( (p7 <=> p8) < 0);
+ EATEST_VERIFY( (p7 <=> p8) <= 0);
+ EATEST_VERIFY( (p9 <=> p8) > 0);
+ EATEST_VERIFY( (p9 <=> p8) >= 0);
+#endif
+
#if !defined(EA_COMPILER_NO_AUTO)
auto p60 = eastl::make_pair("a", "b"); // Different strings of same length of 1.
EATEST_VERIFY((EA::StdC::Strcmp(p60.first, "a") == 0) && (EA::StdC::Strcmp(p60.second, "b") == 0));
@@ -495,13 +509,15 @@ static int TestUtilityIntegerSequence()
using namespace eastl;
int nErrorCount = 0;
#if EASTL_VARIADIC_TEMPLATES_ENABLED
-// Android clang chokes with an internal compiler error on make_integer_sequence
-#if !defined(EA_PLATFORM_ANDROID)
+
EATEST_VERIFY((integer_sequence<int, 0, 1, 2, 3, 4>::size() == 5));
EATEST_VERIFY((make_integer_sequence<int, 5>::size() == 5));
-#endif
+ static_assert(is_same<make_integer_sequence<int, 5>, integer_sequence<int, 0, 1, 2, 3, 4>>::value);
+
EATEST_VERIFY((index_sequence<0, 1, 2, 3, 4>::size() == 5));
EATEST_VERIFY((make_index_sequence<5>::size() == 5));
+ static_assert(is_same<make_index_sequence<5>, index_sequence<0, 1, 2, 3, 4>>::value);
+ static_assert(is_same<make_index_sequence<5>, integer_sequence<size_t, 0, 1, 2, 3, 4>>::value);
#endif // EASTL_VARIADIC_TEMPLATES_ENABLED
return nErrorCount;
@@ -614,6 +630,271 @@ static int TestUtilityExchange()
return nErrorCount;
}
+#if defined(EA_COMPILER_CPP20_ENABLED)
+template <typename T>
+static int TestCmpCommon()
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::cmp_equal(T(0), T(0)));
+ EATEST_VERIFY(eastl::cmp_equal(T(1), T(1)));
+ EATEST_VERIFY(eastl::cmp_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min()));
+ EATEST_VERIFY(eastl::cmp_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max()));
+ EATEST_VERIFY(!eastl::cmp_equal(T(0), T(1)));
+ EATEST_VERIFY(!eastl::cmp_equal(T(1), T(0)));
+ if (eastl::is_signed_v<T>)
+ {
+ EATEST_VERIFY(eastl::cmp_equal(T(-1), T(-1)));
+ EATEST_VERIFY(!eastl::cmp_equal(T(-1), T(-2)));
+ EATEST_VERIFY(!eastl::cmp_equal(T(-2), T(-1)));
+ }
+
+ EATEST_VERIFY(eastl::cmp_not_equal(T(1), T(0)));
+ EATEST_VERIFY(eastl::cmp_not_equal(T(0), T(1)));
+ EATEST_VERIFY(eastl::cmp_not_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max()));
+ EATEST_VERIFY(eastl::cmp_not_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min()));
+ if (eastl::is_signed_v<T>)
+ {
+ EATEST_VERIFY(!eastl::cmp_not_equal(T(-1), T(-1)));
+ EATEST_VERIFY(eastl::cmp_not_equal(T(-1), T(-2)));
+ EATEST_VERIFY(eastl::cmp_not_equal(T(-2), T(-1)));
+ }
+
+ EATEST_VERIFY(eastl::cmp_less(T(0), T(1)));
+ EATEST_VERIFY(eastl::cmp_less(T(5), T(10)));
+ EATEST_VERIFY(!eastl::cmp_less(T(0), T(0)));
+ EATEST_VERIFY(!eastl::cmp_less(T(1), T(0)));
+ EATEST_VERIFY(eastl::cmp_less(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max()));
+ EATEST_VERIFY(!eastl::cmp_less(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min()));
+ EATEST_VERIFY(!eastl::cmp_less(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max()));
+ EATEST_VERIFY(!eastl::cmp_less(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min()));
+ if (eastl::is_signed_v<T>)
+ {
+ EATEST_VERIFY(!eastl::cmp_less(T(-1), T(-1)));
+ EATEST_VERIFY(!eastl::cmp_less(T(-1), T(-2)));
+ EATEST_VERIFY(eastl::cmp_less(T(-2), T(-1)));
+ }
+
+ EATEST_VERIFY(eastl::cmp_less_equal(T(0), T(1)));
+ EATEST_VERIFY(eastl::cmp_less_equal(T(5), T(10)));
+ EATEST_VERIFY(eastl::cmp_less_equal(T(0), T(0)));
+ EATEST_VERIFY(eastl::cmp_less_equal(T(1), T(1)));
+ EATEST_VERIFY(!eastl::cmp_less_equal(T(1), T(0)));
+ EATEST_VERIFY(eastl::cmp_less_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max()));
+ EATEST_VERIFY(eastl::cmp_less_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min()));
+ EATEST_VERIFY(eastl::cmp_less_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max()));
+ EATEST_VERIFY(!eastl::cmp_less_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min()));
+ if (eastl::is_signed_v<T>)
+ {
+ EATEST_VERIFY(eastl::cmp_less_equal(T(-1), T(-1)));
+ EATEST_VERIFY(!eastl::cmp_less_equal(T(-1), T(-2)));
+ EATEST_VERIFY(eastl::cmp_less_equal(T(-2), T(-1)));
+ }
+
+ EATEST_VERIFY(eastl::cmp_greater(T(1), T(0)));
+ EATEST_VERIFY(eastl::cmp_greater(T(10), T(5)));
+ EATEST_VERIFY(!eastl::cmp_greater(T(0), T(0)));
+ EATEST_VERIFY(!eastl::cmp_greater(T(0), T(1)));
+ EATEST_VERIFY(eastl::cmp_greater(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min()));
+ EATEST_VERIFY(!eastl::cmp_greater(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min()));
+ EATEST_VERIFY(!eastl::cmp_greater(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max()));
+ EATEST_VERIFY(!eastl::cmp_greater(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max()));
+ if (eastl::is_signed_v<T>)
+ {
+ EATEST_VERIFY(!eastl::cmp_greater(T(-1), T(-1)));
+ EATEST_VERIFY(eastl::cmp_greater(T(-1), T(-2)));
+ EATEST_VERIFY(!eastl::cmp_greater(T(-2), T(-1)));
+ }
+
+ EATEST_VERIFY(eastl::cmp_greater_equal(T(1), T(0)));
+ EATEST_VERIFY(eastl::cmp_greater_equal(T(10), T(5)));
+ EATEST_VERIFY(eastl::cmp_greater_equal(T(0), T(0)));
+ EATEST_VERIFY(!eastl::cmp_greater_equal(T(0), T(1)));
+ EATEST_VERIFY(eastl::cmp_greater_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min()));
+ EATEST_VERIFY(eastl::cmp_greater_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min()));
+ EATEST_VERIFY(eastl::cmp_greater_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max()));
+ EATEST_VERIFY(!eastl::cmp_greater_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max()));
+ if (eastl::is_signed_v<T>)
+ {
+ EATEST_VERIFY(eastl::cmp_greater_equal(T(-1), T(-1)));
+ EATEST_VERIFY(eastl::cmp_greater_equal(T(-1), T(-2)));
+ EATEST_VERIFY(!eastl::cmp_greater_equal(T(-2), T(-1)));
+ }
+
+ return nErrorCount;
+}
+
+template <typename T, typename U>
+static int TestUtilityCmpEql(const T x, const U y)
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::cmp_equal(T(x), U(y)));
+ EATEST_VERIFY(eastl::cmp_equal(U(y), T(x)));
+ EATEST_VERIFY(!eastl::cmp_not_equal(T(x), U(y)));
+ EATEST_VERIFY(!eastl::cmp_not_equal(U(y), T(x)));
+
+ return nErrorCount;
+}
+
+template <typename T, typename U>
+static int TestUtilityCmpLess(const T x, const U y)
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::cmp_less(T(x), U(y)));
+ EATEST_VERIFY(!eastl::cmp_less(U(y), T(x)));
+
+ EATEST_VERIFY(!eastl::cmp_greater_equal(T(x), U(y)));
+ EATEST_VERIFY(eastl::cmp_greater_equal(U(y), T(x)));
+
+ return nErrorCount;
+}
+
+template <typename T, typename U>
+static int TestUtilityCmpGreater(const T x, const U y)
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::cmp_greater(T(x), U(y)));
+ EATEST_VERIFY(!eastl::cmp_greater(U(y), T(x)));
+
+ EATEST_VERIFY(!eastl::cmp_less_equal(T(x), U(y)));
+ EATEST_VERIFY(eastl::cmp_less_equal(U(y), T(x)));
+
+ return nErrorCount;
+}
+
+template <typename T, typename U>
+static int TestUtilityCmpLessEq(const T x, const U y)
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::cmp_less_equal(T(x), U(y)));
+ EATEST_VERIFY(eastl::cmp_less(T(x), U(y)) || eastl::cmp_equal(T(x), U(y)));
+
+ EATEST_VERIFY(eastl::cmp_greater_equal(U(y), T(x)));
+
+ return nErrorCount;
+}
+
+template <typename T, typename U>
+static int TestUtilityCmpGreaterEq(const T x, const U y)
+{
+ int nErrorCount = 0;
+
+ EATEST_VERIFY(eastl::cmp_greater_equal(T(x), U(y)));
+ EATEST_VERIFY(eastl::cmp_greater(T(x), U(y)) || eastl::cmp_equal(T(x), U(y)));
+
+ EATEST_VERIFY(eastl::cmp_less_equal(U(y), T(x)));
+
+ return nErrorCount;
+}
+
+static int TestUtilityIntegralComp()
+{
+ int nErrorCount = 0;
+
+ // Test integral comparisons among same types
+ nErrorCount += TestCmpCommon<int>();
+ nErrorCount += TestCmpCommon<short>();
+ nErrorCount += TestCmpCommon<long>();
+ nErrorCount += TestCmpCommon<long long>();
+
+ nErrorCount += TestCmpCommon<unsigned int>();
+ nErrorCount += TestCmpCommon<unsigned short>();
+ nErrorCount += TestCmpCommon<unsigned long>();
+ nErrorCount += TestCmpCommon<unsigned long long>();
+
+ // Test integral comparison among different types
+ nErrorCount += TestUtilityCmpEql(int(0), short(0));
+ nErrorCount += TestUtilityCmpEql(short(2), long(2));
+ nErrorCount += TestUtilityCmpEql(short(3), unsigned long(3));
+ nErrorCount += TestUtilityCmpEql(int(-5), long long(-5));
+ nErrorCount += TestUtilityCmpEql(short(-100), long long(-100));
+ nErrorCount += TestUtilityCmpEql(unsigned int(100), long(100));
+ nErrorCount += TestUtilityCmpEql(unsigned long long(100), int(100));
+
+ nErrorCount += TestUtilityCmpLess(int(0), long long(1));
+ nErrorCount += TestUtilityCmpLess(int(-1), unsigned long(1));
+ nErrorCount += TestUtilityCmpLess(short(-100), long long(100));
+ nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<long>::min(), short(0));
+ nErrorCount += TestUtilityCmpLess(short(0), eastl::numeric_limits<int>::max());
+ nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<unsigned short>::min(), eastl::numeric_limits<int>::max());
+ nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<short>::max(), eastl::numeric_limits<long>::max());
+ nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<int>::max(), eastl::numeric_limits<long long>::max());
+ nErrorCount += TestUtilityCmpLess(int(-100), unsigned int(0));
+ nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<int>::min(), eastl::numeric_limits<unsigned int>::min());
+
+ nErrorCount += TestUtilityCmpGreater(int(1), short(0));
+ nErrorCount += TestUtilityCmpGreater(unsigned long(1), int(-1));
+ nErrorCount += TestUtilityCmpGreater(unsigned long long(100), short(-100));
+ nErrorCount += TestUtilityCmpGreater(short(0), eastl::numeric_limits<short>::min());
+ nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<long>::max(), unsigned short(5));
+ nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<long>::max(), eastl::numeric_limits<int>::min());
+ nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<int>::max(), eastl::numeric_limits<short>::max());
+ nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<long long>::max(), eastl::numeric_limits<int>::max());
+ nErrorCount += TestUtilityCmpGreater(unsigned int(0), int(-100));
+ nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<unsigned int>::min(), eastl::numeric_limits<int>::min());
+
+ nErrorCount += TestUtilityCmpLessEq(int(0), short(1));
+ nErrorCount += TestUtilityCmpLessEq(int(-1), long long(-1));
+ nErrorCount += TestUtilityCmpLessEq(short(-100), unsigned long long(100));
+ nErrorCount += TestUtilityCmpLessEq(short(-100), long long(-100));
+ nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<int>::min(), short(0));
+ nErrorCount += TestUtilityCmpLessEq(short(0), eastl::numeric_limits<int>::max());
+ nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<short>::min(), eastl::numeric_limits<short>::min());
+ nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<int>::max(), eastl::numeric_limits<int>::max());
+ nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<int>::max(), eastl::numeric_limits<long long>::max());
+ nErrorCount += TestUtilityCmpLessEq(int(50), unsigned int(50));
+ nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<int>::min(), eastl::numeric_limits<unsigned int>::min());
+
+ nErrorCount += TestUtilityCmpGreaterEq(int(1), short(1));
+ nErrorCount += TestUtilityCmpGreaterEq(long long(-1), int(-1));
+ nErrorCount += TestUtilityCmpGreaterEq(long long(-100), short(-100));
+ nErrorCount += TestUtilityCmpGreaterEq(short(0), long(0));
+ nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<long>::max(), eastl::numeric_limits<long>::max());
+ nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<int>::max(), eastl::numeric_limits<short>::min());
+ nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<int>::max(), eastl::numeric_limits<short>::max());
+ nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<long long>::max(), eastl::numeric_limits<int>::max());
+ nErrorCount += TestUtilityCmpGreaterEq(unsigned int(0), int(0));
+ nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<unsigned int>::min(), eastl::numeric_limits<int>::min());
+
+ // Test in_range
+ EATEST_VERIFY(eastl::in_range<int>(0));
+ EATEST_VERIFY(eastl::in_range<int>(eastl::numeric_limits<int>::min()));
+ EATEST_VERIFY(eastl::in_range<int>(eastl::numeric_limits<int>::max()));
+ EATEST_VERIFY(eastl::in_range<unsigned int>(0));
+ EATEST_VERIFY(eastl::in_range<unsigned int>(eastl::numeric_limits<unsigned int>::min()));
+ EATEST_VERIFY(eastl::in_range<unsigned int>(eastl::numeric_limits<unsigned int>::max()));
+ EATEST_VERIFY(!eastl::in_range<unsigned int>(-1));
+ EATEST_VERIFY(!eastl::in_range<int>(eastl::numeric_limits<unsigned int>::max()));
+ EATEST_VERIFY(!eastl::in_range<unsigned int>(eastl::numeric_limits<int>::min()));
+
+ EATEST_VERIFY(eastl::in_range<short>(100));
+ EATEST_VERIFY(eastl::in_range<short>(eastl::numeric_limits<short>::min()));
+ EATEST_VERIFY(eastl::in_range<short>(eastl::numeric_limits<short>::max()));
+ EATEST_VERIFY(eastl::in_range<unsigned short>(100));
+ EATEST_VERIFY(eastl::in_range<unsigned short>(eastl::numeric_limits<unsigned short>::min()));
+ EATEST_VERIFY(eastl::in_range<unsigned short>(eastl::numeric_limits<unsigned short>::max()));
+ EATEST_VERIFY(!eastl::in_range<unsigned short>(-1));
+ EATEST_VERIFY(!eastl::in_range<short>(eastl::numeric_limits<unsigned int>::max()));
+ EATEST_VERIFY(!eastl::in_range<unsigned short>(eastl::numeric_limits<int>::min()));
+
+ EATEST_VERIFY(eastl::in_range<long>(50));
+ EATEST_VERIFY(eastl::in_range<long>(eastl::numeric_limits<long>::min()));
+ EATEST_VERIFY(eastl::in_range<long>(eastl::numeric_limits<long>::max()));
+ EATEST_VERIFY(eastl::in_range<unsigned long>(50));
+ EATEST_VERIFY(eastl::in_range<unsigned long>(eastl::numeric_limits<unsigned long>::min()));
+ EATEST_VERIFY(eastl::in_range<unsigned long>(eastl::numeric_limits<unsigned long>::max()));
+ EATEST_VERIFY(!eastl::in_range<unsigned long>(-1));
+ EATEST_VERIFY(!eastl::in_range<long>(eastl::numeric_limits<unsigned int>::max()));
+ EATEST_VERIFY(!eastl::in_range<unsigned long>(eastl::numeric_limits<int>::min()));
+
+ return nErrorCount;
+}
+#endif
+
///////////////////////////////////////////////////////////////////////////////
// TestUtility
//
@@ -627,6 +908,8 @@ int TestUtility()
nErrorCount += TestUtilityMove();
nErrorCount += TestUtilityIntegerSequence();
nErrorCount += TestUtilityExchange();
-
+#if defined(EA_COMPILER_CPP20_ENABLED)
+ nErrorCount += TestUtilityIntegralComp();
+#endif
return nErrorCount;
}
diff --git a/EASTL/test/source/TestVariant.cpp b/EASTL/test/source/TestVariant.cpp
index a8197e5..2a78a89 100644
--- a/EASTL/test/source/TestVariant.cpp
+++ b/EASTL/test/source/TestVariant.cpp
@@ -7,6 +7,7 @@
#include <EASTL/string.h>
#include <EASTL/algorithm.h>
#include <EASTL/sort.h>
+#include <EASTL/bonus/overloaded.h>
#ifdef EA_COMPILER_CPP14_ENABLED
#include "ConceptImpls.h"
@@ -291,7 +292,7 @@ int TestVariantHoldsAlternative()
VERIFY(!holds_alternative<long>(v)); // Verify that a query for a T not in the variant typelist returns false.
VERIFY(!holds_alternative<string>(v)); // Verify that a query for a T not in the variant typelist returns false.
- VERIFY(!holds_alternative<int>(v)); // variant does not hold an int
+ VERIFY(!holds_alternative<int>(v)); // variant does not hold an int
VERIFY(!holds_alternative<short>(v)); // variant does not hold a short
}
@@ -377,7 +378,7 @@ int TestVariantValuelessByException()
VERIFY(!v.valueless_by_exception());
}
- // TODO(rparolin): review exception safety for variant types
+ // TODO(rparolin): review exception safety for variant types
//
// {
// #if EASTL_EXCEPTIONS_ENABLED
@@ -563,12 +564,12 @@ int TestVariantSwap()
v1.swap(v2);
- VERIFY(get<int>(v1) == 24);
+ VERIFY(get<int>(v1) == 24);
VERIFY(get<int>(v2) == 42);
v1.swap(v2);
- VERIFY(get<int>(v1) == 42);
+ VERIFY(get<int>(v1) == 42);
VERIFY(get<int>(v2) == 24);
}
@@ -576,13 +577,13 @@ int TestVariantSwap()
variant<string> v1 = "Hello";
variant<string> v2 = "World";
- VERIFY(get<string>(v1) == "Hello");
+ VERIFY(get<string>(v1) == "Hello");
VERIFY(get<string>(v2) == "World");
v1.swap(v2);
VERIFY(get<string>(v1) == "World");
- VERIFY(get<string>(v2) == "Hello");
+ VERIFY(get<string>(v2) == "Hello");
}
return nErrorCount;
@@ -657,7 +658,7 @@ EA_NO_INLINE int TestVariantVisitNoInline(const eastl::variant<int, bool, unsign
struct MyVisitor
{
MyVisitor() = delete;
- MyVisitor(bool& b) : mVisited(b) {}
+ MyVisitor(bool& visited) : mVisited(visited) {};
void operator()(int) { mVisited = true; }
void operator()(bool) { mVisited = true; }
@@ -666,7 +667,7 @@ EA_NO_INLINE int TestVariantVisitNoInline(const eastl::variant<int, bool, unsign
bool& mVisited;
};
- eastl::visit(MyVisitor{bVisited}, v);
+ eastl::visit(MyVisitor(bVisited), v);
EATEST_VERIFY(bVisited);
@@ -682,7 +683,7 @@ EA_NO_INLINE int TestVariantVisit2NoInline(const eastl::variant<int, bool>& v0,
struct MyVisitor
{
MyVisitor() = delete;
- MyVisitor(bool& b) : mVisited(b) {}
+ MyVisitor(bool& visited) : mVisited(visited) {};
void operator()(int, int) { mVisited = true; }
void operator()(bool, int) { mVisited = true; }
@@ -692,7 +693,7 @@ EA_NO_INLINE int TestVariantVisit2NoInline(const eastl::variant<int, bool>& v0,
bool& mVisited;
};
- eastl::visit(MyVisitor{bVisited}, v0, v1);
+ eastl::visit(MyVisitor(bVisited), v0, v1);
EATEST_VERIFY(bVisited);
@@ -708,7 +709,7 @@ EA_NO_INLINE int TestVariantVisit3tNoInline(const eastl::variant<int, bool>& v0,
struct MyVisitor
{
MyVisitor() = delete;
- MyVisitor(bool& b) : mVisited(b) {}
+ MyVisitor(bool& visited) : mVisited(visited) {};
void operator()(int, int, int) { mVisited = true; }
void operator()(bool, int, int) { mVisited = true; }
@@ -723,38 +724,101 @@ EA_NO_INLINE int TestVariantVisit3tNoInline(const eastl::variant<int, bool>& v0,
bool& mVisited;
};
- eastl::visit(MyVisitor{bVisited}, v0, v1, v2);
+ eastl::visit(MyVisitor(bVisited), v0, v1, v2);
EATEST_VERIFY(bVisited);
return nErrorCount;
}
-int TestVariantVisitor()
+int TestVariantVisitorOverloaded()
{
using namespace eastl;
int nErrorCount = 0;
using v_t = variant<int, string, double, long>;
+ v_t arr[] = {42, "jean", 42.0, 42L};
+ v_t v{42.0};
+
+
+ #ifdef __cpp_deduction_guides
+ {
+ int count = 0;
+
+ for (auto& e : arr)
+ {
+ eastl::visit(
+ overloaded{
+ [&](int) { count++; },
+ [&](string) { count++; },
+ [&](double) { count++; },
+ [&](long) { count++; }},
+ e
+ );
+ }
+
+ VERIFY(count == EAArrayCount(arr));
+ }
+
+ {
+ double visitedValue = 0.0f;
+
+ eastl::visit(
+ overloaded{
+ [](int) { },
+ [](string) { },
+ [&](double d) { visitedValue = d; },
+ [](long) { }},
+ v
+ );
+
+ VERIFY(visitedValue == 42.0f);
+ }
+
+ #endif
+
+ {
+ int count = 0;
+
+ for (auto& e : arr)
+ {
+ eastl::visit(
+ eastl::make_overloaded(
+ [&](int) { count++; },
+ [&](string) { count++; },
+ [&](double) { count++; },
+ [&](long) { count++; }),
+ e
+ );
+ }
- // TODO(rparolin): When we have a C++17 compiler
- //
- // template deduction guides test
- // template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
- // template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
+ VERIFY(count == EAArrayCount(arr));
+ }
+
+ {
+ double visitedValue = 0.0f;
- // {
- // v_t arr[] = {42, "rob", 42.0, 42L};
+ eastl::visit(
+ eastl::make_overloaded(
+ [](int) { },
+ [](string) { },
+ [&](double d) { visitedValue = d; },
+ [](long) { }),
+ v
+ );
- // int count = 0;
- // for (auto& e : arr)
- // {
- // eastl::visit(overloaded{[&](int) { count++; },
- // [&](string) { count++; },
- // [&](double) { count++; },
- // [&](long) { count++; }}, e);
- // }
- // }
+ VERIFY(visitedValue == 42.0f);
+ }
+
+ return nErrorCount;
+}
+
+int TestVariantVisitor()
+{
+ using namespace eastl;
+ int nErrorCount = 0;
+
+ using v_t = variant<int, string, double, long>;
{
v_t arr[] = {42, "hello", 42.0, 42L};
@@ -982,7 +1046,7 @@ int TestVariantVisitor()
struct MultipleVisitor
{
MultipleVisitor() = delete;
- MultipleVisitor(bool& b) : mVisited(b) {}
+ MultipleVisitor(bool& visited) : mVisited(visited) {};
void operator()(int, int) { mVisited = true; }
void operator()(int, bool) {}
@@ -992,11 +1056,11 @@ int TestVariantVisitor()
bool& mVisited;
};
- visit(MultipleVisitor{bVisited}, v0, v1);
+ visit(MultipleVisitor(bVisited), v0, v1);
EATEST_VERIFY(bVisited);
bVisited = false;
- visit<void>(MultipleVisitor{bVisited}, v0, v1);
+ visit<void>(MultipleVisitor(bVisited), v0, v1);
EATEST_VERIFY(bVisited);
}
@@ -1742,6 +1806,7 @@ int TestVariant()
nErrorCount += TestVariantEmplace();
nErrorCount += TestVariantRelOps();
nErrorCount += TestVariantInplaceCtors();
+ nErrorCount += TestVariantVisitorOverloaded();
nErrorCount += TestVariantVisitor();
nErrorCount += TestVariantAssignment();
nErrorCount += TestVariantMoveOnly();
@@ -1756,13 +1821,3 @@ int TestVariant()
#else
int TestVariant() { return 0; }
#endif
-
-
-
-
-
-
-
-
-
-
diff --git a/EASTL/test/source/TestVector.cpp b/EASTL/test/source/TestVector.cpp
index 0fe719d..69cdb52 100644
--- a/EASTL/test/source/TestVector.cpp
+++ b/EASTL/test/source/TestVector.cpp
@@ -1258,6 +1258,84 @@ int TestVector()
EATEST_VERIFY(!(intArray1 > intArray2));
}
+ // three way comparison operator
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ {
+ using namespace eastl;
+
+ vector<int> intArray1(10);
+ vector<int> intArray2(10);
+
+ for (i = 0; i < intArray1.size(); i++)
+ {
+ intArray1[i] = (int)i; // Make intArray1 equal to intArray2.
+ intArray2[i] = (int)i;
+ }
+
+ // Verify equality between intArray1 and intArray2
+ EATEST_VERIFY((intArray1 <=> intArray2) == 0);
+ EATEST_VERIFY(!((intArray1 <=> intArray2) != 0));
+ EATEST_VERIFY((intArray1 <=> intArray2) <= 0);
+ EATEST_VERIFY((intArray1 <=> intArray2) >= 0);
+ EATEST_VERIFY(!((intArray1 <=> intArray2) < 0));
+ EATEST_VERIFY(!((intArray1 <=> intArray2) > 0));
+
+ intArray1.push_back(100); // Make intArray1 less than intArray2.
+ intArray2.push_back(101);
+
+ // Verify intArray1 < intArray2
+ EATEST_VERIFY(!((intArray1 <=> intArray2) == 0));
+ EATEST_VERIFY((intArray1 <=> intArray2) != 0);
+ EATEST_VERIFY((intArray1 <=> intArray2) <= 0);
+ EATEST_VERIFY(!((intArray1 <=> intArray2) >= 0));
+ EATEST_VERIFY(((intArray1 <=> intArray2) < 0));
+ EATEST_VERIFY(!((intArray1 <=> intArray2) > 0));
+
+ for (i = 0; i < 3; i++) // Make the length of intArray2 less than intArray1
+ intArray2.pop_back();
+
+ // Verify intArray2.size() < intArray1.size() and intArray2 is a subset of intArray1
+ EATEST_VERIFY(!((intArray1 <=> intArray2) == 0));
+ EATEST_VERIFY((intArray1 <=> intArray2) != 0);
+ EATEST_VERIFY((intArray1 <=> intArray2) >= 0);
+ EATEST_VERIFY(!((intArray1 <=> intArray2) <= 0));
+ EATEST_VERIFY(((intArray1 <=> intArray2) > 0));
+ EATEST_VERIFY(!((intArray1 <=> intArray2) < 0));
+ }
+
+ {
+ using namespace eastl;
+
+ vector<int> intArray1 = {1, 2, 3, 4, 5, 6, 7};
+ vector<int> intArray2 = {7, 6, 5, 4, 3, 2, 1};
+ vector<int> intArray3 = {1, 2, 3, 4};
+
+ struct weak_ordering_vector
+ {
+ vector<int> vec;
+ inline std::weak_ordering operator<=>(const weak_ordering_vector& b) const { return vec <=> b.vec; }
+ };
+
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray1}, weak_ordering_vector{intArray2}) == std::weak_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray3}, weak_ordering_vector{intArray1}) == std::weak_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray2}, weak_ordering_vector{intArray1}) == std::weak_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray2}, weak_ordering_vector{intArray3}) == std::weak_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray1}, weak_ordering_vector{intArray1}) == std::weak_ordering::equivalent);
+
+ struct strong_ordering_vector
+ {
+ vector<int> vec;
+ inline std::strong_ordering operator<=>(const strong_ordering_vector& b) const { return vec <=> b.vec; }
+ };
+
+ EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray1}, strong_ordering_vector{intArray2}) == std::strong_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray3}, strong_ordering_vector{intArray1}) == std::strong_ordering::less);
+ EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray2}, strong_ordering_vector{intArray1}) == std::strong_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray2}, strong_ordering_vector{intArray3}) == std::strong_ordering::greater);
+ EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray1}, strong_ordering_vector{intArray1}) == std::strong_ordering::equal);
+ }
+#endif
+
{
using namespace eastl;
@@ -1317,7 +1395,7 @@ int TestVector()
eastl::vector<TestObject> toTest;
// InputIterator
- demoted_iterator<TestObject*, eastl::forward_iterator_tag> toInput(&to);
+ demoted_iterator<TestObject*, EASTL_ITC_NS::forward_iterator_tag> toInput(&to);
toTest.assign(toInput, toInput);
// ForwardIterator
@@ -1637,7 +1715,7 @@ int TestVector()
{
struct iterator
{
- typedef eastl::input_iterator_tag iterator_category;
+ typedef EASTL_ITC_NS::input_iterator_tag iterator_category;
typedef int value_type;
typedef ptrdiff_t difference_type;
typedef int* pointer;
@@ -1718,20 +1796,24 @@ int TestVector()
{
eastl::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- eastl::erase(v, 5);
+ auto numErased = eastl::erase(v, 5);
VERIFY((v == eastl::vector<int> {1, 2, 3, 4, 6, 7, 8, 9}));
+ VERIFY(numErased == 1);
- eastl::erase(v, 2);
+ numErased = eastl::erase(v, 2);
VERIFY((v == eastl::vector<int> {1, 3, 4, 6, 7, 8, 9}));
+ VERIFY(numErased == 1);
- eastl::erase(v, 9);
+ numErased = eastl::erase(v, 9);
VERIFY((v == eastl::vector<int> {1, 3, 4, 6, 7, 8}));
+ VERIFY(numErased == 1);
}
{
eastl::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- eastl::erase_if(v, [](auto i) { return i % 2 == 0; });
+ auto numErased = eastl::erase_if(v, [](auto i) { return i % 2 == 0; });
VERIFY((v == eastl::vector<int>{1, 3, 5, 7, 9}));
+ VERIFY(numErased == 4);
}
}
diff --git a/EASTL/test/source/main.cpp b/EASTL/test/source/main.cpp
index 8ce7c1b..132bab1 100644
--- a/EASTL/test/source/main.cpp
+++ b/EASTL/test/source/main.cpp
@@ -145,7 +145,7 @@ int EAMain(int argc, char* argv[])
testSuite.AddTest("VectorSet", TestVectorSet);
testSuite.AddTest("AtomicBasic", TestAtomicBasic);
testSuite.AddTest("AtomicAsm", TestAtomicAsm);
- testSuite.AddTest("TestBitcast", TestBitcast);
+ testSuite.AddTest("Bitcast", TestBitcast);
nErrorCount += testSuite.Run();