Updated all array_view uses with the C++20 span. (#7157)
* Updated all array_view uses with the C++20 span. The updates were done in the following order 1. `AZStd::array_view<([^>].+)\* ?>` -> `AZStd::span<\1 const>` 2. `AZStd::array_view<(?:const )(.+)>` -> `AZStd::span<const \1>` 3. `AZStd::array_view` -> `AZStd::span` Removed the implementation of array_view. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Added missing whitespace between `const` and the typename for spans. Updated the ShaderTest comparison of the ShaderResourceGroupLayout span to compare the sizes as well Updated comments on some of the methods that stated that they return "an array" to mention they return "a span". Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
48cea89910
commit
b9824ed172
@@ -13,7 +13,6 @@ set(FILES
|
||||
Instance/InstanceData.h
|
||||
Instance/InstanceData.cpp
|
||||
Instance/InstanceDatabase.h
|
||||
std/containers/array_view.h
|
||||
std/containers/fixed_vector_set.h
|
||||
std/containers/lru_cache.h
|
||||
std/containers/vector_set.h
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
/**
|
||||
* Immutable wrapper for an array of data. It does not maintain storage for the data,
|
||||
* but just holds pointers to mark the beginning and end of the array. It can be
|
||||
* conveniently constructed from a variety of other container types like array,
|
||||
* vector, and fixed_vector.
|
||||
*
|
||||
* Example:
|
||||
* Given "void Func(AZStd::array_view<int> a) {...}" you can call...
|
||||
* - Func({1,2,3});
|
||||
* - AZStd::array<int,3> a = {1,2,3};
|
||||
* Func(a);
|
||||
* - AZStd::vector<int> v = {1,2,3};
|
||||
* Func(v);
|
||||
* - AZStd::fixed_vector<int,10> fv = {1,2,3};
|
||||
* Func(fv);
|
||||
*
|
||||
* Since the array_view does not copy and store any data, it is only valid as long as the data used to create it is valid.
|
||||
*/
|
||||
template <class Element>
|
||||
class array_view final
|
||||
{
|
||||
public:
|
||||
using value_type = Element;
|
||||
|
||||
using pointer = value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
|
||||
using size_type = AZStd::size_t;
|
||||
using difference_type = AZStd::ptrdiff_t;
|
||||
|
||||
using iterator = const value_type*;
|
||||
using const_iterator = const value_type*;
|
||||
using reverse_iterator = AZStd::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = AZStd::reverse_iterator<const_iterator>;
|
||||
|
||||
array_view()
|
||||
: m_begin(nullptr)
|
||||
, m_end(nullptr)
|
||||
{ }
|
||||
|
||||
~array_view() = default;
|
||||
|
||||
array_view(const_pointer s, size_type length)
|
||||
: m_begin(s)
|
||||
, m_end(m_begin + length)
|
||||
{
|
||||
if (length == 0) erase();
|
||||
}
|
||||
|
||||
array_view(const_pointer first, const_pointer last)
|
||||
: m_begin(first)
|
||||
, m_end(last)
|
||||
{ }
|
||||
|
||||
// We explicitly delete this constructor because it's too easy to accidentally
|
||||
// create an array_view to just the first element instead of an entire array.
|
||||
array_view(const_pointer s) = delete;
|
||||
|
||||
template<AZStd::size_t N>
|
||||
array_view(const AZStd::array<value_type, N>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
array_view(const AZStd::vector<value_type>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
template<AZStd::size_t N>
|
||||
array_view(const AZStd::fixed_vector<value_type, N>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
array_view(const array_view&) = default;
|
||||
|
||||
array_view(array_view&& other)
|
||||
: array_view(other.m_begin, other.m_end)
|
||||
{
|
||||
#if AZ_DEBUG_BUILD // Clearing the original pointers isn't necessary, but is good for debugging
|
||||
other.m_begin = nullptr;
|
||||
other.m_end = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
array_view& operator=(const array_view& other) = default;
|
||||
|
||||
array_view& operator=(array_view&& other)
|
||||
{
|
||||
m_begin = other.m_begin;
|
||||
m_end = other.m_end;
|
||||
#if AZ_DEBUG_BUILD // Clearing the original pointers isn't necessary, but is good for debugging
|
||||
other.m_begin = nullptr;
|
||||
other.m_end = nullptr;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_type size() const { return m_end - m_begin; }
|
||||
|
||||
bool empty() const { return m_end == m_begin; }
|
||||
|
||||
const_pointer data() const { return m_begin; }
|
||||
|
||||
const_reference operator[](size_type index) const
|
||||
{
|
||||
AZ_Assert(index < size(), "index value is out of range");
|
||||
return m_begin[index];
|
||||
}
|
||||
|
||||
void erase() { m_begin = m_end = nullptr; }
|
||||
|
||||
iterator begin() const { return m_begin; }
|
||||
iterator end() const { return m_end; }
|
||||
const_iterator cbegin() const { return m_begin; }
|
||||
const_iterator cend() const { return m_end; }
|
||||
reverse_iterator rbegin() const { return reverse_iterator(m_end); }
|
||||
reverse_iterator rend() const { return reverse_iterator(m_begin); }
|
||||
const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); }
|
||||
const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); }
|
||||
|
||||
friend bool operator==(array_view lhs, array_view rhs)
|
||||
{
|
||||
return lhs.m_begin == rhs.m_begin && lhs.m_end == rhs.m_end;
|
||||
}
|
||||
|
||||
friend bool operator!=(array_view lhs, array_view rhs) { return !(lhs == rhs); }
|
||||
friend bool operator< (array_view lhs, array_view rhs) { return lhs.m_begin < rhs.m_begin || lhs.m_begin == rhs.m_begin && lhs.m_end < rhs.m_end; }
|
||||
friend bool operator> (array_view lhs, array_view rhs) { return lhs.m_begin > rhs.m_begin || lhs.m_begin == rhs.m_begin && lhs.m_end > rhs.m_end; }
|
||||
friend bool operator<=(array_view lhs, array_view rhs) { return lhs == rhs || lhs < rhs; }
|
||||
friend bool operator>=(array_view lhs, array_view rhs) { return lhs == rhs || lhs > rhs; }
|
||||
|
||||
private:
|
||||
const_pointer m_begin;
|
||||
const_pointer m_end;
|
||||
};
|
||||
} // namespace AZStd
|
||||
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
* 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 <AtomCore/std/containers/array_view.h>
|
||||
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using namespace AZStd;
|
||||
|
||||
class ArrayView : public AllocatorsTestFixture
|
||||
{
|
||||
protected:
|
||||
template<typename T>
|
||||
void ExpectEqual(initializer_list<T> expectedValues, array_view<T> arrayView)
|
||||
{
|
||||
EXPECT_EQ(false, arrayView.empty());
|
||||
EXPECT_EQ(expectedValues.size(), arrayView.size());
|
||||
|
||||
typename AZStd::vector<T>::const_iterator iterator = arrayView.begin();
|
||||
|
||||
for (int i = 0; i < expectedValues.size(); ++i, ++iterator)
|
||||
{
|
||||
EXPECT_EQ(expectedValues.begin()[i], arrayView[i]);
|
||||
EXPECT_EQ(expectedValues.begin()[i], *iterator);
|
||||
}
|
||||
|
||||
EXPECT_EQ(iterator, arrayView.end());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(ArrayView, DefaultConstructor)
|
||||
{
|
||||
array_view<bool> defaultView;
|
||||
|
||||
EXPECT_EQ(nullptr, defaultView.begin());
|
||||
EXPECT_EQ(nullptr, defaultView.end());
|
||||
EXPECT_EQ(0, defaultView.size());
|
||||
EXPECT_EQ(true, defaultView.empty());
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, PointerConstructor1)
|
||||
{
|
||||
int originalValues[4] = { 2,3,4,5 };
|
||||
array_view<int> view(originalValues, AZ_ARRAY_SIZE(originalValues));
|
||||
|
||||
ExpectEqual({ 2,3,4,5 }, view);
|
||||
|
||||
EXPECT_EQ(originalValues, view.begin());
|
||||
EXPECT_EQ(&originalValues[4], view.end());
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, PointerConstructor2)
|
||||
{
|
||||
int originalValues[3] = { 6,7,8 };
|
||||
array_view<int> view(originalValues, &originalValues[3]);
|
||||
|
||||
ExpectEqual({ 6,7,8 }, view);
|
||||
|
||||
EXPECT_EQ(originalValues, view.begin());
|
||||
EXPECT_EQ(&originalValues[3], view.end());
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, ArrayConstructor)
|
||||
{
|
||||
array<int, 4> originalValues = { 9,10,11,12 };
|
||||
array_view<int> view(originalValues);
|
||||
|
||||
ExpectEqual({ 9,10,11,12 }, view);
|
||||
|
||||
EXPECT_EQ(originalValues.begin(), view.begin());
|
||||
EXPECT_EQ(originalValues.end(), view.end());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(ArrayView, VectorConstructor)
|
||||
{
|
||||
vector<int> originalValues = { 13,14,15,16,17,18 };
|
||||
array_view<int> view(originalValues);
|
||||
|
||||
ExpectEqual({ 13,14,15,16,17,18 }, view);
|
||||
|
||||
EXPECT_EQ(originalValues.begin(), view.begin());
|
||||
EXPECT_EQ(originalValues.end(), view.end());
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, FixedVectorConstructor)
|
||||
{
|
||||
fixed_vector<int, 10> originalValues = { 17,18,19 }; // Note that even though the fixed_vector capacity is 10, it's size is 3, so the view size will be 3 as well
|
||||
array_view<int> view(originalValues);
|
||||
|
||||
ExpectEqual({ 17,18,19 }, view);
|
||||
|
||||
EXPECT_EQ(originalValues.begin(), view.begin());
|
||||
EXPECT_EQ(originalValues.end(), view.end());
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, CopyConstructor)
|
||||
{
|
||||
fixed_vector<int, 2> originalValues = { 27,28 };
|
||||
|
||||
array_view<int> view1(originalValues);
|
||||
array_view<int> view2(view1);
|
||||
|
||||
ExpectEqual({ 27,28 }, view2);
|
||||
|
||||
EXPECT_EQ(view1.begin(), view2.begin());
|
||||
EXPECT_EQ(view1.end(), view2.end());
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, MoveConstructor)
|
||||
{
|
||||
int originalValues[] = { 29,30,31 };
|
||||
array_view<int> view1(originalValues, AZ_ARRAY_SIZE(originalValues));
|
||||
array_view<int> view2(AZStd::move(view1));
|
||||
|
||||
ExpectEqual({ 29,30,31 }, view2);
|
||||
|
||||
EXPECT_EQ(originalValues, view2.begin());
|
||||
EXPECT_EQ(&originalValues[3], view2.end());
|
||||
|
||||
// This isn't strictly necessary but is a good way to make sure the move
|
||||
// constructor actually exists and it itn't just calling the copy constructor
|
||||
#if AZ_DEBUG_BUILD // The pointers are only cleared in debug
|
||||
EXPECT_EQ(nullptr, view1.begin());
|
||||
EXPECT_EQ(nullptr, view1.end());
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, AssignmentOperator)
|
||||
{
|
||||
fixed_vector<int, 4> originalValues = { 32,33,34,35 };
|
||||
|
||||
array_view<int> view1(originalValues);
|
||||
array_view<int> view2;
|
||||
|
||||
view2 = view1;
|
||||
|
||||
ExpectEqual({ 32,33,34,35 }, view2);
|
||||
|
||||
EXPECT_EQ(view1.begin(), view2.begin());
|
||||
EXPECT_EQ(view1.end(), view2.end());
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, MoveAssignmentOperator)
|
||||
{
|
||||
int originalValues[] = { 36,37,38,39,40 };
|
||||
array_view<int> view1(originalValues, AZ_ARRAY_SIZE(originalValues));
|
||||
array_view<int> view2;
|
||||
view2 = AZStd::move(view1);
|
||||
|
||||
ExpectEqual({ 36,37,38,39,40 }, view2);
|
||||
|
||||
EXPECT_EQ(originalValues, view2.begin());
|
||||
EXPECT_EQ(&originalValues[5], view2.end());
|
||||
|
||||
// This isn't strictly necessary but is a good way to make sure the move
|
||||
// assignment operator actually exists and it itn't just calling the norm
|
||||
// assignment operator
|
||||
#if AZ_DEBUG_BUILD // The pointers are only cleared in debug
|
||||
EXPECT_EQ(nullptr, view1.begin());
|
||||
EXPECT_EQ(nullptr, view1.end());
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, Erase)
|
||||
{
|
||||
fixed_vector<int, 4> originalValues = { 1,2,3,4 };
|
||||
|
||||
array_view<int> view(originalValues);
|
||||
view.erase();
|
||||
|
||||
EXPECT_EQ(nullptr, view.begin());
|
||||
EXPECT_EQ(nullptr, view.end());
|
||||
EXPECT_EQ(0, view.size());
|
||||
EXPECT_EQ(true, view.empty());
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, BeginAndEnd)
|
||||
{
|
||||
fixed_vector<int, 4> originalValues = { 1,2,3,4 };
|
||||
|
||||
array_view<int> view(originalValues);
|
||||
|
||||
EXPECT_EQ(1, view.begin()[0]);
|
||||
EXPECT_EQ(4, view.end()[-1]);
|
||||
EXPECT_EQ(1, view.cbegin()[0]);
|
||||
EXPECT_EQ(4, view.cend()[-1]);
|
||||
EXPECT_EQ(4, view.rbegin()[0]);
|
||||
EXPECT_EQ(1, view.rend()[-1]);
|
||||
EXPECT_EQ(4, view.crbegin()[0]);
|
||||
EXPECT_EQ(1, view.crend()[-1]);
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, ImplicitConstruction)
|
||||
{
|
||||
// This test verifies that we can pass in various non-array_view types
|
||||
// into functions that take an array_view
|
||||
|
||||
// The compile cannot detect the correct template type so that has to be specified explicitly
|
||||
|
||||
ExpectEqual<int>({ 1,2,3 }, vector<int>({ 1,2,3 }));
|
||||
ExpectEqual<int>({ 1,2,3 }, fixed_vector<int, 3>({ 1,2,3 }));
|
||||
ExpectEqual<int>({ 1,2,3 }, array<int, 3>({ 1,2,3 }));
|
||||
}
|
||||
|
||||
void CheckComparisonOperators(bool areEqual, array_view<int> a, array_view<int> b)
|
||||
{
|
||||
EXPECT_EQ(areEqual, a == b);
|
||||
|
||||
// For less/greater operators, the exact order doesn't really matter;
|
||||
// We just check for internal consistency
|
||||
if (areEqual)
|
||||
{
|
||||
EXPECT_EQ(false, a != b);
|
||||
EXPECT_EQ(false, a < b);
|
||||
EXPECT_EQ(false, a > b);
|
||||
EXPECT_EQ(true, a <= b);
|
||||
EXPECT_EQ(true, a >= b);
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_EQ(true, a != b);
|
||||
|
||||
EXPECT_EQ(a > b, a >= b);
|
||||
EXPECT_EQ(a < b, a <= b);
|
||||
|
||||
EXPECT_NE(a > b, a < b);
|
||||
EXPECT_NE(a >= b, a <= b);
|
||||
EXPECT_NE(a >= b, a < b);
|
||||
EXPECT_NE(a > b, a <= b);
|
||||
EXPECT_NE(a <= b, a > b);
|
||||
EXPECT_NE(a < b, a >= b);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, ComparisonOperators)
|
||||
{
|
||||
int arrayA[] = { 1,2,3 };
|
||||
int arrayB[] = { 1,2,3 };
|
||||
|
||||
array_view<int> arrayA_view(arrayA, 3);
|
||||
array_view<int> arrayB_view(arrayB, 3);
|
||||
array_view<int> arrayA_otherView(arrayA, 3);
|
||||
// view of a sub-array aligned to the beginning of the array
|
||||
array_view<int> arrayA_headView(arrayA, 2);
|
||||
array_view<int> arrayB_headView(arrayB, 2);
|
||||
// view of a sub-array aligned to the end of the array
|
||||
array_view<int> arrayA_tailView(&arrayA[1], 2);
|
||||
array_view<int> arrayB_tailView(&arrayB[1], 2);
|
||||
// view of a sub-array in the middle of the array
|
||||
array_view<int> arrayA_centerView(&arrayA[1], 1);
|
||||
array_view<int> arrayB_centerView(&arrayB[1], 1);
|
||||
|
||||
// Same view
|
||||
CheckComparisonOperators(true, arrayA_view, arrayA_view);
|
||||
|
||||
// Different view, same array
|
||||
CheckComparisonOperators(true, arrayA_view, arrayA_otherView);
|
||||
CheckComparisonOperators(true, arrayA_otherView, arrayA_view);
|
||||
|
||||
// Different arrays
|
||||
CheckComparisonOperators(false, arrayA_view, arrayB_view);
|
||||
CheckComparisonOperators(false, arrayB_view, arrayA_view);
|
||||
|
||||
// Same arrays, but one is a just a subset of the array
|
||||
CheckComparisonOperators(false, arrayA_view, arrayA_headView);
|
||||
CheckComparisonOperators(false, arrayA_view, arrayA_tailView);
|
||||
CheckComparisonOperators(false, arrayA_view, arrayA_centerView);
|
||||
CheckComparisonOperators(false, arrayA_headView, arrayA_view);
|
||||
CheckComparisonOperators(false, arrayA_tailView, arrayA_view);
|
||||
CheckComparisonOperators(false, arrayA_centerView, arrayA_view);
|
||||
|
||||
// Different arrays, different lengths
|
||||
CheckComparisonOperators(false, arrayA_view, arrayB_headView);
|
||||
CheckComparisonOperators(false, arrayB_view, arrayA_headView);
|
||||
CheckComparisonOperators(false, arrayB_headView, arrayA_view);
|
||||
CheckComparisonOperators(false, arrayA_headView, arrayB_view);
|
||||
}
|
||||
|
||||
TEST_F(ArrayView, AssertOutOfBounds)
|
||||
{
|
||||
array_view<int> view({ 1,2,3,4 });
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
|
||||
view[4];
|
||||
view[5];
|
||||
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,6 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
ArrayView.cpp
|
||||
ConcurrencyCheckerTests.cpp
|
||||
InstanceDatabase.cpp
|
||||
lru_cache.cpp
|
||||
|
||||
Reference in New Issue
Block a user