diff options
Diffstat (limited to 'EASTL/test/source/TestExtra.cpp')
-rw-r--r-- | EASTL/test/source/TestExtra.cpp | 610 |
1 files changed, 608 insertions, 2 deletions
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; } |