Merge remote-tracking branch 'upstream/development' into nvsickle/DomPatch

This commit is contained in:
Nicholas Van Sickle
2022-02-07 10:51:43 -08:00
2456 changed files with 259183 additions and 105897 deletions
@@ -0,0 +1,202 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/concepts/concepts.h>
namespace UnitTest
{
class ConceptsTestFixture
: public ScopedAllocatorSetupFixture
{};
TEST_F(ConceptsTestFixture, GeneralConcepts)
{
// concept same_as
static_assert(AZStd::same_as<ConceptsTestFixture, ConceptsTestFixture>);
static_assert(!AZStd::same_as<ConceptsTestFixture, ScopedAllocatorSetupFixture>);
// concept derived_from
static_assert(AZStd::derived_from<ConceptsTestFixture, ScopedAllocatorSetupFixture>);
static_assert(!AZStd::derived_from<ScopedAllocatorSetupFixture, ConceptsTestFixture>);
// concept convertible_to
static_assert(AZStd::convertible_to<ConceptsTestFixture&, ScopedAllocatorSetupFixture&>);
static_assert(!AZStd::convertible_to<ScopedAllocatorSetupFixture&, ConceptsTestFixture&>);
// Test structs to validate common_reference_with and common_with concepts
struct Base {};
struct TestBase : Base {};
struct NoMove
{
NoMove(NoMove&&) = delete;
NoMove& operator=(NoMove&&) = delete;
};
struct NoDestructible
{
~NoDestructible() = delete;
};
struct NoDefaultInitializable
{
NoDefaultInitializable(bool);
};
struct CopyOnly
{
CopyOnly(const CopyOnly&) = default;
};
struct MoveOnly
{
MoveOnly(MoveOnly&&) = default;
};
struct MoveableButNotCopyable
{
MoveableButNotCopyable(MoveableButNotCopyable&&) = default;
MoveableButNotCopyable& operator=(MoveableButNotCopyable&&) = default;
};
// concept common_reference_with
static_assert(AZStd::common_reference_with<TestBase&, Base&>);
static_assert(AZStd::same_as<AZStd::common_reference_t<const TestBase&, Base&>, const Base&>);
static_assert(!AZStd::common_reference_with<AllocatorsTestFixture, ScopedAllocatorSetupFixture>);
// concept common_with
static_assert(AZStd::common_with<TestBase, Base>);
static_assert(!AZStd::common_with<AllocatorsTestFixture, AllocatorsBenchmarkFixture>);
// arithmetic concepts
// concept integral
static_assert(AZStd::integral<int>);
static_assert(!AZStd::integral<float>);
// concept signed_integral
static_assert(AZStd::signed_integral<int>);
static_assert(!AZStd::signed_integral<unsigned int>);
static_assert(!AZStd::signed_integral<float>);
// concept signed_integral
static_assert(AZStd::unsigned_integral<unsigned int>);
static_assert(!AZStd::unsigned_integral<int>);
static_assert(!AZStd::unsigned_integral<float>);
// concept floating_point
static_assert(AZStd::floating_point<float>);
static_assert(!AZStd::floating_point<int>);
// concept assignable_from
static_assert(AZStd::assignable_from<Base&, TestBase>);
static_assert(!AZStd::assignable_from<TestBase&, Base>);
// concept swappable
static_assert(AZStd::swappable<Base>);
static_assert(!AZStd::swappable<NoMove>);
static_assert(AZStd::swappable_with<Base, Base>);
static_assert(!AZStd::swappable_with<NoMove, Base>);
// concept destructible
static_assert(AZStd::destructible<Base>);
static_assert(!AZStd::destructible<NoDestructible>);
// concept constructible_from
static_assert(AZStd::constructible_from<NoDefaultInitializable, bool>);
static_assert(!AZStd::constructible_from<NoDefaultInitializable>);
// concept default_initializable
static_assert(AZStd::default_initializable<Base>);
static_assert(!AZStd::default_initializable<NoDefaultInitializable>);
// concept move_constructible
static_assert(AZStd::move_constructible<MoveOnly>);
static_assert(!AZStd::move_constructible<NoMove>);
// concept copy_constructible
static_assert(AZStd::copy_constructible<CopyOnly>);
static_assert(!AZStd::copy_constructible<MoveOnly>);
// concept equality_comparable
static_assert(AZStd::equality_comparable<AZStd::string_view>);
static_assert(!AZStd::equality_comparable<Base>);
static_assert(AZStd::equality_comparable_with<AZStd::string_view, const char*>);
static_assert(!AZStd::equality_comparable_with<Base, TestBase>);
static_assert(!AZStd::equality_comparable_with<Base, const char*>);
// concept totally_ordered
static_assert(AZStd::totally_ordered<AZStd::string_view>);
static_assert(!AZStd::totally_ordered<Base>);
static_assert(AZStd::totally_ordered_with<AZStd::string_view, const char*>);
static_assert(!AZStd::totally_ordered_with<Base, TestBase>);
static_assert(!AZStd::totally_ordered_with<Base, const char*>);
// concept movable
static_assert(AZStd::movable<MoveableButNotCopyable>);
static_assert(!AZStd::movable<NoMove>);
// concept copyable
static_assert(AZStd::copyable<Base>);
static_assert(!AZStd::copyable<MoveableButNotCopyable>);
// concept semiregular
static_assert(AZStd::semiregular<Base>);
static_assert(!AZStd::semiregular<MoveableButNotCopyable>);
// concept regular
static_assert(AZStd::regular<AZStd::string_view>);
static_assert(!AZStd::regular<Base>);
// concept invocable
static_assert(AZStd::invocable<decltype(AZStd::ranges::swap), int&, int&>);
static_assert(!AZStd::invocable<decltype(AZStd::ranges::swap), int&, float&>);
// concept predicate
auto BooleanPredicate = [](double) -> int
{
return 0;
};
auto BasePredicate = [](int) -> Base
{
return Base{};
};
static_assert(AZStd::predicate<decltype(BooleanPredicate), double>);
static_assert(!AZStd::predicate<decltype(BooleanPredicate), Base>);
static_assert(!AZStd::predicate<decltype(BasePredicate), int>);
// concept relation
struct RelationPredicate
{
bool operator()(AZStd::string_view, Base) const;
bool operator()(Base, AZStd::string_view) const;
bool operator()(AZStd::string_view, AZStd::string_view) const;
bool operator()(Base, Base) const;
// non-complete relation
bool operator()(Base, int) const;
bool operator()(int, Base) const;
};
static_assert(AZStd::relation<RelationPredicate, AZStd::string_view, Base>);
static_assert(AZStd::relation<RelationPredicate, Base, AZStd::string_view>);
static_assert(!AZStd::relation<RelationPredicate, int, Base>);
static_assert(!AZStd::relation<RelationPredicate, Base, int>);
//concept equivalence_relation
static_assert(AZStd::equivalence_relation<RelationPredicate, AZStd::string_view, Base>);
static_assert(AZStd::equivalence_relation<RelationPredicate, Base, AZStd::string_view>);
static_assert(!AZStd::equivalence_relation<RelationPredicate, int, Base>);
static_assert(!AZStd::equivalence_relation<RelationPredicate, Base, int>);
//concept strict_weak_order
static_assert(AZStd::strict_weak_order<RelationPredicate, AZStd::string_view, Base>);
static_assert(AZStd::strict_weak_order<RelationPredicate, Base, AZStd::string_view>);
static_assert(!AZStd::strict_weak_order<RelationPredicate, int, Base>);
static_assert(!AZStd::strict_weak_order<RelationPredicate, Base, int>);
}
}
+2 -2
View File
@@ -1400,7 +1400,7 @@ namespace UnitTest
{
using ContainerType = ContainerTemplate<int32_t, AZStd::hash<int32_t>, AZStd::equal_to<int32_t>, AZ::AZStdIAllocator>;
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocatorAllocate* allocatorInstance)
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
{
ContainerType allocatorSet(intList, AZStd::hash<int32_t>{}, AZStd::equal_to<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
return allocatorSet;
@@ -1798,7 +1798,7 @@ namespace UnitTest
{
using ContainerType = ContainerTemplate<int32_t, int32_t, AZStd::hash<int32_t>, AZStd::equal_to<int32_t>, AZ::AZStdIAllocator>;
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocatorAllocate* allocatorInstance)
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
{
ContainerType allocatorMap(intList, AZStd::hash<int32_t>{}, AZStd::equal_to<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
return allocatorMap;
+76 -86
View File
@@ -6,6 +6,7 @@
*
*/
#include "UserTypes.h"
#include <AzCore/std/concepts/concepts.h>
#include <AzCore/std/iterator.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/containers/array.h>
@@ -13,13 +14,11 @@
#include <AzCore/std/containers/set.h>
#include <AzCore/std/utils.h>
using namespace AZStd;
using namespace UnitTestInternal;
namespace UnitTest
{
class Iterators
: public AllocatorsFixture
: public ScopedAllocatorSetupFixture
{
};
@@ -28,30 +27,30 @@ namespace UnitTest
{
Container int_container = {{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }};
typename Container::iterator iter_begin = begin(int_container);
typename Container::iterator iter_begin = AZStd::begin(int_container);
EXPECT_EQ(*iter_begin, 0);
EXPECT_EQ(*next(iter_begin), 1);
EXPECT_EQ(*next(iter_begin, 2), 2);
EXPECT_EQ(*AZStd::next(iter_begin), 1);
EXPECT_EQ(*AZStd::next(iter_begin, 2), 2);
++iter_begin;
EXPECT_EQ(*iter_begin, 1);
typename Container::iterator iter_end = end(int_container);
EXPECT_EQ(iter_end, int_container.end());
EXPECT_EQ(*prev(iter_end), 9);
EXPECT_EQ(*prev(iter_end, 2), 8);
EXPECT_EQ(*AZStd::prev(iter_end), 9);
EXPECT_EQ(*AZStd::prev(iter_end, 2), 8);
--iter_end;
EXPECT_EQ(*iter_end, 9);
typename Container::reverse_iterator iter_rbegin = rbegin(int_container);
typename Container::reverse_iterator iter_rbegin = AZStd::rbegin(int_container);
EXPECT_EQ(*iter_rbegin, 9);
EXPECT_EQ(*next(iter_rbegin), 8);
EXPECT_EQ(*next(iter_rbegin, 2), 7);
EXPECT_EQ(*AZStd::next(iter_rbegin), 8);
EXPECT_EQ(*AZStd::next(iter_rbegin, 2), 7);
++iter_rbegin;
EXPECT_EQ(*iter_rbegin, 8);
typename Container::reverse_iterator iter_rend = rend(int_container);
EXPECT_EQ(*prev(iter_rend), 0);
EXPECT_EQ(*prev(iter_rend, 2), 1);
typename Container::reverse_iterator iter_rend = AZStd::rend(int_container);
EXPECT_EQ(*AZStd::prev(iter_rend), 0);
EXPECT_EQ(*AZStd::prev(iter_rend, 2), 1);
--iter_rend;
EXPECT_EQ(*iter_rend, 0);
@@ -65,30 +64,30 @@ namespace UnitTest
{
Container int_container = {{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }};
typename Container::const_iterator iter_cbegin = cbegin(int_container);
typename Container::const_iterator iter_cbegin = AZStd::cbegin(int_container);
EXPECT_EQ(*iter_cbegin, 0);
EXPECT_EQ(*next(iter_cbegin), 1);
EXPECT_EQ(*next(iter_cbegin, 2), 2);
EXPECT_EQ(*AZStd::next(iter_cbegin), 1);
EXPECT_EQ(*AZStd::next(iter_cbegin, 2), 2);
++iter_cbegin;
EXPECT_EQ(*iter_cbegin, 1);
typename Container::const_iterator iter_cend = cend(int_container);
typename Container::const_iterator iter_cend = AZStd::cend(int_container);
EXPECT_EQ(iter_cend, int_container.cend());
EXPECT_EQ(*prev(iter_cend), 9);
EXPECT_EQ(*prev(iter_cend, 2), 8);
EXPECT_EQ(*AZStd::prev(iter_cend), 9);
EXPECT_EQ(*AZStd::prev(iter_cend, 2), 8);
--iter_cend;
EXPECT_EQ(*iter_cend, 9);
typename Container::const_reverse_iterator iter_crbegin = crbegin(int_container);
typename Container::const_reverse_iterator iter_crbegin = AZStd::crbegin(int_container);
EXPECT_EQ(*iter_crbegin, 9);
EXPECT_EQ(*next(iter_crbegin), 8);
EXPECT_EQ(*next(iter_crbegin, 2), 7);
EXPECT_EQ(*AZStd::next(iter_crbegin), 8);
EXPECT_EQ(*AZStd::next(iter_crbegin, 2), 7);
++iter_crbegin;
EXPECT_EQ(*iter_crbegin, 8);
typename Container::const_reverse_iterator iter_crend = crend(int_container);
EXPECT_EQ(*prev(iter_crend), 0);
EXPECT_EQ(*prev(iter_crend, 2), 1);
typename Container::const_reverse_iterator iter_crend = AZStd::crend(int_container);
EXPECT_EQ(*AZStd::prev(iter_crend), 0);
EXPECT_EQ(*AZStd::prev(iter_crend, 2), 1);
--iter_crend;
EXPECT_EQ(*iter_crend, 0);
}
@@ -98,15 +97,15 @@ namespace UnitTest
{
const ConstContainer const_int_container = {{ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }};
typename ConstContainer::const_iterator const_iter_begin = begin(const_int_container);
typename ConstContainer::const_iterator const_iter_begin = AZStd::begin(const_int_container);
EXPECT_EQ(*const_iter_begin, 10);
EXPECT_EQ(*next(const_iter_begin), 11);
EXPECT_EQ(*next(const_iter_begin, 2), 12);
EXPECT_EQ(*AZStd::next(const_iter_begin), 11);
EXPECT_EQ(*AZStd::next(const_iter_begin, 2), 12);
typename ConstContainer::const_iterator const_iter_end = end(const_int_container);
typename ConstContainer::const_iterator const_iter_end = AZStd::end(const_int_container);
EXPECT_EQ(const_iter_end, const_int_container.end());
EXPECT_EQ(*prev(const_iter_end), 19);
EXPECT_EQ(*prev(const_iter_end, 2), 18);
EXPECT_EQ(*AZStd::prev(const_iter_end), 19);
EXPECT_EQ(*AZStd::prev(const_iter_end, 2), 18);
}
TEST_F(Iterators, FunctionWrappers_MutableContainers)
@@ -136,87 +135,78 @@ namespace UnitTest
{
int int_array[10] = { 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 };
EXPECT_EQ(*begin(int_array), 20);
EXPECT_EQ(*next(begin(int_array)), 21);
EXPECT_EQ(*next(begin(int_array), 2), 22);
EXPECT_EQ(*AZStd::begin(int_array), 20);
EXPECT_EQ(*AZStd::next(AZStd::begin(int_array)), 21);
EXPECT_EQ(*AZStd::next(AZStd::begin(int_array), 2), 22);
EXPECT_EQ(end(int_array) - AZ_ARRAY_SIZE(int_array), begin(int_array));
EXPECT_EQ(*prev(end(int_array)), 29);
EXPECT_EQ(*prev(end(int_array), 2), 28);
EXPECT_EQ(AZStd::end(int_array) - AZ_ARRAY_SIZE(int_array), AZStd::begin(int_array));
EXPECT_EQ(*AZStd::prev(AZStd::end(int_array)), 29);
EXPECT_EQ(*AZStd::prev(AZStd::end(int_array), 2), 28);
EXPECT_EQ(*rbegin(int_array), 29);
EXPECT_EQ(*next(rbegin(int_array)), 28);
EXPECT_EQ(*next(rbegin(int_array), 2), 27);
EXPECT_EQ(*AZStd::rbegin(int_array), 29);
EXPECT_EQ(*AZStd::next(AZStd::rbegin(int_array)), 28);
EXPECT_EQ(*AZStd::next(AZStd::rbegin(int_array), 2), 27);
EXPECT_EQ(*prev(rend(int_array)), 20);
EXPECT_EQ(*prev(rend(int_array), 2), 21);
EXPECT_EQ(*AZStd::prev(AZStd::rend(int_array)), 20);
EXPECT_EQ(*AZStd::prev(AZStd::rend(int_array), 2), 21);
EXPECT_EQ(*crbegin(int_array), 29);
EXPECT_EQ(*next(crbegin(int_array)), 28);
EXPECT_EQ(*next(crbegin(int_array), 2), 27);
EXPECT_EQ(*AZStd::crbegin(int_array), 29);
EXPECT_EQ(*AZStd::next(AZStd::crbegin(int_array)), 28);
EXPECT_EQ(*AZStd::next(AZStd::crbegin(int_array), 2), 27);
EXPECT_EQ(*prev(crend(int_array)), 20);
EXPECT_EQ(*prev(crend(int_array), 2), 21);
EXPECT_EQ(*AZStd::prev(AZStd::crend(int_array)), 20);
EXPECT_EQ(*AZStd::prev(AZStd::crend(int_array), 2), 21);
//verify we can successfully modify the value in a non-const iterator
*begin(int_array) = -42;
EXPECT_EQ(*begin(int_array), -42);
*AZStd::begin(int_array) = -42;
EXPECT_EQ(*AZStd::begin(int_array), -42);
}
TEST_F(Iterators, FunctionWrappers_ConstRawArray)
{
const int const_int_array[10] = { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 };
EXPECT_EQ(*cbegin(const_int_array), 30);
EXPECT_EQ(*next(cbegin(const_int_array)), 31);
EXPECT_EQ(*next(cbegin(const_int_array), 2), 32);
EXPECT_EQ(*AZStd::cbegin(const_int_array), 30);
EXPECT_EQ(*AZStd::next(AZStd::cbegin(const_int_array)), 31);
EXPECT_EQ(*AZStd::next(AZStd::cbegin(const_int_array), 2), 32);
EXPECT_EQ(cend(const_int_array) - AZ_ARRAY_SIZE(const_int_array), cbegin(const_int_array));
EXPECT_EQ(*prev(cend(const_int_array)), 39);
EXPECT_EQ(*prev(cend(const_int_array), 2), 38);
EXPECT_EQ(AZStd::cend(const_int_array) - AZ_ARRAY_SIZE(const_int_array), AZStd::cbegin(const_int_array));
EXPECT_EQ(*AZStd::prev(AZStd::cend(const_int_array)), 39);
EXPECT_EQ(*AZStd::prev(AZStd::cend(const_int_array), 2), 38);
}
TEST_F(Iterators, IteratorTraits_ResolveAtCompileTime)
{
using list_type = AZStd::list<int>;
static_assert(AZStd::Internal::has_iterator_category_v<typename list_type::iterator>);
static_assert(AZStd::Internal::has_iterator_type_aliases_v<typename list_type::iterator>);
constexpr bool list_type_iterator_type_aliases = AZStd::Internal::has_iterator_type_aliases_v<typename list_type::iterator>;
static_assert(AZStd::is_convertible_v<AZStd::Internal::iterator_traits_type_aliases<typename list_type::iterator, list_type_iterator_type_aliases>::iterator_category,
AZStd::input_iterator_tag>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::iterator>::iterator_category, bidirectional_iterator_tag>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::iterator>::value_type, int>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::iterator>::difference_type, AZStd::ptrdiff_t>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::iterator>::pointer, int*>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::iterator>::reference, int&>);
static_assert(AZStd::Internal::is_input_iterator_v<typename list_type::iterator>);
static_assert(!AZStd::Internal::has_iterator_concept_v<AZStd::iterator_traits<typename list_type::iterator>>);
static_assert(!AZStd::Internal::satisfies_contiguous_iterator_concept_v<typename list_type::iterator>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::iterator>::iterator_category, AZStd::bidirectional_iterator_tag>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::iterator>::value_type, int>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::iterator>::difference_type, AZStd::ptrdiff_t>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::iterator>::pointer, int*>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::iterator>::reference, int&>);
static_assert(AZStd::input_iterator<typename list_type::iterator>);
static_assert(!AZStd::contiguous_iterator<typename list_type::iterator>);
static_assert(AZStd::Internal::has_iterator_category_v<typename list_type::const_iterator>);
static_assert(AZStd::Internal::has_iterator_type_aliases_v<typename list_type::const_iterator>);
constexpr bool list_type_const_iterator_type_aliases = AZStd::Internal::has_iterator_type_aliases_v<typename list_type::const_iterator>;
static_assert(AZStd::is_convertible_v<AZStd::Internal::iterator_traits_type_aliases<typename list_type::iterator, list_type_const_iterator_type_aliases>::iterator_category,
AZStd::input_iterator_tag>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::iterator_category, bidirectional_iterator_tag>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::value_type, int>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::difference_type, AZStd::ptrdiff_t>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::pointer, const int*>);
static_assert(is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::reference, const int&>);
static_assert(AZStd::Internal::is_input_iterator_v<typename list_type::const_iterator>);
static_assert(!AZStd::Internal::has_iterator_concept_v<AZStd::iterator_traits<typename list_type::const_iterator>>);
static_assert(!AZStd::Internal::satisfies_contiguous_iterator_concept_v<typename list_type::const_iterator>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::iterator_category, AZStd::bidirectional_iterator_tag>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::value_type, int>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::difference_type, AZStd::ptrdiff_t>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::pointer, const int*>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<typename list_type::const_iterator>::reference, const int&>);
static_assert(AZStd::input_iterator<typename list_type::const_iterator>);
static_assert(!AZStd::contiguous_iterator<typename list_type::const_iterator>);
using pointer_type = const char*;
static_assert(AZStd::Internal::has_iterator_category_v<AZStd::iterator_traits<pointer_type>>);
static_assert(AZStd::Internal::has_iterator_type_aliases_v<AZStd::iterator_traits<pointer_type>>);
static_assert(is_same_v<AZStd::iterator_traits<pointer_type>::iterator_concept, contiguous_iterator_tag>);
static_assert(is_same_v<AZStd::iterator_traits<pointer_type>::iterator_category, random_access_iterator_tag>);
static_assert(is_same_v<AZStd::iterator_traits<pointer_type>::value_type, char>);
static_assert(is_same_v<AZStd::iterator_traits<pointer_type>::difference_type, AZStd::ptrdiff_t>);
static_assert(is_same_v<AZStd::iterator_traits<pointer_type>::pointer, const char*>);
static_assert(is_same_v<AZStd::iterator_traits<pointer_type>::reference, const char&>);
static_assert(AZStd::Internal::has_iterator_concept_v<AZStd::iterator_traits<pointer_type>>);
static_assert(AZStd::Internal::satisfies_contiguous_iterator_concept_v<pointer_type>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<pointer_type>::iterator_concept, AZStd::contiguous_iterator_tag>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<pointer_type>::iterator_category, AZStd::random_access_iterator_tag>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<pointer_type>::value_type, char>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<pointer_type>::difference_type, AZStd::ptrdiff_t>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<pointer_type>::pointer, const char*>);
static_assert(AZStd::is_same_v<AZStd::iterator_traits<pointer_type>::reference, const char&>);
static_assert(AZStd::contiguous_iterator<pointer_type>);
}
}
@@ -1082,7 +1082,7 @@ namespace UnitTest
{
using ContainerType = ContainerTemplate<int32_t, AZStd::less<int32_t>, AZ::AZStdIAllocator>;
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocatorAllocate* allocatorInstance)
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
{
ContainerType allocatorSet(intList, AZStd::less<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
return allocatorSet;
@@ -1503,7 +1503,7 @@ namespace UnitTest
{
using ContainerType = ContainerTemplate<int32_t, int32_t, AZStd::less<int32_t>, AZ::AZStdIAllocator>;
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocatorAllocate* allocatorInstance)
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
{
ContainerType allocatorMap(intList, AZStd::less<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
return allocatorMap;
@@ -0,0 +1,583 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/std/ranges/ranges.h>
namespace UnitTest
{
class RangesTestFixture
: public ScopedAllocatorSetupFixture
{};
struct RangeLikeCustomizationPoint {};
RangeLikeCustomizationPoint* begin(RangeLikeCustomizationPoint& rangeLike)
{
return &rangeLike;
}
RangeLikeCustomizationPoint* end(RangeLikeCustomizationPoint& rangeLike)
{
return &rangeLike;
}
const RangeLikeCustomizationPoint* cbegin(const RangeLikeCustomizationPoint& rangeLike)
{
return &rangeLike;
}
const RangeLikeCustomizationPoint* cend(const RangeLikeCustomizationPoint& rangeLike)
{
return &rangeLike;
}
RangeLikeCustomizationPoint* rbegin(RangeLikeCustomizationPoint& rangeLike)
{
return &rangeLike;
}
RangeLikeCustomizationPoint* rend(RangeLikeCustomizationPoint& rangeLike)
{
return &rangeLike;
}
const RangeLikeCustomizationPoint* crbegin(const RangeLikeCustomizationPoint& rangeLike)
{
return &rangeLike;
}
const RangeLikeCustomizationPoint* crend(const RangeLikeCustomizationPoint& rangeLike)
{
return &rangeLike;
}
constexpr size_t size(const RangeLikeCustomizationPoint&)
{
return 0;
}
constexpr size_t size(RangeLikeCustomizationPoint&)
{
return 0;
}
// range access
TEST_F(RangesTestFixture, RangesBegin_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
ArrayExtentType extentArray{};
EXPECT_EQ(extentArray + 0, AZStd::ranges::begin(extentArray));
}
TEST_F(RangesTestFixture, RangesBegin_DoesNotCompile_WithNoExtentArray)
{
using ArrayNoExtentType = int[];
static_assert(!AZStd::invocable<decltype(AZStd::ranges::begin), ArrayNoExtentType>);
}
TEST_F(RangesTestFixture, RangesBegin_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.begin(), AZStd::ranges::begin(strView));
}
TEST_F(RangesTestFixture, RangesBegin_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::begin(rangeLike));
}
TEST_F(RangesTestFixture, RangesEnd_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
ArrayExtentType extentArray{};
EXPECT_EQ(extentArray + 5, AZStd::ranges::end(extentArray));
}
TEST_F(RangesTestFixture, RangesEnd_DoesNotCompile_WithNoExtentArray)
{
using ArrayNoExtentType = int[];
static_assert(!AZStd::invocable<decltype(AZStd::ranges::end), ArrayNoExtentType>);
}
TEST_F(RangesTestFixture, RangesEnd_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.end(), AZStd::ranges::end(strView));
}
TEST_F(RangesTestFixture, RangesEnd_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::end(rangeLike));
}
TEST_F(RangesTestFixture, RangesCBegin_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
ArrayExtentType extentArray{};
EXPECT_EQ(extentArray + 0, AZStd::ranges::cbegin(extentArray));
}
TEST_F(RangesTestFixture, RangesCBegin_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.cbegin(), AZStd::ranges::cbegin(strView));
}
TEST_F(RangesTestFixture, RangesCBegin_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::cbegin(rangeLike));
}
TEST_F(RangesTestFixture, RangesCEnd_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
ArrayExtentType extentArray{};
EXPECT_EQ(extentArray + 5, AZStd::ranges::cend(extentArray));
}
TEST_F(RangesTestFixture, RangesCEnd_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.cend(), AZStd::ranges::cend(strView));
}
TEST_F(RangesTestFixture, RangesCEnd_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::cend(rangeLike));
}
TEST_F(RangesTestFixture, RangesRBegin_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
ArrayExtentType extentArray{};
EXPECT_EQ(extentArray + 5, AZStd::ranges::rbegin(extentArray).base());
}
TEST_F(RangesTestFixture, RangesRBegin_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.rbegin(), AZStd::ranges::rbegin(strView));
}
TEST_F(RangesTestFixture, RangesRBegin_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::rbegin(rangeLike));
}
TEST_F(RangesTestFixture, RangesREnd_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
ArrayExtentType extentArray{};
EXPECT_EQ(extentArray, AZStd::ranges::rend(extentArray).base());
}
TEST_F(RangesTestFixture, RangesREnd_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.rend(), AZStd::ranges::rend(strView));
}
TEST_F(RangesTestFixture, RangesREnd_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::rend(rangeLike));
}
TEST_F(RangesTestFixture, RangesCRBegin_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
ArrayExtentType extentArray{};
EXPECT_EQ(extentArray + 5, AZStd::ranges::crbegin(extentArray).base());
}
TEST_F(RangesTestFixture, RangesCRBegin_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.crbegin(), AZStd::ranges::crbegin(strView));
}
TEST_F(RangesTestFixture, RangesCRBegin_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::crbegin(rangeLike));
}
TEST_F(RangesTestFixture, RangesCREnd_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
ArrayExtentType extentArray{};
EXPECT_EQ(extentArray + 0, AZStd::ranges::crend(extentArray).base());
}
TEST_F(RangesTestFixture, RangesCREnd_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.crend(), AZStd::ranges::crend(strView));
}
TEST_F(RangesTestFixture, RangesCREnd_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::crend(rangeLike));
}
// range access - size
TEST_F(RangesTestFixture, RangesSize_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
constexpr ArrayExtentType extentArray{};
static_assert(5 == AZStd::ranges::size(extentArray));
}
TEST_F(RangesTestFixture, RangesSize_DoesNotCompile_WithNoExtentArray)
{
using ArrayNoExtentType = int[];
static_assert(!AZStd::invocable<decltype(AZStd::ranges::size), ArrayNoExtentType>);
}
TEST_F(RangesTestFixture, RangesSize_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
EXPECT_EQ(strView.size(), AZStd::ranges::size(strView));
}
TEST_F(RangesTestFixture, RangesSize_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(0, AZStd::ranges::size(rangeLike));
}
TEST_F(RangesTestFixture, RangesSSize_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
constexpr ArrayExtentType extentArray{};
static_assert(AZStd::signed_integral<decltype(AZStd::ranges::ssize(extentArray))>);
static_assert(5 == AZStd::ranges::ssize(extentArray));
}
TEST_F(RangesTestFixture, RangesSSize_DoesNotCompile_WithNoExtentArray)
{
using ArrayNoExtentType = int[];
static_assert(!AZStd::invocable<decltype(AZStd::ranges::ssize), ArrayNoExtentType>);
}
TEST_F(RangesTestFixture, RangesSSize_Compiles_WithMemberOverload)
{
AZStd::string_view strView;
static_assert(AZStd::signed_integral<decltype(AZStd::ranges::ssize(strView))>);
EXPECT_EQ(strView.size(), AZStd::ranges::ssize(strView));
}
TEST_F(RangesTestFixture, RangesSSize_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
static_assert(AZStd::signed_integral<decltype(AZStd::ranges::ssize(rangeLike))>);
EXPECT_EQ(0, AZStd::ranges::ssize(rangeLike));
}
// range access - empty
TEST_F(RangesTestFixture, RangesEmpty_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
constexpr ArrayExtentType extentArray{};
static_assert(!AZStd::ranges::empty(extentArray));
}
TEST_F(RangesTestFixture, RangesEmpty_DoesNotCompile_WithNoExtentArray)
{
using ArrayNoExtentType = int[];
static_assert(!AZStd::invocable<decltype(AZStd::ranges::empty), ArrayNoExtentType>);
}
TEST_F(RangesTestFixture, RangesEmpty_Compiles_WithMemberOverload)
{
constexpr AZStd::string_view strView;
static_assert(AZStd::ranges::empty(strView));
}
TEST_F(RangesTestFixture, RangesEmpty_Compiles_WithADL)
{
constexpr RangeLikeCustomizationPoint rangeLike;
static_assert(AZStd::ranges::empty(rangeLike));
}
// range access - data
TEST_F(RangesTestFixture, RangesData_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
constexpr ArrayExtentType extentArray{};
EXPECT_EQ(extentArray, AZStd::ranges::data(extentArray));
}
TEST_F(RangesTestFixture, RangesData_DoesNotCompile_WithNoExtentArray)
{
using ArrayNoExtentType = int[];
static_assert(!AZStd::invocable<decltype(AZStd::ranges::data), ArrayNoExtentType>);
}
TEST_F(RangesTestFixture, RangesData_Compiles_WithMemberOverload)
{
constexpr AZStd::string_view strView;
EXPECT_EQ(strView.data(), AZStd::ranges::data(strView));
}
TEST_F(RangesTestFixture, RangesData_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::data(rangeLike));
}
// range access - cdata
TEST_F(RangesTestFixture, RangesCData_Compiles_WithExtentArray)
{
using ArrayExtentType = int[5];
constexpr ArrayExtentType extentArray{};
EXPECT_EQ(extentArray, AZStd::ranges::cdata(extentArray));
}
TEST_F(RangesTestFixture, RangesCData_DoesNotCompile_WithNoExtentArray)
{
using ArrayNoExtentType = int[];
static_assert(!AZStd::invocable<decltype(AZStd::ranges::cdata), ArrayNoExtentType>);
}
TEST_F(RangesTestFixture, RangesCData_Compiles_WithMemberOverload)
{
constexpr AZStd::string_view strView;
EXPECT_EQ(strView.data(), AZStd::ranges::cdata(strView));
}
TEST_F(RangesTestFixture, RangesCData_Compiles_WithADL)
{
RangeLikeCustomizationPoint rangeLike;
EXPECT_EQ(&rangeLike, AZStd::ranges::cdata(rangeLike));
}
// Ranges TypeTraits Test
TEST_F(RangesTestFixture, RangesTypeTraits_Compiles)
{
// string_view
static_assert(AZStd::same_as<AZStd::ranges::iterator_t<AZStd::string_view>, const char*>);
static_assert(AZStd::same_as<AZStd::ranges::sentinel_t<AZStd::string_view>, const char*>);
static_assert(AZStd::same_as<AZStd::ranges::range_difference_t<AZStd::string_view>, ptrdiff_t>);
static_assert(AZStd::same_as<AZStd::ranges::range_size_t<AZStd::string_view>, size_t>);
static_assert(AZStd::same_as<AZStd::ranges::range_value_t<AZStd::string_view>, char>);
static_assert(AZStd::same_as<AZStd::ranges::range_reference_t<AZStd::string_view>, const char&>);
static_assert(AZStd::same_as<AZStd::ranges::range_rvalue_reference_t<AZStd::string_view>, const char&&>);
// string
static_assert(AZStd::same_as<AZStd::ranges::iterator_t<AZStd::string>, char*>);
static_assert(AZStd::same_as<AZStd::ranges::sentinel_t<AZStd::string>, char*>);
static_assert(AZStd::same_as<AZStd::ranges::range_difference_t<AZStd::string>, ptrdiff_t>);
static_assert(AZStd::same_as<AZStd::ranges::range_size_t<AZStd::string>, size_t>);
static_assert(AZStd::same_as<AZStd::ranges::range_value_t<AZStd::string>, char>);
static_assert(AZStd::same_as<AZStd::ranges::range_reference_t<AZStd::string>, char&>);
static_assert(AZStd::same_as<AZStd::ranges::range_rvalue_reference_t<AZStd::string>, char&&>);
// int array type
using ArrayExtentType = int[5];
static_assert(AZStd::same_as<AZStd::ranges::iterator_t<ArrayExtentType>, int*>);
static_assert(AZStd::same_as<AZStd::ranges::sentinel_t<ArrayExtentType>, int*>);
static_assert(AZStd::same_as<AZStd::ranges::range_difference_t<ArrayExtentType>, ptrdiff_t>);
static_assert(AZStd::same_as<AZStd::ranges::range_size_t<ArrayExtentType>, size_t>);
static_assert(AZStd::same_as<AZStd::ranges::range_value_t<ArrayExtentType>, int>);
static_assert(AZStd::same_as<AZStd::ranges::range_reference_t<ArrayExtentType>, int&>);
static_assert(AZStd::same_as<AZStd::ranges::range_rvalue_reference_t<ArrayExtentType>, int&&>);
// RangeLikeCustomizationPoint type which specializes several range functions
static_assert(AZStd::same_as<AZStd::ranges::iterator_t<RangeLikeCustomizationPoint>, RangeLikeCustomizationPoint*>);
static_assert(AZStd::same_as<AZStd::ranges::sentinel_t<RangeLikeCustomizationPoint>, RangeLikeCustomizationPoint*>);
static_assert(AZStd::same_as<AZStd::ranges::range_difference_t<RangeLikeCustomizationPoint>, ptrdiff_t>);
static_assert(AZStd::same_as<AZStd::ranges::range_size_t<RangeLikeCustomizationPoint>, size_t>);
static_assert(AZStd::same_as<AZStd::ranges::range_value_t<RangeLikeCustomizationPoint>, RangeLikeCustomizationPoint>);
static_assert(AZStd::same_as<AZStd::ranges::range_reference_t<RangeLikeCustomizationPoint>, RangeLikeCustomizationPoint&>);
static_assert(AZStd::same_as<AZStd::ranges::range_rvalue_reference_t<RangeLikeCustomizationPoint>, RangeLikeCustomizationPoint&&>);
}
// Ranges Concepts Test
TEST_F(RangesTestFixture, RangesConcepts_Compiles)
{
using ArrayExtentType = int[5];
// concept - range
static_assert(AZStd::ranges::range<AZStd::string_view>);
static_assert(AZStd::ranges::range<ArrayExtentType>);
static_assert(AZStd::ranges::range<AZ::IO::PathView>);
static_assert(!AZStd::ranges::range<int>);
// concept - sized_range
static_assert(AZStd::ranges::sized_range<AZStd::string_view>);
static_assert(AZStd::ranges::sized_range<ArrayExtentType>);
// Path classes do not have a size() function so they are not a sized_range
static_assert(!AZStd::ranges::sized_range<AZ::IO::PathView>);
// concept - borrowed_range
static_assert(AZStd::ranges::borrowed_range<AZStd::string_view>);
static_assert(AZStd::ranges::borrowed_range<ArrayExtentType&>);
static_assert(!AZStd::ranges::borrowed_range<ArrayExtentType>);
// concept - output_range
static_assert(AZStd::ranges::output_range<AZStd::string, char>);
static_assert(!AZStd::ranges::output_range<AZStd::string_view, char>);
// concept - input_range
static_assert(AZStd::ranges::input_range<AZStd::list<int>>);
static_assert(AZStd::ranges::input_range<AZStd::string>);
static_assert(AZStd::ranges::input_range<AZStd::string_view>);
// concept - forward_range
static_assert(AZStd::ranges::forward_range<AZStd::list<int>>);
static_assert(AZStd::ranges::forward_range<AZStd::string>);
static_assert(AZStd::ranges::forward_range<AZStd::string_view>);
// concept - bidirectional_range
static_assert(AZStd::ranges::bidirectional_range<AZStd::list<int>>);
static_assert(AZStd::ranges::bidirectional_range<AZStd::string>);
static_assert(AZStd::ranges::bidirectional_range<AZStd::string_view>);
// concept - random_access_range
static_assert(!AZStd::ranges::random_access_range<AZStd::list<int>>);
static_assert(AZStd::ranges::random_access_range<AZStd::deque<int>>);
static_assert(AZStd::ranges::random_access_range<AZStd::string>);
static_assert(AZStd::ranges::random_access_range<AZStd::string_view>);
// concept - contiguous_range
static_assert(!AZStd::ranges::contiguous_range<AZStd::deque<int>>);
static_assert(AZStd::ranges::contiguous_range<AZStd::string>);
static_assert(AZStd::ranges::contiguous_range<AZStd::string_view>);
// concept - common_range
static_assert(AZStd::ranges::common_range<ArrayExtentType>);
static_assert(AZStd::ranges::common_range<AZStd::list<int>>);
static_assert(AZStd::ranges::common_range<AZStd::deque<int>>);
static_assert(AZStd::ranges::common_range<AZStd::string>);
static_assert(AZStd::ranges::common_range<AZStd::string_view>);
// concept - view
static_assert(AZStd::ranges::view<AZStd::string_view>);
static_assert(!AZStd::ranges::view<ArrayExtentType>);
// concept - viewable_range
static_assert(AZStd::ranges::viewable_range<AZStd::string>);
static_assert(AZStd::ranges::viewable_range<AZStd::string_view>);
static_assert(!AZStd::ranges::viewable_range<ArrayExtentType>);
}
// Ranges iterator operations
TEST_F(RangesTestFixture, RangesAdvance_PositiveDifference_Succeeds)
{
AZStd::string_view testString{ "Hello World" };
auto strIter = testString.begin();
// difference overload
AZStd::ranges::advance(strIter, 5);
ASSERT_NE(testString.end(), strIter);
EXPECT_EQ(' ', *strIter);
// bound overload
AZStd::ranges::advance(strIter, testString.end());
EXPECT_EQ(testString.end(), strIter);
// difference + bound overload
strIter = testString.begin();
ptrdiff_t charactersToTraverse = 20;
EXPECT_EQ(charactersToTraverse - testString.size(), AZStd::ranges::advance(strIter, charactersToTraverse, testString.end()));
EXPECT_EQ(testString.end(), strIter);
strIter = testString.begin();
charactersToTraverse = 5;
EXPECT_EQ(0, AZStd::ranges::advance(strIter, charactersToTraverse, testString.end()));
ASSERT_NE(testString.end(), strIter);
EXPECT_EQ(' ', *strIter);
}
TEST_F(RangesTestFixture, RangesAdvance_NegativeDifference_Succeeds)
{
AZStd::string_view testString{ "Hello World" };
auto strIter = testString.end();
// difference overload
AZStd::ranges::advance(strIter, -5);
ASSERT_NE(testString.end(), strIter);
EXPECT_EQ('W', *strIter);
// difference + bound overload
strIter = testString.end();
ptrdiff_t charactersToTraverse = -20;
EXPECT_EQ(charactersToTraverse + testString.size(), AZStd::ranges::advance(strIter, charactersToTraverse, testString.begin()));
EXPECT_EQ(testString.begin(), strIter);
strIter = testString.end();
charactersToTraverse = -5;
EXPECT_EQ(0, AZStd::ranges::advance(strIter, charactersToTraverse, testString.begin()));
ASSERT_NE(testString.end(), strIter);
ASSERT_NE(testString.begin(), strIter);
EXPECT_EQ('W', *strIter);
}
TEST_F(RangesTestFixture, RangesDistance_Succeeds)
{
AZStd::string_view testString{ "Hello World" };
EXPECT_EQ(testString.size(), AZStd::ranges::distance(testString));
EXPECT_EQ(testString.size(), AZStd::ranges::distance(testString.begin(), testString.end()));
AZStd::list<char> testList{ 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };
EXPECT_EQ(testList.size(), AZStd::ranges::distance(testList));
EXPECT_EQ(testList.size(), AZStd::ranges::distance(testList.begin(), testList.end()));
}
TEST_F(RangesTestFixture, RangesNext_Succeeds)
{
AZStd::string_view testString{ "Hello World" };
auto strIter = testString.begin();
auto boundIter = testString.begin() + 5;
// single increment
EXPECT_EQ(testString.begin() + 1, AZStd::ranges::next(strIter));
// increment by value
strIter = testString.begin();
EXPECT_EQ(testString.begin() + 5, AZStd::ranges::next(strIter, 5));
// increment until bound
strIter = testString.begin();
EXPECT_EQ(testString.begin() + 5, AZStd::ranges::next(strIter, boundIter));
// increment by value up until bound
strIter = testString.begin();
EXPECT_EQ(testString.begin() + 5, AZStd::ranges::next(strIter, 10, boundIter));
strIter = testString.begin();
EXPECT_EQ(testString.begin() + 4, AZStd::ranges::next(strIter, 4, boundIter));
}
TEST_F(RangesTestFixture, RangesPrev_Succeeds)
{
AZStd::string_view testString{ "Hello World" };
auto strIter = testString.end();
auto boundIter = testString.end() - 5;
// single decrement
EXPECT_EQ(testString.end() - 1, AZStd::ranges::prev(strIter));
// decrement by value
strIter = testString.end();
EXPECT_EQ(testString.end() - 5, AZStd::ranges::prev(strIter, 5));
// decrement by value up until bound
strIter = testString.end();
EXPECT_EQ(testString.end() - 5, AZStd::ranges::prev(strIter, 10, boundIter));
strIter = testString.end();
EXPECT_EQ(testString.end() - 4, AZStd::ranges::prev(strIter, 4, boundIter));
}
}
@@ -0,0 +1,261 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/containers/span.h>
namespace UnitTest
{
class SpanTestFixture
: public ScopedAllocatorSetupFixture
{};
// range access
TEST_F(SpanTestFixture, IsConstructibleWithContiguousRangeLikeContainers)
{
constexpr AZStd::string_view testStringView{ "Foo" };
AZStd::string testString{ "Foo" };
AZStd::vector testVector{ 'F', 'o', 'o' };
AZStd::fixed_vector testFixedVector{ 'F', 'o', 'o' };
AZStd::array testStdArray{ 'F', 'o', 'o' };
const char testCArray[]{ 'F', 'o', 'o' };
constexpr AZStd::span stringViewSpan(testStringView);
static_assert(stringViewSpan.data() == testStringView.data());
AZStd::span testStringSpan(testString);
EXPECT_EQ(testStringSpan.data(), testString.data());
AZStd::span testVectorSpan(testVector);
EXPECT_EQ(testVectorSpan.data(), testVector.data());
AZStd::span testFixedVectorSpan(testFixedVector);
EXPECT_EQ(testFixedVectorSpan.data(), testFixedVector.data());
AZStd::span testStdArraySpan(testStdArray);
EXPECT_EQ(testStdArraySpan.data(), testStdArray.data());
AZStd::span testCArraySpan(testCArray);
EXPECT_EQ(AZStd::data(testCArray), testCArraySpan.data());
}
TEST_F(SpanTestFixture, IsConstructibleWithContiguousIterators)
{
constexpr AZStd::string_view testStringView{ "Foo" };
AZStd::string testString{ "Foo" };
AZStd::vector testVector{ 'F', 'o', 'o' };
AZStd::fixed_vector testFixedVector{ 'F', 'o', 'o' };
AZStd::array testStdArray{ 'F', 'o', 'o' };
const char testCArray[]{ 'F', 'o', 'o' };
constexpr AZStd::span stringViewSpan(testStringView.begin(), testStringView.end());
static_assert(stringViewSpan.data() == testStringView.data());
AZStd::span testStringSpan(testString.begin(), testString.end());
EXPECT_EQ(testStringSpan.data(), testString.data());
AZStd::span testVectorSpan(testVector.begin(), testVector.end());
EXPECT_EQ(testVectorSpan.data(), testVector.data());
AZStd::span testFixedVectorSpan(testFixedVector.begin(), testFixedVector.end());
EXPECT_EQ(testFixedVectorSpan.data(), testFixedVector.data());
AZStd::span testStdArraySpan(testStdArray.begin(), testStdArray.end());
EXPECT_EQ(testStdArraySpan.data(), testStdArray.data());
AZStd::span testCArraySpan(AZStd::begin(testCArray), AZStd::end(testCArray));
EXPECT_EQ(AZStd::data(testCArray), testCArraySpan.data());
}
TEST_F(SpanTestFixture, ObserverMethods_ReturnsCorrectValues)
{
AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
AZStd::span intSpan(intVector);
EXPECT_FALSE(intSpan.empty());
EXPECT_EQ(intVector.size(), intSpan.size());
EXPECT_EQ(intSpan.size() * sizeof(int), intSpan.size_bytes());
intSpan = {};
EXPECT_TRUE(intSpan.empty());
EXPECT_EQ(0, intSpan.size());
EXPECT_EQ(0, intSpan.size_bytes());
}
TEST_F(SpanTestFixture, ElementAccessorMethods_Succeeds)
{
AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
AZStd::span intSpan(intVector);
EXPECT_EQ(intVector.data(), intSpan.data());
EXPECT_EQ(4, intSpan.front());
EXPECT_EQ(7, intSpan.back());
EXPECT_EQ(6, intSpan[2]);
// Create subspan from elements 1 .. end - 1
intSpan = intSpan.subspan(1, intSpan.size() - 2);
EXPECT_NE(intVector.data(), intSpan.data());
EXPECT_EQ(5, intSpan.front());
EXPECT_EQ(1, intSpan.back());
EXPECT_EQ(6, intSpan[1]);
}
TEST_F(SpanTestFixture, Supspan_Returns_Subview_Succeeds)
{
AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
AZStd::span intSpan(intVector);
// dynamic_extent subspan with count
auto dynamicIntSubSpan = intSpan.subspan(1, 2);
ASSERT_EQ(2, dynamicIntSubSpan.size());
EXPECT_EQ(5, dynamicIntSubSpan[0]);
EXPECT_EQ(6, dynamicIntSubSpan[1]);
// dynamic_extent subspan without count
dynamicIntSubSpan = intSpan.subspan(1);
ASSERT_EQ(4, dynamicIntSubSpan.size());
EXPECT_EQ(5, dynamicIntSubSpan[0]);
EXPECT_EQ(6, dynamicIntSubSpan[1]);
EXPECT_EQ(1, dynamicIntSubSpan[2]);
EXPECT_EQ(7, dynamicIntSubSpan[3]);
// template subspan with count
auto templateIntSubSpan1 = intSpan.subspan<1, 3>();
static_assert(decltype(templateIntSubSpan1)::extent == 3);
ASSERT_EQ(3, templateIntSubSpan1.size());
EXPECT_EQ(5, templateIntSubSpan1[0]);
EXPECT_EQ(6, templateIntSubSpan1[1]);
EXPECT_EQ(1, templateIntSubSpan1[2]);
// template subspan without count
auto templateIntSubSpan2 = intSpan.subspan<1>();
static_assert(decltype(templateIntSubSpan2)::extent == AZStd::dynamic_extent);
ASSERT_EQ(4, templateIntSubSpan2.size());
EXPECT_EQ(5, templateIntSubSpan2[0]);
EXPECT_EQ(6, templateIntSubSpan2[1]);
EXPECT_EQ(1, templateIntSubSpan2[2]);
EXPECT_EQ(7, templateIntSubSpan2[3]);
// get subspan of fixed extent span without count
auto subSpanOfSubSpan = templateIntSubSpan1.subspan<1>();
static_assert(decltype(subSpanOfSubSpan)::extent == 2);
ASSERT_EQ(2, subSpanOfSubSpan.size());
EXPECT_EQ(6, subSpanOfSubSpan[0]);
EXPECT_EQ(1, subSpanOfSubSpan[1]);
}
TEST_F(SpanTestFixture, FirstMethod_Returns_FirstCountElementsOfSpan)
{
constexpr size_t vectorElementCount = 5;
AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
AZStd::span intSpan(intVector);
{
// No templated first function
auto prefixSpan = intSpan.first(3);
ASSERT_EQ(3, prefixSpan.size());
EXPECT_EQ(4, prefixSpan[0]);
EXPECT_EQ(5, prefixSpan[1]);
EXPECT_EQ(6, prefixSpan[2]);
auto prefixSpanRedux = prefixSpan.first(1);
ASSERT_EQ(1, prefixSpanRedux.size());
EXPECT_EQ(4, prefixSpanRedux[0]);
// Test failure of preconditions by requesting more
// elements thant stored in the span
AZ_TEST_START_TRACE_SUPPRESSION;
intSpan.first(intSpan.size() + 1);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
{
// templated first function
auto prefixSpan = intSpan.first<3>();
static_assert(decltype(prefixSpan)::extent == 3);
ASSERT_EQ(3, prefixSpan.size());
EXPECT_EQ(4, prefixSpan[0]);
EXPECT_EQ(5, prefixSpan[1]);
EXPECT_EQ(6, prefixSpan[2]);
auto prefixSpanRedux = prefixSpan.first<1>();
ASSERT_EQ(1, prefixSpanRedux.size());
EXPECT_EQ(4, prefixSpanRedux[0]);
// Test failure of preconditions by requesting more
// elements thant stored in the span
AZ_TEST_START_TRACE_SUPPRESSION;
intSpan.first<vectorElementCount + 1>();
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
}
TEST_F(SpanTestFixture, LastCountElementsOfSpan)
{
constexpr size_t vectorElementCount = 5;
AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
AZStd::span intSpan(intVector);
{
// No templated last function
auto suffixSpan = intSpan.last(3);
ASSERT_EQ(3, suffixSpan.size());
EXPECT_EQ(6, suffixSpan[0]);
EXPECT_EQ(1, suffixSpan[1]);
EXPECT_EQ(7, suffixSpan[2]);
auto suffixSpanRedux = suffixSpan.last(1);
ASSERT_EQ(1, suffixSpanRedux.size());
EXPECT_EQ(7, suffixSpanRedux[0]);
// Test failure of preconditions by requesting more
// elements thant stored in the span
AZ_TEST_START_TRACE_SUPPRESSION;
intSpan.last(intSpan.size() + 1);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
{
// templated last function
auto suffixSpan = intSpan.last<3>();
static_assert(decltype(suffixSpan)::extent == 3);
ASSERT_EQ(3, suffixSpan.size());
EXPECT_EQ(6, suffixSpan[0]);
EXPECT_EQ(1, suffixSpan[1]);
EXPECT_EQ(7, suffixSpan[2]);
auto suffixSpanRedux = suffixSpan.last<1>();
ASSERT_EQ(1, suffixSpanRedux.size());
EXPECT_EQ(7, suffixSpanRedux[0]);
// Test failure of preconditions by requesting more
// elements thant stored in the span
AZ_TEST_START_TRACE_SUPPRESSION;
intSpan.last<vectorElementCount + 1>();
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
}
TEST_F(SpanTestFixture, CanInitializeFixedArrayToDynamicExtentSpan)
{
constexpr size_t arrayElementCount = 5;
static constexpr AZStd::array<int, arrayElementCount> intArray{ 4, 5, 6, 1, 7 };
constexpr AZStd::span<const int, AZStd::dynamic_extent> arraySpan(intArray);
static_assert(intArray.data() == arraySpan.data());
constexpr AZStd::span<const int, arrayElementCount> arraySpanFixedExtent(intArray);
static_assert(intArray.data() == arraySpanFixedExtent.data());
}
}
+420 -301
View File
@@ -45,197 +45,197 @@ namespace UnitTest
// Primary type categories:
// alignment_of and align_to
AZ_TEST_STATIC_ASSERT(alignment_of<int>::value == 4);
AZ_TEST_STATIC_ASSERT(alignment_of<char>::value == 1);
static_assert(alignment_of<int>::value == 4);
static_assert(alignment_of<char>::value == 1);
AZ_TEST_STATIC_ASSERT(alignment_of<MyClass>::value == 16);
aligned_storage<sizeof(int)*100, 16>::type alignedArray;
static_assert(alignment_of<MyClass>::value == 16);
aligned_storage<sizeof(int) * 100, 16>::type alignedArray;
AZ_TEST_ASSERT((((AZStd::size_t)&alignedArray) & 15) == 0);
AZ_TEST_STATIC_ASSERT((alignment_of< aligned_storage<sizeof(int)*5, 8>::type >::value) == 8);
AZ_TEST_STATIC_ASSERT(sizeof(aligned_storage<sizeof(int), 16>::type) == 16);
static_assert((alignment_of< aligned_storage<sizeof(int) * 5, 8>::type >::value) == 8);
static_assert(sizeof(aligned_storage<sizeof(int), 16>::type) == 16);
// is_void
AZ_TEST_STATIC_ASSERT(is_void<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_void<void>::value == true);
AZ_TEST_STATIC_ASSERT(is_void<void const>::value == true);
AZ_TEST_STATIC_ASSERT(is_void<void volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_void<void const volatile>::value == true);
static_assert(is_void<int>::value == false);
static_assert(is_void<void>::value == true);
static_assert(is_void<void const>::value == true);
static_assert(is_void<void volatile>::value == true);
static_assert(is_void<void const volatile>::value == true);
// is_integral
AZ_TEST_STATIC_ASSERT(is_integral<unsigned char>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<unsigned short>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<unsigned int>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<unsigned long>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<signed char>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<signed short>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<signed int>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<signed long>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<bool>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<char>::value == true);
//AZ_TEST_STATIC_ASSERT(is_integral<wchar_t>::value == true);
static_assert(is_integral<unsigned char>::value == true);
static_assert(is_integral<unsigned short>::value == true);
static_assert(is_integral<unsigned int>::value == true);
static_assert(is_integral<unsigned long>::value == true);
static_assert(is_integral<signed char>::value == true);
static_assert(is_integral<signed short>::value == true);
static_assert(is_integral<signed int>::value == true);
static_assert(is_integral<signed long>::value == true);
static_assert(is_integral<bool>::value == true);
static_assert(is_integral<char>::value == true);
//static_assert(is_integral<wchar_t>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<char const >::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<short const>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<int const>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<long const>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<char volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<short volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<int volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<long volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<char const volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<short const volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<int const volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<long const volatile>::value == true);
static_assert(is_integral<char const >::value == true);
static_assert(is_integral<short const>::value == true);
static_assert(is_integral<int const>::value == true);
static_assert(is_integral<long const>::value == true);
static_assert(is_integral<char volatile>::value == true);
static_assert(is_integral<short volatile>::value == true);
static_assert(is_integral<int volatile>::value == true);
static_assert(is_integral<long volatile>::value == true);
static_assert(is_integral<char const volatile>::value == true);
static_assert(is_integral<short const volatile>::value == true);
static_assert(is_integral<int const volatile>::value == true);
static_assert(is_integral<long const volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_integral<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_integral<MyStruct const>::value == false);
AZ_TEST_STATIC_ASSERT(is_integral<MyStruct const volatile>::value == false);
static_assert(is_integral<MyStruct>::value == false);
static_assert(is_integral<MyStruct const>::value == false);
static_assert(is_integral<MyStruct const volatile>::value == false);
// is_floating_point
AZ_TEST_STATIC_ASSERT(is_floating_point<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_floating_point<float>::value == true);
AZ_TEST_STATIC_ASSERT(is_floating_point<float const>::value == true);
AZ_TEST_STATIC_ASSERT(is_floating_point<float volatile>::value == true);
AZ_TEST_STATIC_ASSERT(is_floating_point<float const volatile>::value == true);
static_assert(is_floating_point<int>::value == false);
static_assert(is_floating_point<float>::value == true);
static_assert(is_floating_point<float const>::value == true);
static_assert(is_floating_point<float volatile>::value == true);
static_assert(is_floating_point<float const volatile>::value == true);
// is_array
AZ_TEST_STATIC_ASSERT(is_array<int*>::value == false);
AZ_TEST_STATIC_ASSERT(is_array<int[5]>::value == true);
AZ_TEST_STATIC_ASSERT(is_array<const int[5]>::value == true);
AZ_TEST_STATIC_ASSERT(is_array<volatile int[5]>::value == true);
AZ_TEST_STATIC_ASSERT(is_array<const volatile int[5]>::value == true);
static_assert(is_array<int*>::value == false);
static_assert(is_array<int[5]>::value == true);
static_assert(is_array<const int[5]>::value == true);
static_assert(is_array<volatile int[5]>::value == true);
static_assert(is_array<const volatile int[5]>::value == true);
AZ_TEST_STATIC_ASSERT(is_array<float[]>::value == true);
AZ_TEST_STATIC_ASSERT(is_array<const float[]>::value == true);
AZ_TEST_STATIC_ASSERT(is_array<volatile float[]>::value == true);
AZ_TEST_STATIC_ASSERT(is_array<const volatile float[]>::value == true);
static_assert(is_array<float[]>::value == true);
static_assert(is_array<const float[]>::value == true);
static_assert(is_array<volatile float[]>::value == true);
static_assert(is_array<const volatile float[]>::value == true);
// is_pointer
AZ_TEST_STATIC_ASSERT(is_pointer<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_pointer<int*>::value == true);
AZ_TEST_STATIC_ASSERT(is_pointer<const MyStruct*>::value == true);
AZ_TEST_STATIC_ASSERT(is_pointer<volatile int*>::value == true);
AZ_TEST_STATIC_ASSERT(is_pointer<const volatile MyStruct*>::value == true);
static_assert(is_pointer<int>::value == false);
static_assert(is_pointer<int*>::value == true);
static_assert(is_pointer<const MyStruct*>::value == true);
static_assert(is_pointer<volatile int*>::value == true);
static_assert(is_pointer<const volatile MyStruct*>::value == true);
// is_reference
AZ_TEST_STATIC_ASSERT(is_reference<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_reference<int&>::value == true);
AZ_TEST_STATIC_ASSERT(is_reference<const MyStruct&>::value == true);
AZ_TEST_STATIC_ASSERT(is_reference<volatile int&>::value == true);
AZ_TEST_STATIC_ASSERT(is_reference<const volatile MyStruct&>::value == true);
static_assert(is_reference<int>::value == false);
static_assert(is_reference<int&>::value == true);
static_assert(is_reference<const MyStruct&>::value == true);
static_assert(is_reference<volatile int&>::value == true);
static_assert(is_reference<const volatile MyStruct&>::value == true);
// is_member_object_pointer
AZ_TEST_STATIC_ASSERT(is_member_object_pointer<MyStruct*>::value == false);
AZ_TEST_STATIC_ASSERT(is_member_object_pointer<int (MyStruct::*)()>::value == false);
AZ_TEST_STATIC_ASSERT(is_member_object_pointer<int MyStruct::*>::value == true);
static_assert(is_member_object_pointer<MyStruct*>::value == false);
static_assert(is_member_object_pointer<int (MyStruct::*)()>::value == false);
static_assert(is_member_object_pointer<int MyStruct::*>::value == true);
// is_member_function_pointer
AZ_TEST_STATIC_ASSERT(is_member_function_pointer<MyStruct*>::value == false);
AZ_TEST_STATIC_ASSERT(is_member_function_pointer<int (MyStruct::*)()>::value == true);
AZ_TEST_STATIC_ASSERT(is_member_function_pointer<int MyStruct::*>::value == false);
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() const>::value));
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() volatile>::value));
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() const volatile>::value));
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() &>::value));
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() const&>::value));
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() const volatile&>::value));
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() &&>::value));
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() const&&>::value));
AZ_TEST_STATIC_ASSERT((is_member_function_pointer<int (MyStruct::*)() const volatile&&>::value));
static_assert(is_member_function_pointer<MyStruct*>::value == false);
static_assert(is_member_function_pointer<int (MyStruct::*)()>::value == true);
static_assert(is_member_function_pointer<int MyStruct::*>::value == false);
static_assert((is_member_function_pointer<int (MyStruct::*)() const>::value));
static_assert((is_member_function_pointer<int (MyStruct::*)() volatile>::value));
static_assert((is_member_function_pointer<int (MyStruct::*)() const volatile>::value));
static_assert((is_member_function_pointer<int (MyStruct::*)()&>::value));
static_assert((is_member_function_pointer<int (MyStruct::*)() const&>::value));
static_assert((is_member_function_pointer<int (MyStruct::*)() const volatile&>::value));
static_assert((is_member_function_pointer<int (MyStruct::*)()&&>::value));
static_assert((is_member_function_pointer<int (MyStruct::*)() const&&>::value));
static_assert((is_member_function_pointer<int (MyStruct::*)() const volatile&&>::value));
// is_enum
AZ_TEST_STATIC_ASSERT(is_enum<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_enum<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_enum<MyEnum>::value == true);
static_assert(is_enum<int>::value == false);
static_assert(is_enum<MyStruct>::value == false);
static_assert(is_enum<MyEnum>::value == true);
// is_union
AZ_TEST_STATIC_ASSERT(is_union<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_union<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_union<MyUnion>::value == true);
static_assert(is_union<int>::value == false);
static_assert(is_union<MyStruct>::value == false);
static_assert(is_union<MyUnion>::value == true);
// is_class
AZ_TEST_STATIC_ASSERT(is_class<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_class<MyStruct>::value == true);
AZ_TEST_STATIC_ASSERT(is_class<MyClass>::value == true);
static_assert(is_class<int>::value == false);
static_assert(is_class<MyStruct>::value == true);
static_assert(is_class<MyClass>::value == true);
// is_function
AZ_TEST_STATIC_ASSERT(is_function<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_function<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_function<int(float, char)>::value == true);
static_assert(is_function<int>::value == false);
static_assert(is_function<MyStruct>::value == false);
static_assert(is_function<int(float, char)>::value == true);
//////////////////////////////////////////////////////////////////////////
// composite type categories:
// is_arithmetic
AZ_TEST_STATIC_ASSERT(is_arithmetic<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_arithmetic<int>::value == true);
AZ_TEST_STATIC_ASSERT(is_arithmetic<float>::value == true);
static_assert(is_arithmetic<MyStruct>::value == false);
static_assert(is_arithmetic<int>::value == true);
static_assert(is_arithmetic<float>::value == true);
// is_fundamental
AZ_TEST_STATIC_ASSERT(is_fundamental<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_fundamental<int>::value == true);
AZ_TEST_STATIC_ASSERT(is_fundamental<const float>::value == true);
AZ_TEST_STATIC_ASSERT(is_fundamental<void>::value == true);
static_assert(is_fundamental<MyStruct>::value == false);
static_assert(is_fundamental<int>::value == true);
static_assert(is_fundamental<const float>::value == true);
static_assert(is_fundamental<void>::value == true);
// is_object
AZ_TEST_STATIC_ASSERT(is_object<MyStruct>::value == true);
AZ_TEST_STATIC_ASSERT(is_object<MyStruct&>::value == false);
AZ_TEST_STATIC_ASSERT(is_object<int(short, float)>::value == false);
AZ_TEST_STATIC_ASSERT(is_object<void>::value == false);
static_assert(is_object<MyStruct>::value == true);
static_assert(is_object<MyStruct&>::value == false);
static_assert(is_object<int(short, float)>::value == false);
static_assert(is_object<void>::value == false);
// is_scalar
AZ_TEST_STATIC_ASSERT(is_scalar<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_scalar<MyStruct*>::value == true);
AZ_TEST_STATIC_ASSERT(is_scalar<const float>::value == true);
AZ_TEST_STATIC_ASSERT(is_scalar<int>::value == true);
static_assert(is_scalar<MyStruct>::value == false);
static_assert(is_scalar<MyStruct*>::value == true);
static_assert(is_scalar<const float>::value == true);
static_assert(is_scalar<int>::value == true);
// is_compound
AZ_TEST_STATIC_ASSERT(is_compound<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_compound<MyStruct>::value == true);
AZ_TEST_STATIC_ASSERT(is_compound<int(short, float)>::value == true);
AZ_TEST_STATIC_ASSERT(is_compound<float[]>::value == true);
AZ_TEST_STATIC_ASSERT(is_compound<int&>::value == true);
AZ_TEST_STATIC_ASSERT(is_compound<const void*>::value == true);
static_assert(is_compound<int>::value == false);
static_assert(is_compound<MyStruct>::value == true);
static_assert(is_compound<int(short, float)>::value == true);
static_assert(is_compound<float[]>::value == true);
static_assert(is_compound<int&>::value == true);
static_assert(is_compound<const void*>::value == true);
// is_member_pointer
AZ_TEST_STATIC_ASSERT(is_member_pointer<MyStruct*>::value == false);
AZ_TEST_STATIC_ASSERT(is_member_pointer<int MyStruct::*>::value == true);
AZ_TEST_STATIC_ASSERT(is_member_pointer<int (MyStruct::*)()>::value == true);
static_assert(is_member_pointer<MyStruct*>::value == false);
static_assert(is_member_pointer<int MyStruct::*>::value == true);
static_assert(is_member_pointer<int (MyStruct::*)()>::value == true);
//////////////////////////////////////////////////////////////////////////
// type properties:
// is_const
AZ_TEST_STATIC_ASSERT(is_const<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_const<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_const<const MyStruct>::value == true);
AZ_TEST_STATIC_ASSERT(is_const<const float>::value == true);
static_assert(is_const<MyStruct>::value == false);
static_assert(is_const<int>::value == false);
static_assert(is_const<const MyStruct>::value == true);
static_assert(is_const<const float>::value == true);
// is_volatile
AZ_TEST_STATIC_ASSERT(is_volatile<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_volatile<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_volatile<volatile MyStruct>::value == true);
AZ_TEST_STATIC_ASSERT(is_volatile<volatile float>::value == true);
static_assert(is_volatile<MyStruct>::value == false);
static_assert(is_volatile<int>::value == false);
static_assert(is_volatile<volatile MyStruct>::value == true);
static_assert(is_volatile<volatile float>::value == true);
// is_pod
AZ_TEST_STATIC_ASSERT(is_pod<MyStruct>::value == true);
AZ_TEST_STATIC_ASSERT(is_pod<int>::value == true);
AZ_TEST_STATIC_ASSERT(is_pod<const MyClass>::value == false);
AZ_TEST_STATIC_ASSERT((is_pod< aligned_storage<30, 32>::type >::value) == true);
static_assert(is_pod<MyStruct>::value == true);
static_assert(is_pod<int>::value == true);
static_assert(is_pod<const MyClass>::value == false);
static_assert((is_pod< aligned_storage<30, 32>::type >::value) == true);
// is_empty
AZ_TEST_STATIC_ASSERT(is_empty<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_empty<MyEmptyStruct>::value == true);
AZ_TEST_STATIC_ASSERT(is_empty<int>::value == false);
static_assert(is_empty<MyStruct>::value == false);
static_assert(is_empty<MyEmptyStruct>::value == true);
static_assert(is_empty<int>::value == false);
// is_polymorphic
AZ_TEST_STATIC_ASSERT(is_polymorphic<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_polymorphic<MyClass>::value == true);
static_assert(is_polymorphic<MyStruct>::value == false);
static_assert(is_polymorphic<MyClass>::value == true);
// is_abstract
AZ_TEST_STATIC_ASSERT(is_abstract<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_abstract<MyInterface>::value == true);
static_assert(is_abstract<MyStruct>::value == false);
static_assert(is_abstract<MyInterface>::value == true);
// has_trivial_constructor
static_assert(is_trivially_constructible_v<MyStruct>);
@@ -264,20 +264,20 @@ namespace UnitTest
// has_nothrow_assign
// is_signed
AZ_TEST_STATIC_ASSERT(is_signed<int>::value == true);
AZ_TEST_STATIC_ASSERT(is_signed<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_signed<unsigned int>::value == false);
static_assert(is_signed<int>::value == true);
static_assert(is_signed<MyStruct>::value == false);
static_assert(is_signed<unsigned int>::value == false);
static_assert(is_signed<float>::value);
// is_unsigned
AZ_TEST_STATIC_ASSERT(is_unsigned<int>::value == false);
AZ_TEST_STATIC_ASSERT(is_unsigned<MyStruct>::value == false);
AZ_TEST_STATIC_ASSERT(is_unsigned<unsigned int>::value == true);
AZ_TEST_STATIC_ASSERT(is_unsigned<float>::value == false);
static_assert(is_unsigned<int>::value == false);
static_assert(is_unsigned<MyStruct>::value == false);
static_assert(is_unsigned<unsigned int>::value == true);
static_assert(is_unsigned<float>::value == false);
// true and false types
AZ_TEST_STATIC_ASSERT(true_type::value == true);
AZ_TEST_STATIC_ASSERT(false_type::value == false);
static_assert(true_type::value == true);
static_assert(false_type::value == false);
//! function traits tests
struct NotMyStruct
@@ -290,7 +290,7 @@ namespace UnitTest
{
bool operator()(FunctionTestStruct&) const { return true; };
};
using PrimitiveFunctionPtr = int(*)(bool, float, double, AZ::u8, AZ::s8, AZ::u16, AZ::s16, AZ::u32, AZ::s32, AZ::u64, AZ::s64);
using NotMyStructMemberPtr = int(NotMyStruct::*)();
using ComplexFunctionPtr = float(*)(MyEmptyStruct&, NotMyStructMemberPtr, MyUnion*);
@@ -298,27 +298,27 @@ namespace UnitTest
using MemberFunctionPtr = void(MyInterface::*)(int);
using ConstMemberFunctionPtr = bool(FunctionTestStruct::*)(FunctionTestStruct&) const;
AZ_TEST_STATIC_ASSERT((AZStd::is_same<AZStd::function_traits<PrimitiveFunctionPtr>::result_type, int>::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<AZStd::function_traits<PrimitiveFunctionPtr>::get_arg_t<10>, AZ::s64>::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<AZStd::function_traits_get_arg_t<PrimitiveFunctionPtr, 5>, AZ::u16>::value));
AZ_TEST_STATIC_ASSERT((AZStd::function_traits<PrimitiveFunctionPtr>::arity == 11));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<AZStd::function_traits_get_result_t<ComplexFunction>, float>::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<AZStd::function_traits_get_arg_t<ComplexFunction, 1>, int(NotMyStruct::*)()>::value));
AZ_TEST_STATIC_ASSERT((AZStd::function_traits<ComplexFunction>::arity == 3));
static_assert((AZStd::is_same<AZStd::function_traits<PrimitiveFunctionPtr>::result_type, int>::value));
static_assert((AZStd::is_same<AZStd::function_traits<PrimitiveFunctionPtr>::get_arg_t<10>, AZ::s64>::value));
static_assert((AZStd::is_same<AZStd::function_traits_get_arg_t<PrimitiveFunctionPtr, 5>, AZ::u16>::value));
static_assert((AZStd::function_traits<PrimitiveFunctionPtr>::arity == 11));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<MemberFunctionPtr>::class_fp_type, void(MyInterface::*)(int)>::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<MemberFunctionPtr>::raw_fp_type, void(*)(int)>::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<MemberFunctionPtr>::class_type, MyInterface>::value));
AZ_TEST_STATIC_ASSERT((AZStd::function_traits<MemberFunctionPtr>::arity == 1));
static_assert((AZStd::is_same<AZStd::function_traits_get_result_t<ComplexFunction>, float>::value));
static_assert((AZStd::is_same<AZStd::function_traits_get_arg_t<ComplexFunction, 1>, int(NotMyStruct::*)()>::value));
static_assert((AZStd::function_traits<ComplexFunction>::arity == 3));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<ConstMemberFunctionPtr>::class_fp_type, bool(FunctionTestStruct::*)(FunctionTestStruct&) const> ::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<ConstMemberFunctionPtr>::raw_fp_type, bool(*)(FunctionTestStruct&)> ::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<ConstMemberFunctionPtr>::class_type, FunctionTestStruct>::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits_get_arg_t<ConstMemberFunctionPtr, 0>, FunctionTestStruct&>::value));
AZ_TEST_STATIC_ASSERT((AZStd::function_traits<ConstMemberFunctionPtr>::arity == 1));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<decltype(&FunctionTestStruct::operator())>::class_fp_type, bool(FunctionTestStruct::*)(FunctionTestStruct&) const>::value));
static_assert((AZStd::is_same<typename AZStd::function_traits<MemberFunctionPtr>::class_fp_type, void(MyInterface::*)(int)>::value));
static_assert((AZStd::is_same<typename AZStd::function_traits<MemberFunctionPtr>::raw_fp_type, void(*)(int)>::value));
static_assert((AZStd::is_same<typename AZStd::function_traits<MemberFunctionPtr>::class_type, MyInterface>::value));
static_assert((AZStd::function_traits<MemberFunctionPtr>::arity == 1));
static_assert((AZStd::is_same<typename AZStd::function_traits<ConstMemberFunctionPtr>::class_fp_type, bool(FunctionTestStruct::*)(FunctionTestStruct&) const> ::value));
static_assert((AZStd::is_same<typename AZStd::function_traits<ConstMemberFunctionPtr>::raw_fp_type, bool(*)(FunctionTestStruct&)> ::value));
static_assert((AZStd::is_same<typename AZStd::function_traits<ConstMemberFunctionPtr>::class_type, FunctionTestStruct>::value));
static_assert((AZStd::is_same<typename AZStd::function_traits_get_arg_t<ConstMemberFunctionPtr, 0>, FunctionTestStruct&>::value));
static_assert((AZStd::function_traits<ConstMemberFunctionPtr>::arity == 1));
static_assert((AZStd::is_same<typename AZStd::function_traits<decltype(&FunctionTestStruct::operator())>::class_fp_type, bool(FunctionTestStruct::*)(FunctionTestStruct&) const>::value));
auto lambdaFunction = [](FunctionTestStruct, int) -> bool
{
@@ -326,16 +326,16 @@ namespace UnitTest
};
using LambdaType = decltype(lambdaFunction);
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<LambdaType>::raw_fp_type, bool(*)(FunctionTestStruct, int)>::value));
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<LambdaType>::class_fp_type, bool(LambdaType::*)(FunctionTestStruct, int) const>::value));
AZ_TEST_STATIC_ASSERT((AZStd::function_traits<LambdaType>::arity == 2));
static_assert((AZStd::is_same<typename AZStd::function_traits<LambdaType>::raw_fp_type, bool(*)(FunctionTestStruct, int)>::value));
static_assert((AZStd::is_same<typename AZStd::function_traits<LambdaType>::class_fp_type, bool(LambdaType::*)(FunctionTestStruct, int) const>::value));
static_assert((AZStd::function_traits<LambdaType>::arity == 2));
static_assert(AZStd::is_same<AZStd::function_traits<LambdaType>::return_type, bool>::value, "Lambda result type should be bool");
AZStd::function<void(LambdaType*, ComplexFunction&)> stdFunction;
using StdFunctionType = decay_t<decltype(stdFunction)>;
AZ_TEST_STATIC_ASSERT((AZStd::is_same<typename AZStd::function_traits<StdFunctionType>::raw_fp_type, void(*)(LambdaType*, ComplexFunction&)>::value));
AZ_TEST_STATIC_ASSERT((AZStd::function_traits<StdFunctionType>::arity == 2));
}
static_assert((AZStd::is_same<typename AZStd::function_traits<StdFunctionType>::raw_fp_type, void(*)(LambdaType*, ComplexFunction&)>::value));
static_assert((AZStd::function_traits<StdFunctionType>::arity == 2));
}
struct ConstMethodTestStruct
{
@@ -343,145 +343,264 @@ namespace UnitTest
void NonConstMethod() { }
};
AZ_TEST_STATIC_ASSERT((static_cast<uint32_t>(function_traits<decltype(&ConstMethodTestStruct::ConstMethod)>::qual_flags) & static_cast<uint32_t>(Internal::qualifier_flags::const_)) != 0);
AZ_TEST_STATIC_ASSERT((static_cast<uint32_t>(function_traits<decltype(&ConstMethodTestStruct::NonConstMethod)>::qual_flags) & static_cast<uint32_t>(Internal::qualifier_flags::const_)) == 0);
}
static_assert((static_cast<uint32_t>(function_traits<decltype(&ConstMethodTestStruct::ConstMethod)>::qual_flags)& static_cast<uint32_t>(Internal::qualifier_flags::const_)) != 0);
static_assert((static_cast<uint32_t>(function_traits<decltype(&ConstMethodTestStruct::NonConstMethod)>::qual_flags)& static_cast<uint32_t>(Internal::qualifier_flags::const_)) == 0);
TEST(TypeTraits, StdRemoveConstCompiles)
{
static_assert(AZStd::is_same_v<int, AZStd::remove_const_t<const int>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<int, AZStd::remove_const_t<int>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<int*, AZStd::remove_const_t<int* const>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<const int*, AZStd::remove_const_t<const int*>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<const volatile int*, AZStd::remove_const_t<const volatile int* const>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<int, AZStd::remove_const_t<AZStd::remove_reference_t<const int&>>>, "C++11 std::remove_const_t has failed");
}
TEST(TypeTraits, StdRemoveVolatileCompiles)
{
static_assert(AZStd::is_same_v<int, AZStd::remove_volatile_t<volatile int>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<int, AZStd::remove_volatile_t<int>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<int*, AZStd::remove_volatile_t<int* volatile>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<volatile int*, AZStd::remove_volatile_t<volatile int*>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<const volatile int*, AZStd::remove_volatile_t<const volatile int*>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<const int*, AZStd::remove_volatile_t<const int* volatile>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<int, AZStd::remove_volatile_t<AZStd::remove_reference_t<volatile int&>>>, "C++11 std::remove_volatile_t has failed");
}
TEST(TypeTraits, StdIsConstCompiles)
{
static_assert(!AZStd::is_const_v<int>, "C++11 std::is_const has failed");
static_assert(AZStd::is_const_v<const int>, "C++11 std::is_const has failed");
// references are never const
static_assert(!AZStd::is_const_v<const int&>, "C++11 std::is_const has failed");
// pointer checks for constness
static_assert(!AZStd::is_const_v<const int*>, "C++11 std::is_const has failed");
static_assert(AZStd::is_const_v<const int* const>, "C++11 std::is_const has failed");
static_assert(AZStd::is_const_v<int* const>, "C++11 std::is_const has failed");
}
TEST(TypeTraits, StdIsVolatileCompiles)
{
static_assert(!AZStd::is_volatile_v<int>, "C++11 std::is_volatile has failed");
static_assert(AZStd::is_volatile_v<volatile int>, "C++11 std::is_volatile has failed");
// references are never volatile
static_assert(!AZStd::is_volatile_v<volatile int&>, "C++11 std::is_volatile has failed");
// pointer checks for volatile
static_assert(!AZStd::is_volatile_v<volatile int*>, "C++11 std::is_volatile has failed");
static_assert(AZStd::is_volatile_v<const int* volatile>, "C++11 std::is_volatile has failed");
static_assert(!AZStd::is_volatile_v<volatile int* const>, "C++11 std::is_volatile has failed");
static_assert(AZStd::is_volatile_v<int* volatile>, "C++11 std::is_volatile has failed");
}
TEST(TypeTraits, TemplateIsCopyConstructible_WithCopyConstructibleValueType_ReturnsTrue)
{
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::vector<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::list<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::forward_list<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::map<int, int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::multimap<int, int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::unordered_map<int, int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multimap<int, int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::set<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::multiset<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::unordered_set<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multiset<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::pair<int, int>>::value, "");
struct CopyableType
TEST(TypeTraits, StdRemoveConstCompiles)
{
CopyableType() = default;
CopyableType(const CopyableType&) = default;
};
static_assert(AZStd::Internal::template_is_copy_constructible<CopyableType>::value, "");
}
static_assert(AZStd::is_same_v<int, AZStd::remove_const_t<const int>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<int, AZStd::remove_const_t<int>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<int*, AZStd::remove_const_t<int* const>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<const int*, AZStd::remove_const_t<const int*>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<const volatile int*, AZStd::remove_const_t<const volatile int* const>>, "C++11 std::remove_const_t has failed");
static_assert(AZStd::is_same_v<int, AZStd::remove_const_t<AZStd::remove_reference_t<const int&>>>, "C++11 std::remove_const_t has failed");
}
TEST(TypeTraits, TemplateIsCopyConstructible_WithOutCopyConstructibleValueType_ReturnsFalse)
{
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::vector<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::list<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::forward_list<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::map<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::map<int, AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::multimap<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::multimap<int, AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_map<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_map<int, AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multimap<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multimap<int, AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::set<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::multiset<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_set<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multiset<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::pair<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::pair<int, AZStd::unique_ptr<int>>>::value, "");
struct MoveOnly
TEST(TypeTraits, StdRemoveVolatileCompiles)
{
MoveOnly() = default;
MoveOnly(const MoveOnly&) = delete;
MoveOnly(MoveOnly&&) = default;
};
static_assert(!AZStd::Internal::template_is_copy_constructible<MoveOnly>::value, "");
}
static_assert(AZStd::is_same_v<int, AZStd::remove_volatile_t<volatile int>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<int, AZStd::remove_volatile_t<int>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<int*, AZStd::remove_volatile_t<int* volatile>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<volatile int*, AZStd::remove_volatile_t<volatile int*>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<const volatile int*, AZStd::remove_volatile_t<const volatile int*>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<const int*, AZStd::remove_volatile_t<const int* volatile>>, "C++11 std::remove_volatile_t has failed");
static_assert(AZStd::is_same_v<int, AZStd::remove_volatile_t<AZStd::remove_reference_t<volatile int&>>>, "C++11 std::remove_volatile_t has failed");
}
TEST(TypeTraits, MakeSignedCompiles)
{
static_assert(AZStd::is_same_v<typename AZStd::make_signed<AZ::s8>::type, AZ::s8>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::u8>, AZ::s8>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::s16>, AZ::s16>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::u16>, AZ::s16>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::s32>, AZ::s32>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::u32>, AZ::s32>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::s64>, AZ::s64>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::s64>, AZ::s64>);
}
TEST(TypeTraits, MakeUnsignedCompiles)
{
static_assert(AZStd::is_same_v<typename AZStd::make_unsigned<AZ::s8>::type, AZ::u8>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::u8>, AZ::u8>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::s16>, AZ::u16>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::u16>, AZ::u16>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::s32>, AZ::u32>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::u32>, AZ::u32>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::s64>, AZ::u64>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::s64>, AZ::u64>);
}
// VS2017 workaround, calling decltype directly on the fully specialized aznumeric_cast template
// function fails with error C3556: 'aznumeric_cast': incorrect argument to 'decltype'
// So invoke the attempt to invoke function in a non-evaluated context and SFINAE to prevent a compile
// error
template <typename T, typename = void>
constexpr bool NumericCastInvocable = false;
template <typename T>
constexpr bool NumericCastInvocable<T, AZStd::void_t<decltype(aznumeric_cast<int>(AZStd::declval<T>()))>> = true;
TEST(TypeTraits, NumericCastConversionOperatorCompiles)
{
struct AzNumericCastConvertibleCompileTest
TEST(TypeTraits, StdIsConstCompiles)
{
constexpr operator int() { return {}; };
};
static_assert(NumericCastInvocable<AzNumericCastConvertibleCompileTest>, "aznumeric_cast conversion operator overload is should be compilable");
static_assert(!AZStd::is_const_v<int>, "C++11 std::is_const has failed");
static_assert(AZStd::is_const_v<const int>, "C++11 std::is_const has failed");
// references are never const
static_assert(!AZStd::is_const_v<const int&>, "C++11 std::is_const has failed");
// pointer checks for constness
static_assert(!AZStd::is_const_v<const int*>, "C++11 std::is_const has failed");
static_assert(AZStd::is_const_v<const int* const>, "C++11 std::is_const has failed");
static_assert(AZStd::is_const_v<int* const>, "C++11 std::is_const has failed");
}
TEST(TypeTraits, StdIsVolatileCompiles)
{
static_assert(!AZStd::is_volatile_v<int>, "C++11 std::is_volatile has failed");
static_assert(AZStd::is_volatile_v<volatile int>, "C++11 std::is_volatile has failed");
// references are never volatile
static_assert(!AZStd::is_volatile_v<volatile int&>, "C++11 std::is_volatile has failed");
// pointer checks for volatile
static_assert(!AZStd::is_volatile_v<volatile int*>, "C++11 std::is_volatile has failed");
static_assert(AZStd::is_volatile_v<const int* volatile>, "C++11 std::is_volatile has failed");
static_assert(!AZStd::is_volatile_v<volatile int* const>, "C++11 std::is_volatile has failed");
static_assert(AZStd::is_volatile_v<int* volatile>, "C++11 std::is_volatile has failed");
}
struct CommonReferenceSpecializationTest
{};
}
namespace AZStd
{
template <template <class> class TQual, template <class> class UQual>
struct basic_common_reference<UnitTest::CommonReferenceSpecializationTest, int, TQual, UQual>
{
using type = int&;
};
template <template <class> class TQual, template <class> class UQual>
struct basic_common_reference<int, UnitTest::CommonReferenceSpecializationTest, TQual, UQual>
{
using type = int&;
};
}
namespace UnitTest
{
TEST(TypeTraits, StdCommonReferenceCompiles)
{
// Test std::common_reference bullet https://eel.is/c++draft/meta.trans.other#6.3.1
static_assert(AZStd::is_same_v<AZStd::common_reference_t<volatile float&, const float&>, const volatile float&>, "C++20 std::common_reference has failed");
static_assert(AZStd::is_same_v<AZStd::common_reference_t<float&&, const float&>, const float&>, "C++20 std::common_reference has failed");
static_assert(AZStd::is_same_v<AZStd::common_reference_t<const float&&, const float&>, const float&>, "C++20 std::common_reference has failed");
static_assert(AZStd::is_same_v<AZStd::common_reference_t<int&&, float&>, float>, "C++20 std::common_reference has failed");
static_assert(AZStd::is_same_v<AZStd::common_reference_t<int, float&&>, float>, "C++20 std::common_reference has failed");
// Test std::common_reference customization point https://eel.is/c++draft/meta.trans.other#6.3.2
static_assert(AZStd::is_same_v<AZStd::common_reference_t<UnitTest::CommonReferenceSpecializationTest, int>, int&>, "C++ basic_common_reference_customization_point has failed");
static_assert(AZStd::is_same_v<AZStd::common_reference_t<int, UnitTest::CommonReferenceSpecializationTest>, int&>, "C++ basic_common_reference_customization_point has failed");
// Test std::common_reference bullet https://eel.is/c++draft/meta.trans.other#6.3.3
static_assert(AZStd::is_same_v<AZStd::common_reference_t<int, float>, float>, "C++20 std::common_reference has failed");
static_assert(AZStd::is_same_v<AZStd::common_reference_t<float, int>, float>, "C++20 std::common_reference has failed");
static_assert(AZStd::is_same_v<AZStd::common_reference_t<float, const int>, float>, "C++20 std::common_reference has failed");
// Test std::common_reference bullet https://eel.is/c++draft/meta.trans.other#6.3.3
using Int64Milliseconds = AZStd::chrono::duration<int64_t, AZStd::milli>;
using DoubleMilliseconds = AZStd::chrono::duration<double, AZStd::milli>;
static_assert(AZStd::is_same_v<AZStd::common_reference_t<Int64Milliseconds, DoubleMilliseconds>, DoubleMilliseconds>,
"C++20 std::common_reference common_type check has failed");
}
TEST(TypeTraits, TemplateIsCopyConstructible_WithCopyConstructibleValueType_ReturnsTrue)
{
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::vector<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::list<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::forward_list<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::map<int, int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::multimap<int, int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::unordered_map<int, int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multimap<int, int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::set<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::multiset<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::unordered_set<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multiset<int>>::value, "");
static_assert(AZStd::Internal::template_is_copy_constructible<AZStd::pair<int, int>>::value, "");
struct CopyableType
{
CopyableType() = default;
CopyableType(const CopyableType&) = default;
};
static_assert(AZStd::Internal::template_is_copy_constructible<CopyableType>::value, "");
}
TEST(TypeTraits, TemplateIsCopyConstructible_WithOutCopyConstructibleValueType_ReturnsFalse)
{
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::vector<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::list<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::forward_list<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::map<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::map<int, AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::multimap<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::multimap<int, AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_map<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_map<int, AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multimap<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multimap<int, AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::set<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::multiset<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_set<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::unordered_multiset<AZStd::unique_ptr<int>>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::pair<AZStd::unique_ptr<int>, int>>::value, "");
static_assert(!AZStd::Internal::template_is_copy_constructible<AZStd::pair<int, AZStd::unique_ptr<int>>>::value, "");
struct MoveOnly
{
MoveOnly() = default;
MoveOnly(const MoveOnly&) = delete;
MoveOnly(MoveOnly&&) = default;
};
static_assert(!AZStd::Internal::template_is_copy_constructible<MoveOnly>::value, "");
}
TEST(TypeTraits, MakeSignedCompiles)
{
static_assert(AZStd::is_same_v<typename AZStd::make_signed<AZ::s8>::type, AZ::s8>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::u8>, AZ::s8>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::s16>, AZ::s16>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::u16>, AZ::s16>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::s32>, AZ::s32>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::u32>, AZ::s32>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::s64>, AZ::s64>);
static_assert(AZStd::is_same_v<AZStd::make_signed_t<AZ::s64>, AZ::s64>);
}
TEST(TypeTraits, MakeUnsignedCompiles)
{
static_assert(AZStd::is_same_v<typename AZStd::make_unsigned<AZ::s8>::type, AZ::u8>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::u8>, AZ::u8>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::s16>, AZ::u16>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::u16>, AZ::u16>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::s32>, AZ::u32>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::u32>, AZ::u32>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::s64>, AZ::u64>);
static_assert(AZStd::is_same_v<AZStd::make_unsigned_t<AZ::s64>, AZ::u64>);
}
struct IteratorTraitsSpecializationTest {};
}
namespace AZStd
{
template <>
struct iterator_traits<UnitTest::IteratorTraitsSpecializationTest>
{
using difference_type = ptrdiff_t;
using value_type = char;
using pointer = char*;
using reference = char&;
using iterator_category = random_access_iterator_tag;
using iterator_concept = contiguous_iterator_tag;
};
}
namespace UnitTest
{
TEST(TypeTraits, IterValueCompiles)
{
struct IterValueWithValueAndElementTypeTest
{
using element_type = volatile char;
using value_type = const char;
};
static_assert(AZStd::is_same_v<AZStd::iter_value_t<AZStd::string_view>, typename AZStd::string_view::value_type>);
static_assert(AZStd::is_same_v<AZStd::iter_value_t<AZStd::unique_ptr<char>>, typename AZStd::unique_ptr<char>::element_type>);
static_assert(AZStd::is_same_v<AZStd::iter_value_t<AZ::u32[]>, AZ::u32>);
static_assert(AZStd::is_same_v<AZStd::iter_value_t<AZ::u32*>, AZ::u32>);
static_assert(AZStd::is_same_v<AZStd::iter_value_t<IterValueWithValueAndElementTypeTest>, char>);
static_assert(AZStd::is_same_v<AZStd::iter_value_t<UnitTest::IteratorTraitsSpecializationTest>, char>);
}
TEST(TypeTraits, IterDifferenceCompiles)
{
struct IterDifferenceTest
{
using difference_type = AZ::s8;
};
static_assert(AZStd::is_same_v<AZStd::iter_difference_t<AZ::s32>, AZ::s32>);
static_assert(AZStd::is_same_v<AZStd::iter_difference_t<AZ::u32>, AZ::s32 >);
static_assert(AZStd::is_same_v<AZStd::iter_difference_t<AZ::s32*>, ptrdiff_t>);
static_assert(AZStd::is_same_v<AZStd::iter_difference_t<IterDifferenceTest>, AZ::s8>);
static_assert(AZStd::is_same_v<AZStd::iter_difference_t<const IterDifferenceTest>, AZ::s8>);
static_assert(AZStd::is_same_v<AZStd::iter_difference_t<UnitTest::IteratorTraitsSpecializationTest>, ptrdiff_t>);
}
TEST(TypeTraits, IterReferenceCompiles)
{
static_assert(AZStd::is_same_v<AZStd::iter_reference_t<typename AZStd::string_view::iterator>, const char&>);
static_assert(AZStd::is_same_v<AZStd::iter_reference_t<typename AZStd::list<char>::iterator>, char&>);
static_assert(AZStd::is_same_v<AZStd::iter_reference_t<AZ::u32[]>, AZ::u32&>);
static_assert(AZStd::is_same_v<AZStd::iter_reference_t<AZ::u32*>, AZ::u32&>);
static_assert(AZStd::is_same_v<AZStd::iter_reference_t<typename AZStd::list<char>::const_iterator>, const char&>);
static_assert(AZStd::is_same_v<AZStd::iter_reference_t<std::istreambuf_iterator<char>>, char>);
}
// Test customizing the ranges::iter_move function
struct IterMoveCustomizationPointTest
{
int operator*();
};
char&& iter_move(IterMoveCustomizationPointTest&);
TEST(TypeTraits, IterRvalueReferenceCompiles)
{
static_assert(AZStd::is_same_v<AZStd::iter_rvalue_reference_t<typename AZStd::string_view::iterator>, const char&&>);
static_assert(AZStd::is_same_v<AZStd::iter_rvalue_reference_t<typename AZStd::list<char>::iterator>, char&&>);
static_assert(AZStd::is_same_v<AZStd::iter_rvalue_reference_t<AZ::u32[]>, AZ::u32&&>);
static_assert(AZStd::is_same_v<AZStd::iter_rvalue_reference_t<AZ::u32*>, AZ::u32&&>);
static_assert(AZStd::is_same_v<AZStd::iter_rvalue_reference_t<typename AZStd::list<char>::const_iterator>, const char&&>);
static_assert(AZStd::is_same_v<AZStd::iter_rvalue_reference_t<std::istreambuf_iterator<char>>, char>);
static_assert(AZStd::is_same_v<AZStd::iter_rvalue_reference_t<IterMoveCustomizationPointTest>, char&&>);
}
// VS2017 workaround, calling decltype directly on the fully specialized aznumeric_cast template
// function fails with error C3556: 'aznumeric_cast': incorrect argument to 'decltype'
// So invoke the attempt to invoke function in a non-evaluated context and SFINAE to prevent a compile
// error
template <typename T, typename = void>
constexpr bool NumericCastInvocable = false;
template <typename T>
constexpr bool NumericCastInvocable<T, AZStd::void_t<decltype(aznumeric_cast<int>(AZStd::declval<T>()))>> = true;
TEST(TypeTraits, NumericCastConversionOperatorCompiles)
{
struct AzNumericCastConvertibleCompileTest
{
constexpr operator int() { return {}; };
};
static_assert(NumericCastInvocable<AzNumericCastConvertibleCompileTest>, "aznumeric_cast conversion operator overload should be compilable");
}
}
@@ -6,6 +6,7 @@
*
*/
#include <AzCore/Asset/AssetDataStream.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AZTestShared/Utils/Utils.h>
#include <Tests/Streamer/IStreamerMock.h>
-98
View File
@@ -10,7 +10,6 @@
#include <AzCore/Jobs/JobCompletion.h>
#include <AzCore/Jobs/JobCompletionSpin.h>
#include <AzCore/Jobs/JobFunction.h>
#include <AzCore/Jobs/LegacyJobExecutor.h>
#include <AzCore/Jobs/JobManager.h>
#include <AzCore/Jobs/task_group.h>
#include <AzCore/Jobs/Algorithms.h>
@@ -1398,103 +1397,6 @@ namespace UnitTest
run();
}
using JobLegacyJobExecutorIsRunning = DefaultJobManagerSetupFixture;
TEST_F(JobLegacyJobExecutorIsRunning, Test)
{
// Note: Legacy JobExecutor exists as an adapter to Legacy CryEngine jobs.
// When writing new jobs instead favor direct use of the AZ::Job type family
AZ::LegacyJobExecutor jobExecutor;
EXPECT_FALSE(jobExecutor.IsRunning());
// Completion fences and IsRunning()
{
jobExecutor.PushCompletionFence();
EXPECT_TRUE(jobExecutor.IsRunning());
jobExecutor.PopCompletionFence();
EXPECT_FALSE(jobExecutor.IsRunning());
}
AZStd::atomic_bool jobExecuted{ false };
AZStd::binary_semaphore jobSemaphore;
jobExecutor.StartJob([&jobSemaphore, &jobExecuted]
{
// Wait until the test thread releases
jobExecuted = true;
jobSemaphore.acquire();
}
);
EXPECT_TRUE(jobExecutor.IsRunning());
// Allow the job to complete
jobSemaphore.release();
// Wait for completion
jobExecutor.WaitForCompletion();
EXPECT_FALSE(jobExecutor.IsRunning());
EXPECT_TRUE(jobExecuted);
}
using JobLegacyJobExecutorWaitForCompletion = DefaultJobManagerSetupFixture;
TEST_F(JobLegacyJobExecutorWaitForCompletion, Test)
{
// Note: Legacy JobExecutor exists as an adapter to Legacy CryEngine jobs.
// When writing new jobs instead favor direct use of the AZ::Job type family
AZ::LegacyJobExecutor jobExecutor;
// Semaphores used to park job threads until released
const AZ::u32 numParkJobs = AZ::JobContext::GetGlobalContext()->GetJobManager().GetNumWorkerThreads();
AZStd::vector<AZStd::binary_semaphore> jobSemaphores(numParkJobs);
// Data destination for workers
const AZ::u32 workJobCount = numParkJobs * 2;
AZStd::vector<AZ::u32> jobData(workJobCount, 0);
// Touch completion multiple times as a test of correctly transitioning in and out of the all jobs completed state
AZ::u32 NumCompletionCycles = 5;
for (AZ::u32 completionItrIdx = 0; completionItrIdx < NumCompletionCycles; ++completionItrIdx)
{
// Intentionally park every job thread
for (auto& jobSemaphore : jobSemaphores)
{
jobExecutor.StartJob([&jobSemaphore]
{
jobSemaphore.acquire();
}
);
}
EXPECT_TRUE(jobExecutor.IsRunning());
// Kick off verifiable "work" jobs
for (AZ::u32 i = 0; i < workJobCount; ++i)
{
jobExecutor.StartJob([i, &jobData]
{
jobData[i] = i + 1;
}
);
}
EXPECT_TRUE(jobExecutor.IsRunning());
// Now released our parked job threads
for (auto& jobSemaphore : jobSemaphores)
{
jobSemaphore.release();
}
// And wait for all jobs to finish
jobExecutor.WaitForCompletion();
EXPECT_FALSE(jobExecutor.IsRunning());
// Verify our workers ran and clear data
for (size_t i = 0; i < workJobCount; ++i)
{
EXPECT_EQ(jobData[i], i + 1);
jobData[i] = 0;
}
}
}
class JobCompletionCompleteNotScheduled
: public DefaultJobManagerSetupFixture
{
+97 -102
View File
@@ -87,7 +87,7 @@ namespace UnitTest
#endif
void* addresses[numAllocations] = {nullptr};
IAllocatorAllocate& sysAlloc = AllocatorInstance<SystemAllocator>::Get();
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
//////////////////////////////////////////////////////////////////////////
// Allocate
@@ -96,19 +96,19 @@ namespace UnitTest
{
AZStd::size_t size = AZStd::GetMax(rand() % 256, 1);
// supply all debug info, so we don't need to record the stack.
addresses[i] = sysAlloc.Allocate(size, 8, 0, "Test Alloc", __FILE__, __LINE__);
addresses[i] = sysAllocator.Allocate(size, 8, 0, "Test Alloc", __FILE__, __LINE__);
memset(addresses[i], 1, size);
totalAllocSize += size;
}
//////////////////////////////////////////////////////////////////////////
EXPECT_GE(sysAlloc.NumAllocatedBytes(), totalAllocSize);
EXPECT_GE(sysAllocator.NumAllocatedBytes(), totalAllocSize);
//////////////////////////////////////////////////////////////////////////
// Deallocate
for (int i = numAllocations-1; i >=0; --i)
{
sysAlloc.DeAllocate(addresses[i]);
sysAllocator.DeAllocate(addresses[i]);
}
//////////////////////////////////////////////////////////////////////////
}
@@ -122,21 +122,21 @@ namespace UnitTest
{
AllocatorInstance<SystemAllocator>::Create();
IAllocatorAllocate& sysAlloc = AllocatorInstance<SystemAllocator>::Get();
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
for (int i = 0; i < 100; ++i)
{
address[i] = sysAlloc.Allocate(1000, 32, 0);
address[i] = sysAllocator.Allocate(1000, 32, 0);
EXPECT_NE(nullptr, address[i]);
EXPECT_EQ(0, ((size_t)address[i] & 31)); // check alignment
EXPECT_GE(sysAlloc.AllocationSize(address[i]), 1000); // check allocation size
EXPECT_GE(sysAllocator.AllocationSize(address[i]), 1000); // check allocation size
}
EXPECT_GE(sysAlloc.NumAllocatedBytes(), 100000); // we requested 100 * 1000 so we should have at least this much allocated
EXPECT_GE(sysAllocator.NumAllocatedBytes(), 100000); // we requested 100 * 1000 so we should have at least this much allocated
for (int i = 0; i < 100; ++i)
{
sysAlloc.DeAllocate(address[i]);
sysAllocator.DeAllocate(address[i]);
}
////////////////////////////////////////////////////////////////////////
@@ -168,18 +168,17 @@ namespace UnitTest
SystemAllocator::Descriptor descriptor;
descriptor.m_stackRecordLevels = 20;
AllocatorInstance<SystemAllocator>::Create(descriptor);
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::GetAllocator();
IAllocatorAllocate& sysAlloc = *sysAllocator.GetAllocationSource();
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
for (int i = 0; i < 100; ++i)
{
address[i] = sysAlloc.Allocate(1000, 32, 0);
address[i] = sysAllocator.Allocate(1000, 32, 0);
EXPECT_NE(nullptr, address[i]);
EXPECT_EQ(0, ((size_t)address[i] & 31)); // check alignment
EXPECT_GE(sysAlloc.AllocationSize(address[i]), 1000); // check allocation size
EXPECT_GE(sysAllocator.AllocationSize(address[i]), 1000); // check allocation size
}
EXPECT_TRUE(sysAlloc.NumAllocatedBytes() >= 100000); // we requested 100 * 1000 so we should have at least this much allocated
EXPECT_TRUE(sysAllocator.NumAllocatedBytes() >= 100000); // we requested 100 * 1000 so we should have at least this much allocated
// If tracking and recording is enabled, we can verify that the alloc info is valid
#if defined(AZ_DEBUG_BUILD)
@@ -192,7 +191,7 @@ namespace UnitTest
const Debug::AllocationInfo& ai = iter->second;
EXPECT_EQ(32, ai.m_alignment);
EXPECT_EQ(1000, ai.m_byteSize);
EXPECT_EQ(nullptr, ai.m_fileName); // We did not pass fileName or lineNum to sysAlloc.Allocate()
EXPECT_EQ(nullptr, ai.m_fileName); // We did not pass fileName or lineNum to sysAllocator.Allocate()
EXPECT_EQ(0, ai.m_lineNum); // -- " --
# if defined(AZ_PLATFORM_WINDOWS)
// if our hardware support stack traces make sure we have them, since we did not provide fileName,lineNum
@@ -229,47 +228,47 @@ namespace UnitTest
// Free all memory
for (int i = 0; i < 100; ++i)
{
sysAlloc.DeAllocate(address[i]);
sysAllocator.DeAllocate(address[i]);
}
sysAlloc.GarbageCollect();
EXPECT_LT(sysAlloc.NumAllocatedBytes(), 1024); // We freed everything from a memspace, we should have only a very minor chunk of data
sysAllocator.GarbageCollect();
EXPECT_LT(sysAllocator.NumAllocatedBytes(), 1024); // We freed everything from a memspace, we should have only a very minor chunk of data
//////////////////////////////////////////////////////////////////////////
// realloc test
address[0] = nullptr;
static const unsigned int checkValue = 0x0badbabe;
// create tree (non pool) allocation (we usually pool < 256 bytes)
address[0] = sysAlloc.Allocate(2048, 16);
address[0] = sysAllocator.Allocate(2048, 16);
*(unsigned*)(address[0]) = checkValue; // set check value
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 2048, 16);
address[0] = sysAlloc.ReAllocate(address[0], 1024, 16); // test tree big -> tree small
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 2048, 16);
address[0] = sysAllocator.ReAllocate(address[0], 1024, 16); // test tree big -> tree small
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 1024, 16);
address[0] = sysAlloc.ReAllocate(address[0], 4096, 16); // test tree small -> tree big
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 4096, 16);
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 1024, 16);
address[0] = sysAllocator.ReAllocate(address[0], 4096, 16); // test tree small -> tree big
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 4096, 16);
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
address[0] = sysAlloc.ReAllocate(address[0], 128, 16); // test tree -> pool,
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 128, 16);
address[0] = sysAllocator.ReAllocate(address[0], 128, 16); // test tree -> pool,
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 128, 16);
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
address[0] = sysAlloc.ReAllocate(address[0], 64, 16); // pool big -> pool small
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 64, 16);
address[0] = sysAllocator.ReAllocate(address[0], 64, 16); // pool big -> pool small
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 64, 16);
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
address[0] = sysAlloc.ReAllocate(address[0], 64, 16); // pool sanity check
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 64, 16);
address[0] = sysAllocator.ReAllocate(address[0], 64, 16); // pool sanity check
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 64, 16);
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
address[0] = sysAlloc.ReAllocate(address[0], 192, 16); // pool small -> pool big
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 192, 16);
address[0] = sysAllocator.ReAllocate(address[0], 192, 16); // pool small -> pool big
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 192, 16);
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
address[0] = sysAlloc.ReAllocate(address[0], 2048, 16); // pool -> tree
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 2048, 16);
address[0] = sysAllocator.ReAllocate(address[0], 2048, 16); // pool -> tree
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 2048, 16);
;
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
address[0] = sysAlloc.ReAllocate(address[0], 2048, 16); // tree sanity check
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 2048, 16);
address[0] = sysAllocator.ReAllocate(address[0], 2048, 16); // tree sanity check
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 2048, 16);
;
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
sysAlloc.DeAllocate(address[0], 2048, 16);
sysAllocator.DeAllocate(address[0], 2048, 16);
// TODO realloc with different alignment tests
//////////////////////////////////////////////////////////////////////////
@@ -340,8 +339,7 @@ namespace UnitTest
void run()
{
IAllocatorAllocate& poolAlloc = AllocatorInstance<PoolAllocator>::Get();
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::GetAllocator();
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::Get();
// 64 should be the max number of different pool sizes we can allocate.
void* address[64];
//////////////////////////////////////////////////////////////////////////
@@ -352,12 +350,12 @@ namespace UnitTest
int i = 0;
for (int size = 8; size <= 256; ++i, size += 8)
{
address[i] = poolAlloc.Allocate(size, 8);
EXPECT_GE(poolAlloc.AllocationSize(address[i]), (AZStd::size_t)size);
address[i] = poolAllocator.Allocate(size, 8);
EXPECT_GE(poolAllocator.AllocationSize(address[i]), (AZStd::size_t)size);
memset(address[i], 1, size);
}
EXPECT_GE(poolAlloc.NumAllocatedBytes(), 4126);
EXPECT_GE(poolAllocator.NumAllocatedBytes(), 4126);
if (poolAllocator.GetRecords())
{
@@ -369,11 +367,11 @@ namespace UnitTest
for (i = 0; address[i] != nullptr; ++i)
{
poolAlloc.DeAllocate(address[i]);
poolAllocator.DeAllocate(address[i]);
}
//////////////////////////////////////////////////////////////////////////
EXPECT_EQ(0, poolAlloc.NumAllocatedBytes());
EXPECT_EQ(0, poolAllocator.NumAllocatedBytes());
if (poolAllocator.GetRecords())
{
@@ -393,13 +391,13 @@ namespace UnitTest
memset(address, 0, AZ_ARRAY_SIZE(address)*sizeof(void*));
for (unsigned int j = 0; j < AZ_ARRAY_SIZE(address); ++j)
{
address[j] = poolAlloc.Allocate(256, 8, 0, "Pool Alloc", "This File", 123);
EXPECT_GE(poolAlloc.AllocationSize(address[j]), 256);
address[j] = poolAllocator.Allocate(256, 8, 0, "Pool Alloc", "This File", 123);
EXPECT_GE(poolAllocator.AllocationSize(address[j]), 256);
memset(address[j], 1, 256);
}
// AllocatorManager::Instance().ResetMemoryBreak(0);
EXPECT_GE(poolAlloc.NumAllocatedBytes(), AZ_ARRAY_SIZE(address)*256);
EXPECT_GE(poolAllocator.NumAllocatedBytes(), AZ_ARRAY_SIZE(address)*256);
if (poolAllocator.GetRecords())
{
@@ -411,11 +409,11 @@ namespace UnitTest
for (unsigned int j = 0; j < AZ_ARRAY_SIZE(address); ++j)
{
poolAlloc.DeAllocate(address[j]);
poolAllocator.DeAllocate(address[j]);
}
//////////////////////////////////////////////////////////////////////////
EXPECT_EQ(0, poolAlloc.NumAllocatedBytes());
EXPECT_EQ(0, poolAllocator.NumAllocatedBytes());
if (poolAllocator.GetRecords())
{
@@ -541,14 +539,14 @@ namespace UnitTest
#endif
void* addresses[numAllocations] = {nullptr};
IAllocatorAllocate& poolAlloc = AllocatorInstance<ThreadPoolAllocator>::Get();
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::Get();
//////////////////////////////////////////////////////////////////////////
// Allocate
for (int i = 0; i < numAllocations; ++i)
{
AZStd::size_t size = AZStd::GetMax(1, ((i + 1) * 2) % 256);
addresses[i] = poolAlloc.Allocate(size, 8, 0, "Test Alloc", __FILE__, __LINE__);
addresses[i] = poolAllocator.Allocate(size, 8, 0, "Test Alloc", __FILE__, __LINE__);
EXPECT_NE(addresses[i], nullptr);
memset(addresses[i], 1, size);
}
@@ -558,7 +556,7 @@ namespace UnitTest
// Deallocate
for (int i = numAllocations-1; i >=0; --i)
{
poolAlloc.DeAllocate(addresses[i]);
poolAllocator.DeAllocate(addresses[i]);
}
//////////////////////////////////////////////////////////////////////////
}
@@ -568,12 +566,12 @@ namespace UnitTest
*/
void SharedAlloc()
{
IAllocatorAllocate& poolAlloc = AllocatorInstance<ThreadPoolAllocator>::Get();
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::Get();
for (int i = 0; i < m_numSharedAlloc; ++i)
{
AZStd::size_t minSize = sizeof(AllocClass);
AZStd::size_t size = AZStd::GetMax((AZStd::size_t)(rand() % 256), minSize);
AllocClass* ac = reinterpret_cast<AllocClass*>(poolAlloc.Allocate(size, AZStd::alignment_of<AllocClass>::value, 0, "Shared Alloc", __FILE__, __LINE__));
AllocClass* ac = reinterpret_cast<AllocClass*>(poolAllocator.Allocate(size, AZStd::alignment_of<AllocClass>::value, 0, "Shared Alloc", __FILE__, __LINE__));
AZStd::lock_guard<AZStd::mutex> lock(m_mutex);
m_sharedAlloc.push_back(*ac);
}
@@ -584,7 +582,7 @@ namespace UnitTest
*/
void SharedDeAlloc()
{
IAllocatorAllocate& poolAlloc = AllocatorInstance<ThreadPoolAllocator>::Get();
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::Get();
AllocClass* ac;
int isDone = 0;
while (isDone!=2)
@@ -594,7 +592,7 @@ namespace UnitTest
{
ac = &m_sharedAlloc.front();
m_sharedAlloc.pop_front();
poolAlloc.DeAllocate(ac);
poolAllocator.DeAllocate(ac);
}
if (m_doneSharedAlloc) // once we know we don't add more elements, make one last check and exit.
@@ -633,8 +631,7 @@ namespace UnitTest
void run()
{
IAllocatorAllocate& poolAlloc = AllocatorInstance<ThreadPoolAllocator>::Get();
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::GetAllocator();
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::Get();
// 64 should be the max number of different pool sizes we can allocate.
void* address[64];
//////////////////////////////////////////////////////////////////////////
@@ -645,12 +642,12 @@ namespace UnitTest
int j = 0;
for (int size = 8; size <= 256; ++j, size += 8)
{
address[j] = poolAlloc.Allocate(size, 8);
EXPECT_GE(poolAlloc.AllocationSize(address[j]), (AZStd::size_t)size);
address[j] = poolAllocator.Allocate(size, 8);
EXPECT_GE(poolAllocator.AllocationSize(address[j]), (AZStd::size_t)size);
memset(address[j], 1, size);
}
EXPECT_GE(poolAlloc.NumAllocatedBytes(), 4126);
EXPECT_GE(poolAllocator.NumAllocatedBytes(), 4126);
if (poolAllocator.GetRecords())
{
@@ -662,11 +659,11 @@ namespace UnitTest
for (int i = 0; address[i] != nullptr; ++i)
{
poolAlloc.DeAllocate(address[i]);
poolAllocator.DeAllocate(address[i]);
}
//////////////////////////////////////////////////////////////////////////
EXPECT_EQ(0, poolAlloc.NumAllocatedBytes());
EXPECT_EQ(0, poolAllocator.NumAllocatedBytes());
if (poolAllocator.GetRecords())
{
@@ -681,12 +678,12 @@ namespace UnitTest
memset(address, 0, AZ_ARRAY_SIZE(address)*sizeof(void*));
for (unsigned int i = 0; i < AZ_ARRAY_SIZE(address); ++i)
{
address[i] = poolAlloc.Allocate(256, 8);
EXPECT_GE(poolAlloc.AllocationSize(address[i]), 256);
address[i] = poolAllocator.Allocate(256, 8);
EXPECT_GE(poolAllocator.AllocationSize(address[i]), 256);
memset(address[i], 1, 256);
}
EXPECT_GE(poolAlloc.NumAllocatedBytes(), AZ_ARRAY_SIZE(address)*256);
EXPECT_GE(poolAllocator.NumAllocatedBytes(), AZ_ARRAY_SIZE(address)*256);
if (poolAllocator.GetRecords())
{
@@ -698,11 +695,11 @@ namespace UnitTest
for (unsigned int i = 0; i < AZ_ARRAY_SIZE(address); ++i)
{
poolAlloc.DeAllocate(address[i]);
poolAllocator.DeAllocate(address[i]);
}
//////////////////////////////////////////////////////////////////////////
EXPECT_EQ(0, poolAlloc.NumAllocatedBytes());
EXPECT_EQ(0, poolAllocator.NumAllocatedBytes());
if (poolAllocator.GetRecords())
{
@@ -820,7 +817,7 @@ namespace UnitTest
desc.m_memoryBlock = azmalloc(desc.m_memoryBlockByteSize, desc.m_memoryBlockAlignment);
AllocatorInstance<BestFitExternalMapAllocator>::Create(desc);
IAllocatorAllocate& bfAlloc = AllocatorInstance<BestFitExternalMapAllocator>::Get();
IAllocator& bfAlloc = AllocatorInstance<BestFitExternalMapAllocator>::Get();
EXPECT_EQ( desc.m_memoryBlockByteSize, bfAlloc.Capacity() );
EXPECT_EQ( 0, bfAlloc.NumAllocatedBytes() );
@@ -882,8 +879,8 @@ namespace UnitTest
void run()
{
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::GetAllocator();
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::GetAllocator();
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::Get();
void* ptr = azmalloc(16*1024, 32, SystemAllocator);
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
@@ -1010,27 +1007,27 @@ namespace UnitTest
void run()
{
IAllocator& sysAlloc = AllocatorInstance<SystemAllocator>::GetAllocator();
IAllocator& poolAlloc = AllocatorInstance<PoolAllocator>::GetAllocator();
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::Get();
MyClass* ptr = aznew MyClass(202); /// this should allocate memory from the pool allocator
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
EXPECT_EQ(202, ptr->m_data); // check value
if (poolAlloc.GetRecords())
if (poolAllocator.GetRecords())
{
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAlloc.GetRecords());
const Debug::AllocationRecordsType& records = poolAlloc.GetRecords()->GetMap();
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAllocator.GetRecords());
const Debug::AllocationRecordsType& records = poolAllocator.GetRecords()->GetMap();
Debug::AllocationRecordsType::const_iterator iter = records.find(ptr);
EXPECT_TRUE(iter!=records.end()); // our allocation is in the list
EXPECT_STREQ(iter->second.m_name, "MyClass");
}
delete ptr;
if (poolAlloc.GetRecords())
if (poolAllocator.GetRecords())
{
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAlloc.GetRecords());
const Debug::AllocationRecordsType& records = poolAlloc.GetRecords()->GetMap();
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAllocator.GetRecords());
const Debug::AllocationRecordsType& records = poolAllocator.GetRecords()->GetMap();
EXPECT_TRUE(records.find(ptr)==records.end()); // our allocation is NOT in the list
}
@@ -1038,19 +1035,19 @@ namespace UnitTest
ptr = azcreate(MyClass, (101), SystemAllocator);
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
EXPECT_EQ(101, ptr->m_data); // check value
if (sysAlloc.GetRecords())
if (sysAllocator.GetRecords())
{
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAlloc.GetRecords());
const Debug::AllocationRecordsType& records = sysAlloc.GetRecords()->GetMap();
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAllocator.GetRecords());
const Debug::AllocationRecordsType& records = sysAllocator.GetRecords()->GetMap();
Debug::AllocationRecordsType::const_iterator iter = records.find(ptr);
EXPECT_TRUE(iter!=records.end()); // our allocation is in the list
EXPECT_STREQ(iter->second.m_name, "MyClass");
}
azdestroy(ptr, SystemAllocator);
if (sysAlloc.GetRecords())
if (sysAllocator.GetRecords())
{
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAlloc.GetRecords());
const Debug::AllocationRecordsType& records = sysAlloc.GetRecords()->GetMap();
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAllocator.GetRecords());
const Debug::AllocationRecordsType& records = sysAllocator.GetRecords()->GetMap();
EXPECT_TRUE(records.find(ptr)==records.end()); // our allocation is NOT in the list
}
@@ -1059,19 +1056,19 @@ namespace UnitTest
ptr = azcreate(MyClass, (505), SystemAllocator, "MyClassNamed");
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
EXPECT_EQ(505, ptr->m_data); // check value
if (sysAlloc.GetRecords())
if (sysAllocator.GetRecords())
{
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAlloc.GetRecords());
const Debug::AllocationRecordsType& records = sysAlloc.GetRecords()->GetMap();
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAllocator.GetRecords());
const Debug::AllocationRecordsType& records = sysAllocator.GetRecords()->GetMap();
Debug::AllocationRecordsType::const_iterator iter = records.find(ptr);
EXPECT_TRUE(iter!=records.end()); // our allocation is in the list
EXPECT_STREQ(iter->second.m_name, "MyClassNamed");
}
azdestroy(ptr); // imply SystemAllocator
if (sysAlloc.GetRecords())
if (sysAllocator.GetRecords())
{
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAlloc.GetRecords());
const Debug::AllocationRecordsType& records = sysAlloc.GetRecords()->GetMap();
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAllocator.GetRecords());
const Debug::AllocationRecordsType& records = sysAllocator.GetRecords()->GetMap();
EXPECT_TRUE(records.find(ptr)==records.end()); // our allocation is NOT in the list
}
@@ -1080,20 +1077,20 @@ namespace UnitTest
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
EXPECT_EQ(303, ptr->m_data); // check value
if (poolAlloc.GetRecords())
if (poolAllocator.GetRecords())
{
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAlloc.GetRecords());
const Debug::AllocationRecordsType& records = poolAlloc.GetRecords()->GetMap();
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAllocator.GetRecords());
const Debug::AllocationRecordsType& records = poolAllocator.GetRecords()->GetMap();
Debug::AllocationRecordsType::const_iterator iter = records.find(ptr);
EXPECT_TRUE(iter != records.end()); // our allocation is in the list
EXPECT_STREQ(iter->second.m_name, "MyClass");
}
delete ptr;
if (poolAlloc.GetRecords())
if (poolAllocator.GetRecords())
{
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAlloc.GetRecords());
const Debug::AllocationRecordsType& records = poolAlloc.GetRecords()->GetMap();
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAllocator.GetRecords());
const Debug::AllocationRecordsType& records = poolAllocator.GetRecords()->GetMap();
EXPECT_TRUE(records.find(ptr) == records.end()); // our allocation is NOT in the list
}
}
@@ -1140,8 +1137,8 @@ namespace UnitTest
return (size_t)1 << (size_t)(MAX_ALIGNMENT_LOG2 * r);
}
class DebugSysAlloc
: public AZ::IAllocatorAllocate
class DebugSysAllocSchema
: public AZ::IAllocatorSchema
{
pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override
{
@@ -1176,8 +1173,6 @@ namespace UnitTest
size_type GetMaxAllocationSize() const override { return 1 * 1024 * 1024 * 1024; }
/// Returns max allocation size of a single contiguous allocation
size_type GetMaxContiguousAllocationSize() const override { return 1 * 1024 * 1024 * 1024; }
/// Returns a pointer to a sub-allocator or NULL.
IAllocatorAllocate* GetSubAllocator() override { return NULL; }
};
public:
void SetUp() override
@@ -2565,7 +2560,7 @@ namespace UnitTest
printf("\n\t\t\t=======================\n");
printf("\t\t\tSchemas Benchmark Test!\n");
printf("\t\t\t=======================\n");
DebugSysAlloc da;
DebugSysAllocSchema da;
{
HphaSchema::Descriptor hphaDesc;
hphaDesc.m_fixedMemoryBlockByteSize = AZ_TRAIT_OS_HPHA_MEMORYBLOCKBYTESIZE;
@@ -113,7 +113,6 @@ namespace Benchmark
{
}
// IAllocatorAllocate
static void* Allocate(size_t byteSize, size_t)
{
s_numAllocatedBytes += byteSize;
@@ -157,11 +156,9 @@ namespace Benchmark
}
private:
static size_t s_numAllocatedBytes;
inline static size_t s_numAllocatedBytes = 0;
};
size_t TestAllocatorWrapper<RawMallocAllocator>::s_numAllocatedBytes = 0;
// Some allocator are not fully declared, those we simply setup from the schema
class MallocSchemaAllocator : public AZ::SimpleSchemaAllocator<AZ::MallocSchema>
{
@@ -581,6 +578,7 @@ namespace Benchmark
//BM_REGISTER_ALLOCATOR(BestFitExternalMapAllocator, BestFitExternalMapAllocator); // Requires to pre-allocate blocks and cannot work as a general-purpose allocator
//BM_REGISTER_ALLOCATOR(HeapSchemaAllocator, TestHeapSchemaAllocator); // Requires to pre-allocate blocks and cannot work as a general-purpose allocator
//BM_REGISTER_SCHEMA(PoolSchema); // Requires special alignment requests while allocating
// BM_REGISTER_ALLOCATOR(OSAllocator, OSAllocator); // Requires special treatment to initialize since it will be already initialized, maybe creating a different instance?
#undef BM_REGISTER_ALLOCATOR
#undef BM_REGISTER_SIZE_FIXTURES
@@ -7,7 +7,6 @@
*/
#include <AzCore/Memory/AllocatorManager.h>
#include <AzCore/Memory/AllocatorOverrideShim.h>
#include <AzCore/Memory/MallocSchema.h>
#include <AzCore/UnitTest/TestTypes.h>
@@ -47,9 +46,6 @@ namespace UnitTest
void RunTests()
{
TestAllocatorShimWithDeallocateAfter();
TestAllocatorShimRemovedAfterFinalization();
TestAllocatorShimUsedForRealloc();
TearDownAllocatorManagerTest();
}
@@ -64,7 +60,7 @@ namespace UnitTest
EXPECT_EQ(m_manager->GetNumAllocators(), 0);
AllocatorInstance<SystemAllocator>::Create();
EXPECT_EQ(m_manager->GetNumAllocators(), 2); // SystemAllocator creates the OSAllocator if it doesn't exist
m_systemAllocator = &AllocatorInstance<SystemAllocator>::GetAllocator();
m_systemAllocator = &AllocatorInstance<SystemAllocator>::Get();
}
void TearDownAllocatorManagerTest()
@@ -83,85 +79,6 @@ namespace UnitTest
m_systemAllocator = nullptr;
}
void TestAllocatorShimWithDeallocateAfter()
{
SetUpAllocatorManagerTest();
// Should begin with a shim installed. If this fails, check that AZCORE_MEMORY_ENABLE_OVERRIDES is enabled in AllocatorManager.cpp.
EXPECT_NE(m_systemAllocator->GetAllocationSource(), m_systemAllocator->GetOriginalAllocationSource());
const int testAllocBytes = TEST_ALLOC_BYTES;
// Allocate from the shim, which should take from the allocator's original source
void* p = m_systemAllocator->GetAllocationSource()->Allocate(testAllocBytes, 0, 0);
EXPECT_NE(p, nullptr);
EXPECT_EQ(m_systemAllocator->GetOriginalAllocationSource()->NumAllocatedBytes(), testAllocBytes);
// Add the override schema
m_manager->SetOverrideAllocatorSource(&m_mallocSchema);
// Allocations should go through malloc schema instead of the allocator's regular schema
void* q = m_systemAllocator->GetAllocationSource()->Allocate(testAllocBytes, 0, 0);
EXPECT_NE(q, nullptr);
EXPECT_EQ(m_mallocSchema.NumAllocatedBytes(), testAllocBytes);
EXPECT_EQ(m_systemAllocator->GetOriginalAllocationSource()->NumAllocatedBytes(), testAllocBytes);
// Finalize configuration, no more shims should be created after this point
m_manager->FinalizeConfiguration();
// Deallocating the original orphaned allocation from the SystemAllocator should remove the shim
EXPECT_NE(m_systemAllocator->GetAllocationSource(), &m_mallocSchema);
m_systemAllocator->GetAllocationSource()->DeAllocate(p);
EXPECT_EQ(m_systemAllocator->GetAllocationSource(), &m_mallocSchema);
// Clean up
m_systemAllocator->GetAllocationSource()->DeAllocate(q);
}
void TestAllocatorShimRemovedAfterFinalization()
{
SetUpAllocatorManagerTest();
// Should begin with a shim installed
EXPECT_NE(m_systemAllocator->GetAllocationSource(), m_systemAllocator->GetOriginalAllocationSource());
// Finalizing the configuration should remove the shim if it was unused
m_manager->FinalizeConfiguration();
EXPECT_EQ(m_systemAllocator->GetAllocationSource(), m_systemAllocator->GetOriginalAllocationSource());
}
void TestAllocatorShimUsedForRealloc()
{
SetUpAllocatorManagerTest();
// Should begin with a shim installed
EXPECT_NE(m_systemAllocator->GetAllocationSource(), m_systemAllocator->GetOriginalAllocationSource());
const int testAllocBytes = TEST_ALLOC_BYTES;
// Allocate from the shim, which should take from the allocator's original source
void* p = m_systemAllocator->GetAllocationSource()->Allocate(testAllocBytes, 0, 0);
EXPECT_NE(p, nullptr);
EXPECT_EQ(m_systemAllocator->GetOriginalAllocationSource()->NumAllocatedBytes(), testAllocBytes);
// Add the override schema and finalize
m_manager->SetOverrideAllocatorSource(&m_mallocSchema);
m_manager->FinalizeConfiguration();
// Shim should still be present
EXPECT_NE(m_systemAllocator->GetAllocationSource(), &m_mallocSchema);
// Reallocation should move allocation from the old source to the new source
EXPECT_EQ(m_mallocSchema.NumAllocatedBytes(), 0);
void* q = m_systemAllocator->GetAllocationSource()->ReAllocate(p, testAllocBytes * 2, 0);
EXPECT_NE(p, q);
EXPECT_EQ(m_mallocSchema.NumAllocatedBytes(), testAllocBytes * 2);
EXPECT_EQ(m_systemAllocator->GetOriginalAllocationSource()->NumAllocatedBytes(), 0);
// Reallocation should also have removed the shim as it was no longer necessary
EXPECT_EQ(m_systemAllocator->GetAllocationSource(), &m_mallocSchema);
}
MallocSchema m_mallocSchema;
AllocatorManager* m_manager = nullptr;
IAllocator* m_systemAllocator = nullptr;
@@ -642,7 +642,7 @@ namespace UnitTest
char buffer[RandomStringBufferSize];
AZStd::sys_time_t newNameTime;
AZStd::sys_time_t existingNameTime;
[[maybe_unused]] AZStd::sys_time_t existingNameTime;
AZStd::sys_time_t stringTime;
{
@@ -0,0 +1,467 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Android/Utils.h>
#include <AzCore/Android/JNI/JNI.h>
#include <AzCore/Android/JNI/Object.h>
#include <AzCore/Android/JNI/Signature.h>
// Include Testing Framework Here
using namespace AZ::Android;
namespace UnitTest
{
struct SimpleJavaObject
{
SimpleJavaObject()
: m_classRef(nullptr)
, m_objectRef(nullptr)
{
m_classRef = JNI::LoadClass("com/amazon/test/SimpleObject");
JNIEnv* jniEnv = JNI::GetEnv();
jmethodID constructorMethodId = jniEnv->GetMethodID(m_classRef, "<init>", "()V");
jobject localObjectRef = jniEnv->NewObject(m_classRef, constructorMethodId);
m_objectRef = jniEnv->NewGlobalRef(localObjectRef);
jniEnv->DeleteLocalRef(localObjectRef);
}
~SimpleJavaObject()
{
JNI::DeleteRef(m_objectRef);
}
jclass m_classRef;
jobject m_objectRef;
};
// ----
TEST(Signature, Sanity)
{
EXPECT_EQ(1, 1);
}
// ----
// Generation Tests
// ----
TEST(Signature, Generate_NoArgs_IsEmptyString)
{
AZStd::string emptyStr = JNI::GetSignature();
ASSERT_TRUE(emptyStr.empty());
}
TEST(Signature, Generate_DefaultNativeBooleanTypes_IsZ)
{
AZStd::string nativeTrueType = JNI::GetSignature(true);
ASSERT_STREQ(nativeTrueType.c_str(), "Z");
AZStd::string nativeFalseType = JNI::GetSignature(false);
ASSERT_STREQ(nativeFalseType.c_str(), "Z");
AZStd::string boolType = JNI::GetSignature(bool());
ASSERT_STREQ(boolType.c_str(), "Z");
AZStd::string allBoolTypes = JNI::GetSignature(true, false, bool());
ASSERT_STREQ(allBoolTypes.c_str(), "ZZZ");
}
TEST(Signature, Generate_DefaultJBooleanTypes_IsZ)
{
AZStd::string jniTrueType = JNI::GetSignature(JNI_TRUE);
ASSERT_STREQ(jniTrueType.c_str(), "Z");
AZStd::string jniFalseType = JNI::GetSignature(JNI_FALSE);
ASSERT_STREQ(jniFalseType.c_str(), "Z");
AZStd::string jboolType = JNI::GetSignature(jboolean());
ASSERT_STREQ(jboolType.c_str(), "Z");
AZStd::string jniBoolArrayType = JNI::GetSignature(jbooleanArray());
ASSERT_STREQ(jniBoolArrayType.c_str(), "[Z");
AZStd::string allJBoolTypes = JNI::GetSignature(JNI_TRUE, JNI_FALSE, jboolean(), jbooleanArray());
ASSERT_STREQ(allJBoolTypes.c_str(), "ZZZ[Z");
}
TEST(Signature, Generate_AllDefaultBooleanTypes_IsZ)
{
AZStd::string allBoolTypes = JNI::GetSignature(true, false, bool(), JNI_TRUE, JNI_FALSE, jboolean(), jbooleanArray());
ASSERT_STREQ(allBoolTypes.c_str(), "ZZZZZZ[Z");
}
TEST(Signature, Generate_DefaultJByteTypes_IsB)
{
AZStd::string jbyteType = JNI::GetSignature(jbyte());
ASSERT_STREQ(jbyteType.c_str(), "B");
AZStd::string jbyteArrayType = JNI::GetSignature(jbyteArray());
ASSERT_STREQ(jbyteArrayType.c_str(), "[B");
AZStd::string allJByteTypes = JNI::GetSignature(jbyte(), jbyteArray());
ASSERT_STREQ(allJByteTypes.c_str(), "B[B");
}
TEST(Signature, Generate_DefaultJCharTypes_IsC)
{
AZStd::string jcharType = JNI::GetSignature(jchar());
ASSERT_STREQ(jcharType.c_str(), "C");
AZStd::string jcharArrayType = JNI::GetSignature(jcharArray());
ASSERT_STREQ(jcharArrayType.c_str(), "[C");
AZStd::string allJCharTypes = JNI::GetSignature(jchar(), jcharArray());
ASSERT_STREQ(allJCharTypes.c_str(), "C[C");
}
TEST(Signature, Generate_DefaultJShortTypes_IsS)
{
AZStd::string jshortType = JNI::GetSignature(jshort());
ASSERT_STREQ(jshortType.c_str(), "S");
AZStd::string jshortArrayType = JNI::GetSignature(jshortArray());
ASSERT_STREQ(jshortArrayType.c_str(), "[S");
AZStd::string allJShortTypes = JNI::GetSignature(jshort(), jshortArray());
ASSERT_STREQ(allJShortTypes.c_str(), "S[S");
}
TEST(Signature, Generate_DefaultJIntTypes_IsI)
{
AZStd::string jintType = JNI::GetSignature(jint());
ASSERT_STREQ(jintType.c_str(), "I");
AZStd::string jintArrayType = JNI::GetSignature(jintArray());
ASSERT_STREQ(jintArrayType.c_str(), "[I");
AZStd::string allJIntTypes = JNI::GetSignature(jint(), jintArray());
ASSERT_STREQ(allJIntTypes.c_str(), "I[I");
}
TEST(Signature, Generate_DefaultJLongTypes_IsJ)
{
AZStd::string jlongType = JNI::GetSignature(jlong());
ASSERT_STREQ(jlongType.c_str(), "J");
AZStd::string jlongArrayType = JNI::GetSignature(jlongArray());
ASSERT_STREQ(jlongArrayType.c_str(), "[J");
AZStd::string allJLongTypes = JNI::GetSignature(jlong(), jlongArray());
ASSERT_STREQ(allJLongTypes.c_str(), "J[J");
}
TEST(Signature, Generate_DefaultJFloatTypes_IsF)
{
AZStd::string jfloatType = JNI::GetSignature(jfloat());
ASSERT_STREQ(jfloatType.c_str(), "F");
AZStd::string jfloatArrayType = JNI::GetSignature(jfloatArray());
ASSERT_STREQ(jfloatArrayType.c_str(), "[F");
AZStd::string allJFloatTypes = JNI::GetSignature(jfloat(), jfloatArray());
ASSERT_STREQ(allJFloatTypes.c_str(), "F[F");
}
TEST(Signature, Generate_DefaultJDoubleTypes_IsD)
{
AZStd::string jdoubleType = JNI::GetSignature(jdouble());
ASSERT_STREQ(jdoubleType.c_str(), "D");
AZStd::string jdoubleArrayType = JNI::GetSignature(jdoubleArray());
ASSERT_STREQ(jdoubleArrayType.c_str(), "[D");
AZStd::string allJDoubleTypes = JNI::GetSignature(jdouble(), jdoubleArray());
ASSERT_STREQ(allJDoubleTypes.c_str(), "D[D");
}
TEST(Signature, Generate_DefaultJStringTypes_IsLjava_lang_String)
{
AZStd::string jstringType = JNI::GetSignature(jstring());
ASSERT_STREQ(jstringType.c_str(), "Ljava/lang/String;");
}
TEST(Signature, Generate_DefaultJClassTypes_IsLjava_lang_Class)
{
AZStd::string jclassType = JNI::GetSignature(jclass());
ASSERT_STREQ(jclassType.c_str(), "Ljava/lang/Class;");
}
TEST(Signature, Generate_DefaultJObjectType_IsEmptyString)
{
AZStd::string jobjectType = JNI::GetSignature(jobject());
ASSERT_TRUE(jobjectType.empty());
AZStd::string jobjectArrayType = JNI::GetSignature(jobjectArray());
ASSERT_TRUE(jobjectArrayType.empty());
}
TEST(Signature, Generate_SimpleJObjectType_IsLcom_amazon_test_SimpleObject)
{
SimpleJavaObject simpleObject;
AZStd::string simpleObjectType = JNI::GetSignature(simpleObject.m_objectRef);
ASSERT_STREQ(simpleObjectType.c_str(), "Lcom/amazon/test/SimpleObject;");
}
TEST(Signature, Generate_AllDefaultPrimtiveTypes_IsZZZBBCCSSIIJJFFDD)
{
AZStd::string allPrimitiveTypes = JNI::GetSignature(
bool(), jboolean(), jbooleanArray(),
jbyte(), jbyteArray(),
jchar(), jcharArray(),
jshort(), jshortArray(),
jint(), jintArray(),
jlong(), jlongArray(),
jfloat(), jfloatArray(),
jdouble(), jdoubleArray()
);
ASSERT_STREQ(allPrimitiveTypes.c_str(), "ZZ[ZB[BC[CS[SI[IJ[JF[FD[D");
}
TEST(Signature, Generate_DefaultJStringJClassTypes_IsLjava_lang_StringLjava_lang_Class)
{
AZStd::string jstringJClassTypes = JNI::GetSignature(jstring(), jclass());
ASSERT_STREQ(jstringJClassTypes.c_str(), "Ljava/lang/String;Ljava/lang/Class;");
}
TEST(Signature, Generate_AllTypes_IsZZZBBCCSSIIJJFFDDLjava_lang_StringLjava_lang_ClassLcom_amazon_test_SimpleObject)
{
SimpleJavaObject simpleObject;
AZStd::string allTypes = JNI::GetSignature(
bool(), jboolean(), jbooleanArray(),
jbyte(), jbyteArray(),
jchar(), jcharArray(),
jshort(), jshortArray(),
jint(), jintArray(),
jlong(), jlongArray(),
jfloat(), jfloatArray(),
jdouble(), jdoubleArray(),
jstring(), jclass(),
simpleObject.m_objectRef
);
ASSERT_STREQ(allTypes.c_str(), "ZZ[ZB[BC[CS[SI[IJ[JF[FD[DLjava/lang/String;Ljava/lang/Class;Lcom/amazon/test/SimpleObject;");
}
// ----
// Validation Tests
// ----
TEST(Signature, Validate_NoArgs_IsEmptyString)
{
ASSERT_TRUE(JNI::ValidateSignature(""));
}
TEST(Signature, Validate_DefaultNativeBooleanTypes_IsZ)
{
ASSERT_TRUE(JNI::ValidateSignature("Z", true));
ASSERT_TRUE(JNI::ValidateSignature("Z", false));
ASSERT_TRUE(JNI::ValidateSignature("Z", bool()));
}
TEST(Signature, Validate_DefaultJBooleanTypes_IsZ)
{
ASSERT_TRUE(JNI::ValidateSignature("Z", JNI_TRUE));
ASSERT_TRUE(JNI::ValidateSignature("Z", JNI_FALSE));
ASSERT_TRUE(JNI::ValidateSignature("Z", jboolean()));
ASSERT_TRUE(JNI::ValidateSignature("[Z", jbooleanArray()));
}
TEST(Signature, Validate_AllDefaultBooleanTypes_IsZ)
{
ASSERT_TRUE(JNI::ValidateSignature("ZZZ", true, false, bool()));
ASSERT_TRUE(JNI::ValidateSignature("ZZZ[Z", JNI_TRUE, JNI_FALSE, jboolean(), jbooleanArray()));
ASSERT_TRUE(JNI::ValidateSignature("ZZZZZZ[Z",
true, false, bool(),
JNI_TRUE, JNI_FALSE, jboolean(),
jbooleanArray()));
}
TEST(Signature, Validate_DefaultJByteTypes_IsB)
{
ASSERT_TRUE(JNI::ValidateSignature("B", jbyte()));
ASSERT_TRUE(JNI::ValidateSignature("[B", jbyteArray()));
}
TEST(Signature, Validate_AllDefaultJByteTypes_IsB)
{
ASSERT_TRUE(JNI::ValidateSignature("B[B", jbyte(), jbyteArray()));
}
TEST(Signature, Validate_DefaultJCharTypes_IsC)
{
ASSERT_TRUE(JNI::ValidateSignature("C", jchar()));
ASSERT_TRUE(JNI::ValidateSignature("[C", jcharArray()));
}
TEST(Signature, Validate_AllDefaultJCharTypes_IsC)
{
ASSERT_TRUE(JNI::ValidateSignature("C[C", jchar(), jcharArray()));
}
TEST(Signature, Validate_DefaultJShortTypes_IsS)
{
ASSERT_TRUE(JNI::ValidateSignature("S", jshort()));
ASSERT_TRUE(JNI::ValidateSignature("[S", jshortArray()));
}
TEST(Signature, Validate_AllDefaultJShortTypes_IsS)
{
ASSERT_TRUE(JNI::ValidateSignature("S[S", jshort(), jshortArray()));
}
TEST(Signature, Validate_DefaultJIntTypes_IsI)
{
ASSERT_TRUE(JNI::ValidateSignature("I", jint()));
ASSERT_TRUE(JNI::ValidateSignature("[I", jintArray()));
}
TEST(Signature, Validate_AllDefaultJIntTypes_IsI)
{
ASSERT_TRUE(JNI::ValidateSignature("I[I", jint(), jintArray()));
}
TEST(Signature, Validate_DefaultJLongTypes_IsJ)
{
ASSERT_TRUE(JNI::ValidateSignature("J", jlong()));
ASSERT_TRUE(JNI::ValidateSignature("[J", jlongArray()));
}
TEST(Signature, Validate_AllDefaultJLongTypes_IsJ)
{
ASSERT_TRUE(JNI::ValidateSignature("J[J", jlong(), jlongArray()));
}
TEST(Signature, Validate_DefaultJFloatTypes_IsF)
{
ASSERT_TRUE(JNI::ValidateSignature("F", jfloat()));
ASSERT_TRUE(JNI::ValidateSignature("[F", jfloatArray()));
}
TEST(Signature, Validate_AllDefaultJFloatTypes_IsF)
{
ASSERT_TRUE(JNI::ValidateSignature("F[F", jfloat(), jfloatArray()));
}
TEST(Signature, Validate_DefaultJDoubleTypes_IsD)
{
ASSERT_TRUE(JNI::ValidateSignature("D", jdouble()));
ASSERT_TRUE(JNI::ValidateSignature("[D", jdoubleArray()));
}
TEST(Signature, Validate_AllDefaultJDoubleTypes_IsD)
{
ASSERT_TRUE(JNI::ValidateSignature("D[D", jdouble(), jdoubleArray()));
}
TEST(Signature, Validate_AllDefaultPrimtiveTypes_IsZZZBBCCSSIIJJFFDD)
{
ASSERT_TRUE(JNI::ValidateSignature(
"ZZ[ZB[BC[CS[SI[IJ[JF[FD[D",
bool(), jboolean(), jbooleanArray(),
jbyte(), jbyteArray(),
jchar(), jcharArray(),
jshort(), jshortArray(),
jint(), jintArray(),
jlong(), jlongArray(),
jfloat(), jfloatArray(),
jdouble(), jdoubleArray()
));
}
TEST(Signature, Validate_JClass_IsL_java_lang_Class)
{
jclass signatureClass = JNI::LoadClass("com/amazon/test/SimpleObject");
ASSERT_TRUE(JNI::ValidateSignature("Ljava/lang/Class;", signatureClass));
}
TEST(Signature, Validate_JString_IsL_java_lang_String)
{
JNIEnv* jniEnv = JNI::GetEnv();
jstring javaString = jniEnv->NewStringUTF("Test");
EXPECT_TRUE(JNI::ValidateSignature("Ljava/lang/String;", javaString));
jniEnv->DeleteLocalRef(javaString);
}
TEST(Signature, Validate_SimpleJObjectType_IsLcom_amazon_test_SimpleObject)
{
SimpleJavaObject simpleObject;
ASSERT_TRUE(JNI::ValidateSignature("Lcom/amazon/test/SimpleObject;", simpleObject.m_objectRef));
}
TEST(Signature, Validate_PolymorphicActivityType_IsLandroid_app_Activity)
{
jobject activity = Utils::GetActivityRef();
ASSERT_TRUE(JNI::ValidateSignature("Landroid/app/Activity;", activity));
}
TEST(Signature, Validate_JStringJClass_IsLjava_lang_StringLjava_lang_Class)
{
JNIEnv* jniEnv = JNI::GetEnv();
jclass signatureClass = JNI::LoadClass("com/amazon/test/SimpleObject");
jstring javaString = jniEnv->NewStringUTF("Test");
EXPECT_TRUE(JNI::ValidateSignature("Ljava/lang/String;Ljava/lang/Class;", javaString, signatureClass));
jniEnv->DeleteLocalRef(javaString);
}
TEST(Signature, Validate_AllTypes_IsZZZBBCCSSIIJJFFDDL_java_lang_StringL_java_lang_ClassLcom_amazon_test_SimpleObjectLandroid_app_Activity)
{
JNIEnv* jniEnv = JNI::GetEnv();
jstring javaString = jniEnv->NewStringUTF("Test");
SimpleJavaObject simpleObject;
jobject activity = Utils::GetActivityRef();
ASSERT_TRUE(JNI::ValidateSignature(
"ZZ[ZB[BC[CS[SI[IJ[JF[FD[DLjava/lang/String;Ljava/lang/Class;Lcom/amazon/test/SimpleObject;Landroid/app/Activity;",
bool(), jboolean(), jbooleanArray(),
jbyte(), jbyteArray(),
jchar(), jcharArray(),
jshort(), jshortArray(),
jint(), jintArray(),
jlong(), jlongArray(),
jfloat(), jfloatArray(),
jdouble(), jdoubleArray(),
javaString,
simpleObject.m_classRef,
simpleObject.m_objectRef,
activity
));
jniEnv->DeleteLocalRef(javaString);
}
TEST(Signature, Validate_ExtraParams_IsFalse)
{
ASSERT_FALSE(JNI::ValidateSignature("Z", JNI_TRUE, JNI_TRUE));
}
TEST(Signature, Validate_MissingParams_IsFalse)
{
ASSERT_FALSE(JNI::ValidateSignature("ZZ", JNI_TRUE));
}
TEST(Signature, Validate_WrongParms_IsFalse)
{
ASSERT_FALSE(JNI::ValidateSignature("ZI", JNI_TRUE, jfloat()));
}
} // namespace UnitTest
File diff suppressed because it is too large Load Diff
@@ -69,9 +69,11 @@ namespace UnitTest
// Note that ConvertToAbsolutePath will perform a realpath on the result. The result of AZ::Utils::GetExecutableDirectory
// uses AZ::Android::AndroidEnv::Get()->GetAppPrivateStoragePath() which will retrieve the storage path, but that path could
// be symlinked, so we need to perform a real path on it before comparison
char realExecutableDirectory[AZ::IO::MaxPathLength];
ASSERT_TRUE(realpath(executableDirectory, realExecutableDirectory));
char* realExecutableDirectory = realpath(executableDirectory, nullptr);
ASSERT_NE(realExecutableDirectory, nullptr);
EXPECT_STRCASEEQ(realExecutableDirectory, absolutePath->c_str());
free(realExecutableDirectory);
}
}
@@ -406,7 +406,7 @@ namespace AZ::IO
request->CreateFileMetaDataRetrieval(path);
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
EXPECT_FALSE(fileMetaData.m_found);
EXPECT_EQ(0, fileMetaData.m_fileSize);
});
@@ -424,7 +424,7 @@ namespace AZ::IO
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
EXPECT_TRUE(fileMetaData.m_found);
EXPECT_EQ(4_kib, fileMetaData.m_fileSize);
});
@@ -442,7 +442,7 @@ namespace AZ::IO
request->CreateFileMetaDataRetrieval(path);
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
EXPECT_FALSE(fileMetaData.m_found);
EXPECT_EQ(0, fileMetaData.m_fileSize);
});
@@ -460,7 +460,7 @@ namespace AZ::IO
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
EXPECT_TRUE(fileMetaData.m_found);
EXPECT_EQ(16_kib, fileMetaData.m_fileSize);
});
@@ -484,7 +484,7 @@ namespace AZ::IO
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
EXPECT_TRUE(fileMetaData.m_found);
EXPECT_EQ(4_kib, fileMetaData.m_fileSize);
});
@@ -502,7 +502,7 @@ namespace AZ::IO
request->CreateFileExistsCheck(invalidPath);
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
EXPECT_FALSE(fileExistsCheck.m_found);
});
@@ -519,7 +519,7 @@ namespace AZ::IO
request->CreateFileExistsCheck(path);
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
EXPECT_FALSE(fileExistsCheck.m_found);
});
@@ -535,7 +535,7 @@ namespace AZ::IO
request->CreateFileExistsCheck(m_dummyRequestPath);
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
EXPECT_TRUE(fileExistsCheck.m_found);
});
@@ -551,7 +551,7 @@ namespace AZ::IO
request->CreateFileExistsCheck(m_dummyRequestPath);
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
EXPECT_TRUE(fileExistsCheck.m_found);
});
@@ -573,7 +573,7 @@ namespace AZ::IO
request->CreateFileExistsCheck(m_dummyRequestPath);
request->SetCompletionCallback([](const FileRequest& request)
{
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
EXPECT_TRUE(fileExistsCheck.m_found);
});
@@ -603,7 +603,7 @@ namespace AZ::IO
AZ_POP_DISABLE_WARNING
{
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
auto& readRequest = AZStd::get<AZ::IO::Requests::ReadData>(request.GetCommand());
EXPECT_EQ(readRequest.m_size, fileSize);
EXPECT_STREQ(readRequest.m_path.GetAbsolutePath(), m_dummyFilepath.c_str());
};
@@ -648,7 +648,7 @@ namespace AZ::IO
AZ_POP_DISABLE_WARNING
{
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
auto& readRequest = AZStd::get<AZ::IO::Requests::ReadData>(request.GetCommand());
EXPECT_EQ(readRequest.m_size, unalignedSize);
EXPECT_EQ(readRequest.m_offset, unalignedOffset);
EXPECT_STREQ(readRequest.m_path.GetAbsolutePath(), m_dummyFilepath.c_str());
@@ -796,7 +796,7 @@ namespace AZ::IO
AZ_POP_DISABLE_WARNING
{
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
auto& readRequest = AZStd::get<AZ::IO::Requests::ReadData>(request.GetCommand());
EXPECT_EQ(readRequest.m_size, chunkSize);
EXPECT_EQ(readRequest.m_offset, i * chunkSize);
};
@@ -720,6 +720,49 @@ namespace SerializeTestClasses {
AZStd::intrusive_ptr<SmartPtrClass> m_intrusivePtr;
AZStd::unique_ptr<SmartPtrClass> m_uniquePtr;
};
struct ElementOverrideType
{
AZ_RTTI(ElementOverrideType, "{BAA18B6C-3CB3-476C-8B41-21EA7CE1F4CF}");
AZ_CLASS_ALLOCATOR(ElementOverrideType, AZ::SystemAllocator, 0);
virtual ~ElementOverrideType() = default;
static AZ::ObjectStreamWriteOverrideResponse Writer(
AZ::SerializeContext::EnumerateInstanceCallContext& callContext,
const void* object,
const AZ::SerializeContext::ClassData&,
const AZ::SerializeContext::ClassElement*)
{
auto ptr = static_cast<const ElementOverrideType*>(object);
if(ptr)
{
switch(ptr->m_field)
{
case 0:
{
float output{};
callContext.m_context->EnumerateInstanceConst(&callContext, &output, azrtti_typeid<decltype(output)>(), nullptr, nullptr);
return AZ::ObjectStreamWriteOverrideResponse::CompletedWrite;
}
case 1:
return AZ::ObjectStreamWriteOverrideResponse::FallbackToDefaultWrite;
}
}
return AZ::ObjectStreamWriteOverrideResponse::AbortWrite;
}
static void Reflect(AZ::SerializeContext& sc)
{
sc.Class<ElementOverrideType>()
->Attribute(AZ::SerializeContextAttributes::ObjectStreamWriteElementOverride, &ElementOverrideType::Writer)
->Field("field", &ElementOverrideType::m_field);
}
int m_field = 0;
};
} //SerializeTestClasses
namespace AZ
@@ -1698,6 +1741,66 @@ namespace UnitTest
}
}
TEST_F(Serialization, ElementOverrideTest_DefaultSerializationWorks)
{
ElementOverrideType::Reflect(*m_serializeContext);
ElementOverrideType testType;
testType.m_field = 1; // Our custom serializer will use the default output when this value is 1
AZStd::vector<char> buffer;
IO::ByteContainerStream<AZStd::vector<char>> stream(&buffer);
ASSERT_TRUE(Utils::SaveObjectToStream(stream, DataStream::ST_XML, &testType, m_serializeContext.get()));
constexpr const char* expectedValue =
R"(<ObjectStream version="3">)" "\n"
"\t" R"(<Class name="ElementOverrideType" type="{BAA18B6C-3CB3-476C-8B41-21EA7CE1F4CF}">)" "\n"
"\t\t" R"(<Class name="int" field="field" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>)" "\n"
"\t" R"(</Class>)" "\n"
R"(</ObjectStream>)";
AZStd::string result(buffer.data(), stream.GetLength());
AZ::StringFunc::TrimWhiteSpace(result, true, true);
EXPECT_STREQ(result.c_str(), expectedValue);
}
TEST_F(Serialization, ElementOverrideTest_CustomSerializationWorks)
{
ElementOverrideType::Reflect(*m_serializeContext);
ElementOverrideType testType;
testType.m_field = 0; // Our custom serializer will do its own output when this value is 0
AZStd::vector<char> buffer;
IO::ByteContainerStream<AZStd::vector<char>> stream(&buffer);
ASSERT_TRUE(Utils::SaveObjectToStream(stream, DataStream::ST_XML, &testType, m_serializeContext.get()));
constexpr const char* expectedValue =
R"(<ObjectStream version="3">)" "\n"
"\t" R"(<Class name="float" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>)" "\n"
R"(</ObjectStream>)";
AZStd::string result(buffer.data(), stream.GetLength());
AZ::StringFunc::TrimWhiteSpace(result, true, true);
EXPECT_STREQ(result.c_str(), expectedValue);
}
TEST_F(Serialization, ElementOverrideTest_FailureCase)
{
ElementOverrideType::Reflect(*m_serializeContext);
ElementOverrideType testType;
testType.m_field = 2; // Our custom serializer will report a failure when this value is not 0/1
AZStd::vector<char> buffer;
IO::ByteContainerStream<AZStd::vector<char>> stream(&buffer);
AZ_TEST_START_TRACE_SUPPRESSION;
ASSERT_FALSE(Utils::SaveObjectToStream(stream, DataStream::ST_XML, &testType, m_serializeContext.get()));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(Serialization, ContainerTypeContainedTypeDiffersByPointer)
{
ContainersTest::ReflectVectorOfInts(m_serializeContext.get());
@@ -475,7 +475,7 @@ namespace JsonSerializationTests
EXPECT_STRCASEEQ("value_42", worldKey->second.m_value.c_str());
}
TEST_F(JsonMapSerializerTests, Load_DuplicateKey_EntryIgnored)
TEST_F(JsonMapSerializerTests, Load_DuplicateKey_EntryUpdated)
{
using namespace AZ::JsonSerializationResult;
@@ -489,12 +489,12 @@ namespace JsonSerializationTests
StringMap values;
ResultCode result = m_unorderedMapSerializer.Load(&values, azrtti_typeid(&values), *m_jsonDocument, *m_jsonDeserializationContext);
EXPECT_EQ(Processing::PartialAlter, result.GetProcessing());
EXPECT_EQ(Outcomes::Unavailable, result.GetOutcome());
EXPECT_EQ(Processing::Completed, result.GetProcessing());
EXPECT_EQ(Outcomes::Success, result.GetOutcome());
auto entry = values.find("Hello");
ASSERT_NE(values.end(), entry);
EXPECT_STRCASEEQ("World", entry->second.c_str());
EXPECT_EQ("Other", entry->second);
}
TEST_F(JsonMapSerializerTests, Load_DuplicateMultiKey_LoadEverything)
@@ -536,8 +536,8 @@ namespace JsonSerializationTests
ResultCode result = m_unorderedMapSerializer.Load(&values,
azrtti_typeid(&values), *m_jsonDocument, *m_jsonDeserializationContext);
EXPECT_EQ(Processing::Altered, result.GetProcessing());
EXPECT_EQ(Outcomes::Unavailable, result.GetOutcome());
EXPECT_EQ(Processing::Completed, result.GetProcessing());
EXPECT_EQ(Outcomes::Success, result.GetOutcome());
auto entry = values.find("Hello");
ASSERT_NE(values.end(), entry);
@@ -100,7 +100,7 @@ namespace AZ::IO
void QueueReadRequest(FileRequest* request)
{
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
if (data)
{
if (m_fakeFileFound)
@@ -122,15 +122,15 @@ namespace AZ::IO
m_context->MarkRequestAsCompleted(request);
}
else if (
AZStd::holds_alternative<FileRequest::FlushData>(request->GetCommand()) ||
AZStd::holds_alternative<FileRequest::FlushAllData>(request->GetCommand()))
AZStd::holds_alternative<Requests::FlushData>(request->GetCommand()) ||
AZStd::holds_alternative<Requests::FlushAllData>(request->GetCommand()))
{
request->SetStatus(IStreamerTypes::RequestStatus::Completed);
m_context->MarkRequestAsCompleted(request);
}
else if (AZStd::holds_alternative<FileRequest::FileMetaDataRetrievalData>(request->GetCommand()))
else if (AZStd::holds_alternative<Requests::FileMetaDataRetrievalData>(request->GetCommand()))
{
auto& data2 = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
auto& data2 = AZStd::get<Requests::FileMetaDataRetrievalData>(request->GetCommand());
data2.m_found = m_fakeFileFound;
data2.m_fileSize = m_fakeFileLength;
request->SetStatus(m_fakeFileFound ? IStreamerTypes::RequestStatus::Completed : IStreamerTypes::RequestStatus::Failed);
@@ -158,16 +158,16 @@ namespace AZ::IO
void QueueCanceledReadRequest(FileRequest* request)
{
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
if (data)
{
ReadFile(data->m_output, data->m_path, data->m_offset, data->m_size);
request->SetStatus(IStreamerTypes::RequestStatus::Canceled);
m_context->MarkRequestAsCompleted(request);
}
else if (AZStd::holds_alternative<FileRequest::FileMetaDataRetrievalData>(request->GetCommand()))
else if (AZStd::holds_alternative<Requests::FileMetaDataRetrievalData>(request->GetCommand()))
{
auto& data2 = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
auto& data2 = AZStd::get<Requests::FileMetaDataRetrievalData>(request->GetCommand());
data2.m_found = true;
data2.m_fileSize = m_fakeFileLength;
request->SetStatus(IStreamerTypes::RequestStatus::Completed);
@@ -145,7 +145,7 @@ namespace AZ::IO
void PrepareReadRequest(FileRequest* request)
{
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
ASSERT_NE(nullptr, data);
u64 size = data->m_size >> 2;
@@ -9,6 +9,7 @@
#include <gmock/gmock.h>
#include <AzCore/IO/IStreamer.h>
#include <AzCore/IO/Streamer/FileRequest.h>
using namespace AZ::IO;
@@ -155,7 +155,7 @@ namespace AZ::IO
{
EXPECT_EQ(subRequests[i]->GetParent(), readRequest);
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequests[i]->GetCommand());
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequests[i]->GetCommand());
ASSERT_NE(nullptr, data);
EXPECT_EQ(SplitSize, data->m_size);
EXPECT_EQ(SplitSize * i, data->m_offset);
@@ -210,7 +210,7 @@ namespace AZ::IO
{
EXPECT_EQ(subRequests[i]->GetParent(), readRequest);
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequests[i]->GetCommand());
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequests[i]->GetCommand());
ASSERT_NE(nullptr, data);
EXPECT_EQ(SplitSize, data->m_size);
EXPECT_EQ(SplitSize * i, data->m_offset);
@@ -230,7 +230,7 @@ namespace AZ::IO
{
EXPECT_EQ(subRequests[i]->GetParent(), readRequest);
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequests[i]->GetCommand());
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequests[i]->GetCommand());
ASSERT_NE(nullptr, data);
EXPECT_EQ(SplitSize, data->m_size);
EXPECT_EQ(SplitSize * (batchSize + i), data->m_offset);
@@ -265,7 +265,7 @@ namespace AZ::IO
m_readSplitter->QueueRequest(readRequest);
ASSERT_NE(nullptr, subRequest);
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequest->GetCommand());
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequest->GetCommand());
EXPECT_NE(buffer, data->m_output);
EXPECT_EQ(readSize, data->m_size);
EXPECT_EQ(0, data->m_offset);
@@ -311,7 +311,7 @@ namespace AZ::IO
m_readSplitter->QueueRequest(readRequest);
ASSERT_NE(nullptr, subRequest);
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequest->GetCommand());
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequest->GetCommand());
EXPECT_NE(buffer, data->m_output);
EXPECT_EQ(readSize + offsetAdjustment, data->m_size);
EXPECT_EQ(0, data->m_offset);
@@ -9,6 +9,7 @@
#include <AzCore/Casting/lossy_cast.h>
#include <AzCore/IO/Streamer/Streamer.h>
#include <AzCore/IO/Streamer/Scheduler.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/std/parallel/atomic.h>
#include <AzCore/std/parallel/binary_semaphore.h>
#include <AzCore/std/smart_ptr/make_shared.h>
@@ -86,7 +87,7 @@ namespace AZ::IO
.WillOnce([this](FileRequest* request)
{
AZ_Assert(m_streamerContext, "AZ::IO::Streamer is not ready to process requests.");
auto readData = AZStd::get_if<FileRequest::ReadRequestData>(&request->GetCommand());
auto readData = AZStd::get_if<Requests::ReadRequestData>(&request->GetCommand());
AZ_Assert(readData, "Test didn't pass in the correct request.");
FileRequest* read = m_streamerContext->GetNewInternalRequest();
read->CreateRead(request, readData->m_output, readData->m_outputSize, readData->m_path,
@@ -99,7 +100,7 @@ namespace AZ::IO
.WillOnce([this](FileRequest* request)
{
AZ_Assert(m_streamerContext, "AZ::IO::Streamer is not ready to process requests.");
auto readData = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
auto readData = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
AZ_Assert(readData, "Test didn't pass in the correct request.");
auto output = reinterpret_cast<uint8_t*>(readData->m_output);
AZ_Assert(output != nullptr, "Output buffer has not been set.");
@@ -304,7 +305,7 @@ namespace AZ::IO
EXPECT_CALL(*m_mock, QueueRequest(_)).Times(1)
.WillOnce(Invoke([this](FileRequest* request)
{
auto* read = request->GetCommandFromChain<FileRequest::ReadRequestData>();
auto* read = request->GetCommandFromChain<Requests::ReadRequestData>();
ASSERT_NE(nullptr, read);
EXPECT_LT(read->m_deadline, FileRequest::s_noDeadlineTime);
EXPECT_EQ(read->m_priority, IStreamerTypes::s_priorityHighest);
@@ -10,6 +10,7 @@
#include <limits>
#include <AzCore/IO/IStreamerTypes.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/IO/Streamer/StreamerContext.h>
#include <AzCore/IO/Streamer/StreamStackEntry.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
@@ -10,6 +10,7 @@
#include <FileIOBaseTestTypes.h>
#include <AzCore/IO/CompressionBus.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/IO/Streamer/Streamer.h>
#include <AzCore/IO/Streamer/StreamerComponent.h>
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
+32 -32
View File
@@ -447,13 +447,13 @@ namespace UnitTest
{
x -= 1;
});
// a <-- Root
// / \
// b c
// \ /
// d
/*
a <-- Root
/ \
b c
\ /
d
*/
a.Precedes(b, c);
d.Follows(b, c);
@@ -522,20 +522,20 @@ namespace UnitTest
{
x -= 1;
});
// NOTE: The ideal way to express this topology is without the wait on the subgraph
// at task g, but this is more an illustrative test. Better is to express the entire
// graph in a single larger graph.
// a <-- Root
// / \
// b c - f
// \ \ \
// \ e - g
// \ /
// \ /
// \ /
// d
/*
NOTE: The ideal way to express this topology is without the wait on the subgraph
at task g, but this is more an illustrative test. Better is to express the entire
graph in a single larger graph.
a <-- Root
/ \
b c - f
\ \ \
\ e - g
\ /
\ /
\ /
d
*/
a.Precedes(b);
a.Precedes(c);
b.Precedes(d);
@@ -593,17 +593,17 @@ namespace UnitTest
{
x += 0b1000;
});
// a <-- Root
// / \
// b c - f
// \ \ \
// \ e - g
// \ /
// \ /
// \ /
// d
/*
a <-- Root
/ \
b c - f
\ \ \
\ e - g
\ /
\ /
\ /
d
*/
a.Precedes(b, c);
b.Precedes(d);
c.Precedes(e, f);
@@ -11,6 +11,7 @@
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Serialization/Utils.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/std/parallel/condition_variable.h>
namespace UnitTest
{
@@ -182,6 +182,7 @@ set(FILES
AZStd/Atomics.cpp
AZStd/Any.cpp
AZStd/Bitset.cpp
AZStd/ConceptsTests.cpp
AZStd/CreateDestroy.cpp
AZStd/ConcurrentAllocators.cpp
AZStd/ConcurrentContainers.cpp
@@ -205,9 +206,11 @@ set(FILES
AZStd/Optional.cpp
AZStd/Pair.cpp
AZStd/Parallel.cpp
AZStd/RangesTests.cpp
AZStd/ScopedLockTests.cpp
AZStd/SetsIntrusive.cpp
AZStd/SmartPtr.cpp
AZStd/SpanTests.cpp
AZStd/String.cpp
AZStd/TypeTraits.cpp
AZStd/Tuple.cpp