Merge branch 'development' into memory/benchmarks
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
#include <AzCore/Module/Module.h>
|
||||
#include <AzCore/Module/ModuleManager.h>
|
||||
|
||||
#include <AzCore/IO/Path/PathReflect.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
#include <AzCore/Driller/Driller.h>
|
||||
@@ -1547,7 +1548,7 @@ namespace AZ
|
||||
// reflect name dictionary.
|
||||
Name::Reflect(context);
|
||||
// reflect path
|
||||
IO::PathReflection::Reflect(context);
|
||||
IO::PathReflect(context);
|
||||
|
||||
// reflect the SettingsRegistryInterface, SettignsRegistryImpl and the global Settings Registry
|
||||
// instance (AZ::SettingsRegistry::Get()) into the Behavior Context
|
||||
|
||||
@@ -32,7 +32,16 @@ namespace AZ
|
||||
template <typename BASE_TYPE, ThreadSafety THREAD_SAFETY>
|
||||
inline void ConsoleDataWrapper<BASE_TYPE, THREAD_SAFETY>::operator =(const BASE_TYPE& rhs)
|
||||
{
|
||||
const BASE_TYPE currentValue = this->m_value;
|
||||
// Do the value assignment outside new value check.
|
||||
// Client code can supply a type for m_value that overrides the operator= function and trigger side effects
|
||||
// in the operator= function body. Doing the assignment outside the value change check avoids those side
|
||||
// effects not being triggered because AzCore believes the value wouldn't change.
|
||||
this->m_value = rhs;
|
||||
if (currentValue != rhs)
|
||||
{
|
||||
InvokeCallback();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename BASE_TYPE, ThreadSafety THREAD_SAFETY>
|
||||
|
||||
@@ -50,13 +50,4 @@ namespace AZ::IO
|
||||
const PathIterator<Path>& rhs);
|
||||
template bool operator!=<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
|
||||
const PathIterator<FixedMaxPath>& rhs);
|
||||
|
||||
void PathReflection::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AZ::IO::Path>()
|
||||
->Field("m_path", &AZ::IO::Path::m_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ namespace AZ::IO
|
||||
|
||||
// native format observers
|
||||
//! Returns string_view stored within the PathView
|
||||
constexpr AZStd::string_view Native() const noexcept;
|
||||
constexpr const AZStd::string_view& Native() const noexcept;
|
||||
constexpr AZStd::string_view& Native() noexcept;
|
||||
//! Conversion operator to retrieve string_view stored within the PathView
|
||||
constexpr explicit operator AZStd::string_view() const noexcept;
|
||||
|
||||
@@ -321,7 +322,6 @@ namespace AZ::IO
|
||||
using const_iterator = const PathIterator<BasicPath>;
|
||||
using iterator = const_iterator;
|
||||
friend PathIterator<BasicPath>;
|
||||
friend struct PathReflection;
|
||||
|
||||
// constructors and destructor
|
||||
constexpr BasicPath() = default;
|
||||
@@ -665,6 +665,7 @@ namespace AZ::IO
|
||||
namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_SPECIALIZE(AZ::IO::Path, "{88E0A40F-3085-4CAB-8B11-EF5A2659C71A}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(AZ::IO::FixedMaxPath, "{FA6CA49F-376A-417C-9767-DD50744DF203}");
|
||||
}
|
||||
|
||||
namespace AZ::IO
|
||||
|
||||
@@ -101,7 +101,11 @@ namespace AZ::IO
|
||||
}
|
||||
|
||||
// native format observers
|
||||
constexpr auto PathView::Native() const noexcept -> AZStd::string_view
|
||||
constexpr auto PathView::Native() const noexcept -> const AZStd::string_view&
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
constexpr auto PathView::Native() noexcept -> AZStd::string_view&
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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/IO/Path/Path.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
template <typename PathType>
|
||||
struct PathSerializer
|
||||
: public SerializeContext::IDataSerializer
|
||||
{
|
||||
public:
|
||||
/// Convert binary data to text
|
||||
size_t DataToText(IO::GenericStream& in, IO::GenericStream& out, bool) override
|
||||
{
|
||||
PathType outPath;
|
||||
outPath.Native().resize_no_construct(in.GetLength());
|
||||
in.Read(outPath.Native().size(), outPath.Native().data());
|
||||
|
||||
return static_cast<size_t>(out.Write(outPath.Native().size(), outPath.Native().c_str()));
|
||||
}
|
||||
|
||||
size_t TextToData(const char* text, unsigned int, IO::GenericStream& stream, bool) override
|
||||
{
|
||||
return static_cast<size_t>(stream.Write(strlen(text), reinterpret_cast<const void*>(text)));
|
||||
}
|
||||
|
||||
size_t Save(const void* classPtr, IO::GenericStream& stream, bool) override
|
||||
{
|
||||
/// Save paths out using the PosixPathSeparator
|
||||
PathType path(reinterpret_cast<const PathType*>(classPtr)->Native(), AZ::IO::PosixPathSeparator);
|
||||
path.MakePreferred();
|
||||
|
||||
return static_cast<size_t>(stream.Write(path.Native().size(), path.c_str()));
|
||||
}
|
||||
|
||||
bool Load(void* classPtr, IO::GenericStream& stream, unsigned int, bool) override
|
||||
{
|
||||
// Normalize the path load
|
||||
auto path = reinterpret_cast<PathType*>(classPtr);
|
||||
|
||||
path->Native().resize_no_construct(stream.GetLength());
|
||||
stream.Read(path->Native().size(), path->Native().data());
|
||||
*path = path->LexicallyNormal();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CompareValueData(const void* lhs, const void* rhs) override
|
||||
{
|
||||
return SerializeContext::EqualityCompareHelper<Path>::CompareValues(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
void PathReflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<SerializeContext*>(context); serializeContext != nullptr)
|
||||
{
|
||||
serializeContext->Class<Path>()
|
||||
->Serializer(AZ::SerializeContext::IDataSerializerPtr{ new PathSerializer<Path>{},
|
||||
AZ::SerializeContext::IDataSerializer::CreateDefaultDeleteDeleter() })
|
||||
;
|
||||
|
||||
serializeContext->Class<FixedMaxPath>()
|
||||
->Serializer(AZ::SerializeContext::IDataSerializerPtr{ new PathSerializer<FixedMaxPath>{},
|
||||
AZ::SerializeContext::IDataSerializer::CreateDefaultDeleteDeleter() })
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class ReflectContext;
|
||||
}
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
void PathReflect(AZ::ReflectContext* context);
|
||||
}
|
||||
@@ -57,11 +57,6 @@ namespace AZ::IO
|
||||
// It depends on the path type
|
||||
template <typename PathType>
|
||||
class PathIterator;
|
||||
|
||||
struct PathReflection
|
||||
{
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
};
|
||||
}
|
||||
|
||||
namespace AZStd
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
AZ_CVAR(float, cl_jobThreadsConcurrencyRatio, 0.6f, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system multiplier on the number of hw threads the machine creates at initialization");
|
||||
AZ_CVAR(uint32_t, cl_jobThreadsNumReserved, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system number of hardware threads that are reserved for O3DE system threads");
|
||||
AZ_CVAR(uint32_t, cl_jobThreadsMinNumber, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system minimum number of worker threads to create after scaling the number of hw threads");
|
||||
AZ_CVAR(uint32_t, cl_jobThreadsMinNumber, 3, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system minimum number of worker threads to create after scaling the number of hw threads");
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
//
|
||||
// When AZ_CRC("My string") is used by default it will map to AZ::Crc32("My string").
|
||||
// We do have a pro-processor program which will precompute the crc for you and
|
||||
// transform that macro to AZ_CRC("My string",0xabcdef00) this will expand to just 0xabcdef00.
|
||||
// transform that macro to AZ_CRC("My string", 0x18fbd270) this will expand to just 0x18fbd270.
|
||||
// This will remove completely the "My string" from your executable, it will add it to a database and so on.
|
||||
// WHen you want to update the string, just change the string.
|
||||
// If you don't run the precompile step the code should still run fine, except it will be slower,
|
||||
@@ -24,7 +24,7 @@
|
||||
// a constant expression.
|
||||
// For example
|
||||
// switch(id) {
|
||||
// case AZ_CRC("My string",0xabcdef00): {} break; // this will compile fine
|
||||
// case AZ_CRC("My string",0x18fbd270): {} break; // this will compile fine
|
||||
// case AZ_CRC("My string"): {} break; // this will cause "error C2051: case expression not constant"
|
||||
// }
|
||||
// So it's you choice what you do, depending on your needs.
|
||||
|
||||
@@ -351,7 +351,8 @@ namespace AZ
|
||||
->Method("CreateFromMatrix3x3AndTranslation", &Matrix3x4::CreateFromMatrix3x3AndTranslation)
|
||||
->Method("CreateScale", &Matrix3x4::CreateScale)
|
||||
->Method("CreateDiagonal", &Matrix3x4::CreateDiagonal)
|
||||
->Method("CreateTranslation", &Matrix3x4::CreateTranslation);
|
||||
->Method("CreateTranslation", &Matrix3x4::CreateTranslation)
|
||||
->Method("UnsafeCreateFromMatrix4x4", &Matrix3x4::UnsafeCreateFromMatrix4x4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,9 @@ namespace AZ
|
||||
//! Constructs from a Matrix3x3 and a translation.
|
||||
static Matrix3x4 CreateFromMatrix3x3AndTranslation(const Matrix3x3& matrix3x3, const Vector3& translation);
|
||||
|
||||
//! Constructs from a Matrix4x4.
|
||||
static Matrix3x4 UnsafeCreateFromMatrix4x4(const Matrix4x4& matrix4x4);
|
||||
|
||||
//! Constructs from a Transform.
|
||||
static Matrix3x4 CreateFromTransform(const Transform& transform);
|
||||
|
||||
@@ -227,7 +230,7 @@ namespace AZ
|
||||
Matrix3x4& operator+=(const Matrix3x4& rhs);
|
||||
//! @}
|
||||
|
||||
//! Operator for matrix-matrix substraction.
|
||||
//! Operator for matrix-matrix subtraction.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x4 operator-(const Matrix3x4& rhs) const;
|
||||
Matrix3x4& operator-=(const Matrix3x4& rhs);
|
||||
@@ -266,6 +269,9 @@ namespace AZ
|
||||
//! Post-multiplies the matrix by a vector, using only the 3x3 part of the matrix.
|
||||
[[nodiscard]] Vector3 TransformVector(const Vector3& rhs) const;
|
||||
|
||||
//! Post-multiplies the matrix by a point, using the rotation and translation part of the matrix.
|
||||
[[nodiscard]] Vector3 TransformPoint(const Vector3& rhs) const;
|
||||
|
||||
//! Gets the result of transposing the 3x3 part of the matrix, setting the translation part to zero.
|
||||
[[nodiscard]] Matrix3x4 GetTranspose() const;
|
||||
|
||||
|
||||
@@ -203,6 +203,16 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::UnsafeCreateFromMatrix4x4(const Matrix4x4& matrix4x4)
|
||||
{
|
||||
Matrix3x4 result;
|
||||
result.SetRow(0, matrix4x4.GetRow(0));
|
||||
result.SetRow(1, matrix4x4.GetRow(1));
|
||||
result.SetRow(2, matrix4x4.GetRow(2));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::CreateScale(const Vector3& scale)
|
||||
{
|
||||
return CreateDiagonal(scale);
|
||||
@@ -609,6 +619,12 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix3x4::TransformPoint(const Vector3& rhs) const
|
||||
{
|
||||
return Multiply3x3(rhs) + GetTranslation();
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::GetTranspose() const
|
||||
{
|
||||
Matrix3x4 result;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Console/ConsoleFunctor.h>
|
||||
#include <AzCore/IO/ByteContainerStream.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Settings/SettingsRegistryConsoleUtils.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
@@ -36,7 +37,7 @@ namespace AZ::SettingsRegistryConsoleUtils
|
||||
combinedKeyValueCommand.c_str());
|
||||
AZ::Debug::Trace::Output("SettingsRegistry", setOutput.c_str());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void ConsoleRemoveSettingsRegistryValue(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs)
|
||||
{
|
||||
@@ -57,7 +58,7 @@ namespace AZ::SettingsRegistryConsoleUtils
|
||||
AZ::Debug::Trace::Output("SettingsRegistry", removeOutput.c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void ConsoleDumpSettingsRegistryValue(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs)
|
||||
{
|
||||
@@ -88,13 +89,39 @@ namespace AZ::SettingsRegistryConsoleUtils
|
||||
}
|
||||
|
||||
AZ::Debug::Trace::Output("SettingsRegistry", outputString.c_str());
|
||||
};
|
||||
}
|
||||
|
||||
static void ConsoleDumpAllSettingsRegistryValues(SettingsRegistryInterface& settingsRegistry,
|
||||
[[maybe_unused]] const ConsoleCommandContainer& commandArgs)
|
||||
{
|
||||
ConsoleDumpSettingsRegistryValue(settingsRegistry, { "" });
|
||||
};
|
||||
}
|
||||
|
||||
static void ConsoleMergeFileToSettingsRegistry(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs)
|
||||
{
|
||||
if (commandArgs.empty())
|
||||
{
|
||||
AZ_Error("SettingsRegistryConsoleUtils", false, "Command %s requires a <file path> argument to locate json file to merge",
|
||||
SettingsRegistryMergeFile);
|
||||
return;
|
||||
}
|
||||
|
||||
auto commandArgumentsIter = commandArgs.begin();
|
||||
// Extract the JSON pointer path from the argument list
|
||||
AZStd::string_view filePath{ *commandArgumentsIter++ };
|
||||
AZ::SettingsRegistryInterface::FixedValueString jsonAnchorPath;
|
||||
AZ::StringFunc::Join(jsonAnchorPath, commandArgumentsIter, commandArgs.end(), ' ');
|
||||
|
||||
const auto mergeFormat = AZ::IO::PathView(filePath).Extension() != ".setregpatch" ? AZ::SettingsRegistryInterface::Format::JsonMergePatch : AZ::SettingsRegistryInterface::Format::JsonPatch;
|
||||
if (settingsRegistry.MergeSettingsFile(filePath, mergeFormat, jsonAnchorPath))
|
||||
{
|
||||
const auto mergeFileOutput = AZ::SettingsRegistryInterface::FixedValueString::format(
|
||||
R"(Merged json file "%*.s" anchored to json path "%s" into the global settings registry)" "\n",
|
||||
AZ_STRING_ARG(filePath), jsonAnchorPath.c_str());
|
||||
AZ::Debug::Trace::Output("SettingsRegistry", mergeFileOutput.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole)
|
||||
{
|
||||
@@ -115,6 +142,11 @@ namespace AZ::SettingsRegistryConsoleUtils
|
||||
resultHandle.m_consoleFunctors.emplace_back(azConsole, SettingsRegistryDumpAll,
|
||||
R"(Dumps all values from the global settings registry)" "\n",
|
||||
ConsoleFunctorFlags::Null, AZ::TypeId::CreateNull(), registry, &ConsoleDumpAllSettingsRegistryValues);
|
||||
resultHandle.m_consoleFunctors.emplace_back(azConsole, SettingsRegistryMergeFile,
|
||||
R"(Merges File into the global settings registry)" "\n"
|
||||
R"(@param file-path - path to JSON formatted file to merge)" "\n"
|
||||
R"(@param anchor-path - JSON path to anchor merge operation. Defaults to "")" "\n",
|
||||
ConsoleFunctorFlags::Null, AZ::TypeId::CreateNull(), registry, &ConsoleMergeFileToSettingsRegistry);
|
||||
|
||||
return resultHandle;
|
||||
}
|
||||
|
||||
@@ -14,15 +14,16 @@
|
||||
|
||||
namespace AZ::SettingsRegistryConsoleUtils
|
||||
{
|
||||
//! Only 4 console command are registered for the settings registry
|
||||
//! "regset", "regremove", "regdump", "regdumpall"
|
||||
//! The following console command are registered for the settings registry
|
||||
//! "regset", "regremove", "regdump", "regdumpall", "regset-file"
|
||||
//! The value should be increased if more commands are needed
|
||||
inline constexpr size_t MaxSettingsRegistryConsoleFunctors = 4;
|
||||
inline constexpr size_t MaxSettingsRegistryConsoleFunctors = 5;
|
||||
|
||||
inline constexpr const char* SettingsRegistrySet = "sr_regset";
|
||||
inline constexpr const char* SettingsRegistryRemove = "sr_regremove";
|
||||
inline constexpr const char* SettingsRegistryDump = "sr_regdump";
|
||||
inline constexpr const char* SettingsRegistryDumpAll = "sr_regdumpall";
|
||||
inline constexpr const char* SettingsRegistryMergeFile = "sr_regset-file";
|
||||
|
||||
// RAII structure which owns the instances of the Settings Registry Console commands
|
||||
// registered with an AZ Console
|
||||
@@ -51,6 +52,10 @@ namespace AZ::SettingsRegistryConsoleUtils
|
||||
//!
|
||||
//! "sr_regdumpall" accepts 0 arguments and dumps the entire settings registry
|
||||
//! NOTE: this might result in a large amount of output to the console
|
||||
//!
|
||||
//! "sr_regset-file" accepts 1 or 2 arguments - <file-path> [<anchor json path>]
|
||||
//! Merges the json formatted file <file path> into the settings registry underneath the root anchor ""
|
||||
//! or <anchor json path> if supplied
|
||||
[[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Settings/CommandLine.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/std/string/wildcard.h>
|
||||
#include <AzCore/std/tuple.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <cinttypes>
|
||||
@@ -983,7 +980,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
// code in the loop makes calls that mutates the `commandLine` instance, invalidating the iterators. Making a copy
|
||||
// ensures that the iterators remain valid.
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeCommands)
|
||||
void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeRegdumpCommands)
|
||||
{
|
||||
// Iterate over all the command line options in order to parse the --regset and --regremove
|
||||
// arguments in the order they were supplied
|
||||
@@ -998,18 +995,44 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (commandArgument.m_option == "regset-file")
|
||||
{
|
||||
AZStd::string_view fileArg(commandArgument.m_value);
|
||||
AZStd::string_view jsonAnchorPath;
|
||||
// double colons is treated as the separator for an anchor path
|
||||
// single colon cannot be used as it is used in Windows paths
|
||||
if (auto anchorPathIndex = AZ::StringFunc::Find(fileArg, "::");
|
||||
anchorPathIndex != AZStd::string_view::npos)
|
||||
{
|
||||
jsonAnchorPath = fileArg.substr(anchorPathIndex + 2);
|
||||
fileArg = fileArg.substr(0, anchorPathIndex);
|
||||
}
|
||||
if (!fileArg.empty())
|
||||
{
|
||||
AZ::IO::PathView filePath(fileArg);
|
||||
const auto mergeFormat = filePath.Extension() != ".setregpatch"
|
||||
? AZ::SettingsRegistryInterface::Format::JsonMergePatch
|
||||
: AZ::SettingsRegistryInterface::Format::JsonPatch;
|
||||
if (!registry.MergeSettingsFile(filePath.Native(), mergeFormat, jsonAnchorPath))
|
||||
{
|
||||
AZ_Warning("SettingsRegistryMergeUtils", false, R"(Merging of file "%.*s" to the Settings Registry has failed at anchor "%.*s".)",
|
||||
AZ_STRING_ARG(filePath.Native()), AZ_STRING_ARG(jsonAnchorPath));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (commandArgument.m_option == "regremove")
|
||||
{
|
||||
if (!registry.Remove(commandArgument.m_value))
|
||||
{
|
||||
AZ_Warning("SettingsRegistryMergeUtils", false, "Unable to remove value at JSON Pointer %s for --regremove.",
|
||||
commandArgument.m_value.data());
|
||||
commandArgument.m_value.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (executeCommands)
|
||||
if (executeRegdumpCommands)
|
||||
{
|
||||
constexpr bool prettifyOutput = true;
|
||||
const size_t regdumpSwitchValues = commandLine.GetNumSwitchValues("regdump");
|
||||
|
||||
@@ -157,6 +157,22 @@ namespace AZ::Statistics
|
||||
}
|
||||
}
|
||||
|
||||
void GetAllStatistics(AZStd::vector<NamedRunningStatistic*>& stats)
|
||||
{
|
||||
for (auto& iter : m_profilers)
|
||||
{
|
||||
iter.second.m_profiler.GetStatsManager().GetAllStatistics(stats);
|
||||
}
|
||||
}
|
||||
|
||||
void GetAllStatisticsOfUnits(AZStd::vector<NamedRunningStatistic*>& stats, const char* units)
|
||||
{
|
||||
for (auto& iter : m_profilers)
|
||||
{
|
||||
iter.second.m_profiler.GetStatsManager().GetAllStatisticsOfUnits(stats, units);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct ProfilerInfo
|
||||
{
|
||||
|
||||
@@ -56,13 +56,25 @@ namespace AZ
|
||||
|
||||
void GetAllStatistics(AZStd::vector<NamedRunningStatistic*>& vector)
|
||||
{
|
||||
for (auto const& it : m_statistics)
|
||||
for (const auto& it : m_statistics)
|
||||
{
|
||||
NamedRunningStatistic* stat = it.second;
|
||||
vector.push_back(stat);
|
||||
}
|
||||
}
|
||||
|
||||
void GetAllStatisticsOfUnits(AZStd::vector<NamedRunningStatistic*>& vector, const char* units)
|
||||
{
|
||||
for (const auto& it : m_statistics)
|
||||
{
|
||||
NamedRunningStatistic* stat = it.second;
|
||||
if (stat->GetUnits() == units)
|
||||
{
|
||||
vector.push_back(stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Helper method to apply units to statistics with empty units string.
|
||||
AZ::u32 ApplyUnits(const AZStd::string& units)
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ set(FILES
|
||||
IO/Path/Path.inl
|
||||
IO/Path/PathIterable.inl
|
||||
IO/Path/PathParser.inl
|
||||
IO/Path/PathReflect.cpp
|
||||
IO/Path/PathReflect.h
|
||||
IO/Path/Path_fwd.h
|
||||
IO/SystemFile.cpp
|
||||
IO/SystemFile.h
|
||||
|
||||
@@ -1233,6 +1233,14 @@ namespace AZStd
|
||||
right.swap(AZStd::forward<this_type>(left));
|
||||
}
|
||||
|
||||
template<class T, class Allocator, AZStd::size_t NumElementsPerBlock, AZStd::size_t MinMapSize, class U>
|
||||
decltype(auto) erase(deque<T, Allocator, NumElementsPerBlock, MinMapSize>& container, const U& value)
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), value);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
template<class T, class Allocator, AZStd::size_t NumElementsPerBlock, AZStd::size_t MinMapSize, class Predicate>
|
||||
decltype(auto) erase_if(deque<T, Allocator, NumElementsPerBlock, MinMapSize>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -130,10 +130,11 @@ namespace AZStd::Internal
|
||||
|
||||
|
||||
//! Constructors
|
||||
constexpr fixed_trivial_storage() = default;
|
||||
fixed_trivial_storage() = default;
|
||||
|
||||
template <typename U, typename = enable_if_t<is_convertible_v<U, T>>>
|
||||
constexpr fixed_trivial_storage(AZStd::initializer_list<U> ilist) noexcept
|
||||
fixed_trivial_storage(AZStd::initializer_list<U> ilist) noexcept
|
||||
: m_size(aznumeric_caster(ilist.size()))
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(ilist.size() <= capacity(), "Initializer list cannot be larger than storage capacity");
|
||||
size_t index{};
|
||||
@@ -141,20 +142,19 @@ namespace AZStd::Internal
|
||||
{
|
||||
m_data[index++] = element;
|
||||
}
|
||||
resize_no_construct(ilist.size());
|
||||
}
|
||||
|
||||
constexpr pointer data() noexcept
|
||||
pointer data() noexcept
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
constexpr const_pointer data() const noexcept
|
||||
const_pointer data() const noexcept
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
//! Number of elements currently stored.
|
||||
constexpr size_type size() const noexcept
|
||||
size_type size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
@@ -164,12 +164,12 @@ namespace AZStd::Internal
|
||||
return Capacity;
|
||||
}
|
||||
//! Is the storage empty?
|
||||
constexpr bool empty() const noexcept
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return size() == 0;
|
||||
}
|
||||
//! Is the storage full?
|
||||
constexpr bool full() const noexcept
|
||||
bool full() const noexcept
|
||||
{
|
||||
return size() == capacity();
|
||||
}
|
||||
@@ -186,7 +186,7 @@ namespace AZStd::Internal
|
||||
//! Increases size of the storage by one.
|
||||
//! Always fails for empty storage.
|
||||
template <typename... Args, typename = enable_if_t<is_constructible_v<T, Args...>>>
|
||||
constexpr reference emplace_back(Args&&... args) noexcept
|
||||
reference emplace_back(Args&&... args) noexcept
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(!full(), "emplace_back cannot be invoked on full storage");
|
||||
reference new_element = *(data() + size());
|
||||
@@ -196,7 +196,7 @@ namespace AZStd::Internal
|
||||
}
|
||||
//! Removes the last element of the storage.
|
||||
//! Precondition: size is not empty
|
||||
constexpr void pop_back() noexcept
|
||||
void pop_back() noexcept
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(!empty(), "pop_back cannot be invoked on empty storage");
|
||||
resize_no_construct(size() - 1);
|
||||
@@ -205,7 +205,7 @@ namespace AZStd::Internal
|
||||
//! removing elements (unsafe).
|
||||
//!
|
||||
//! Updates the size of the container while checking that the new size is less than capacity
|
||||
constexpr void resize_no_construct(size_t new_size) noexcept
|
||||
void resize_no_construct(size_t new_size) noexcept
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(new_size <= capacity(), "New size cannot be larger than capacity");
|
||||
m_size = aznumeric_cast<size_type>(new_size);
|
||||
@@ -215,19 +215,19 @@ namespace AZStd::Internal
|
||||
//! This does not modify the size of the storage
|
||||
//! This is a no-op for trivial types
|
||||
template <typename InputIt, typename = enable_if_t<Internal::is_input_iterator_v<InputIt>>>
|
||||
constexpr void unsafe_destroy(InputIt, InputIt) noexcept
|
||||
void unsafe_destroy(InputIt, InputIt) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
//! Destructs all elements of the storage.
|
||||
//! This does not modify the size of the storage
|
||||
//! This is a no-op for trivial types
|
||||
constexpr void unsafe_destroy_all() noexcept
|
||||
void unsafe_destroy_all() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
T m_data[Capacity]{};
|
||||
T m_data[Capacity];
|
||||
size_type m_size{};
|
||||
};
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace AZStd::Internal
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
|
||||
constexpr fixed_non_trivial_storage() = default;
|
||||
fixed_non_trivial_storage() = default;
|
||||
|
||||
~fixed_non_trivial_storage() noexcept
|
||||
{
|
||||
@@ -253,7 +253,7 @@ namespace AZStd::Internal
|
||||
}
|
||||
|
||||
template <typename U, typename = enable_if_t<is_convertible_v<U, T>>>
|
||||
constexpr fixed_non_trivial_storage(AZStd::initializer_list<U> ilist) noexcept(noexcept(emplace_back(AZStd::declval<U>())))
|
||||
fixed_non_trivial_storage(AZStd::initializer_list<U> ilist) noexcept(noexcept(emplace_back(AZStd::declval<U>())))
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(ilist.size() <= capacity(), "Initializer list cannot be larger than storage capacity");
|
||||
for (const U& element : ilist)
|
||||
@@ -272,7 +272,7 @@ namespace AZStd::Internal
|
||||
}
|
||||
|
||||
//! Number of elements currently stored.
|
||||
constexpr size_type size() const noexcept
|
||||
size_type size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
@@ -282,12 +282,12 @@ namespace AZStd::Internal
|
||||
return Capacity;
|
||||
}
|
||||
//! Is the storage empty?
|
||||
constexpr bool empty() const noexcept
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return size() == 0;
|
||||
}
|
||||
//! Is the storage full?
|
||||
constexpr bool full() const noexcept
|
||||
bool full() const noexcept
|
||||
{
|
||||
return size() == capacity();
|
||||
}
|
||||
@@ -325,7 +325,7 @@ namespace AZStd::Internal
|
||||
//! removing elements (unsafe).
|
||||
//!
|
||||
//! Updates the size of the container while checking that the new size is less than capacity
|
||||
constexpr void resize_no_construct(size_t new_size) noexcept
|
||||
void resize_no_construct(size_t new_size) noexcept
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(new_size <= capacity(), "New size cannot be larger than capacity");
|
||||
m_size = aznumeric_cast<size_type>(new_size);
|
||||
@@ -402,23 +402,23 @@ namespace AZStd
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 23.2.4.1 construct/copy/destroy
|
||||
constexpr fixed_vector() = default;
|
||||
fixed_vector() = default;
|
||||
|
||||
constexpr explicit fixed_vector(size_type numElements, const_reference value = value_type())
|
||||
explicit fixed_vector(size_type numElements, const_reference value = value_type())
|
||||
{
|
||||
resize_no_construct(numElements);
|
||||
AZStd::uninitialized_fill_n(data(), numElements, value);
|
||||
}
|
||||
|
||||
template <class InputIt, typename = AZStd::enable_if_t<Internal::is_input_iterator_v<InputIt>>>
|
||||
constexpr fixed_vector(InputIt first, InputIt last)
|
||||
fixed_vector(InputIt first, InputIt last)
|
||||
{
|
||||
resize_no_construct(AZStd::distance(first, last));
|
||||
AZStd::uninitialized_copy(first, last, data());
|
||||
}
|
||||
|
||||
|
||||
constexpr fixed_vector(const fixed_vector& rhs)
|
||||
fixed_vector(const fixed_vector& rhs)
|
||||
{
|
||||
resize_no_construct(rhs.size());
|
||||
AZStd::uninitialized_copy(rhs.data(), rhs.data() + rhs.size(), data());
|
||||
@@ -428,7 +428,7 @@ namespace AZStd
|
||||
// It performs an AZStd::move on each of the fixed_vector elements instead
|
||||
// of swapping pointers to the allocted memory address
|
||||
// as it is unable to perform that operations due to the storage being baked into the container
|
||||
constexpr fixed_vector(fixed_vector&& rhs)
|
||||
fixed_vector(fixed_vector&& rhs)
|
||||
{
|
||||
resize_no_construct(rhs.size());
|
||||
AZStd::uninitialized_move(rhs.data(), rhs.data() + rhs.size(), data());
|
||||
@@ -440,7 +440,7 @@ namespace AZStd
|
||||
// into a fixed_vector given that the type in question isn't the same type as this fixed_vector type
|
||||
template <typename VectorContainer, typename = AZStd::enable_if_t<!AZStd::is_same_v<VectorContainer, fixed_vector>
|
||||
&& !AZStd::is_convertible_v<VectorContainer, size_type>>>
|
||||
constexpr fixed_vector(VectorContainer&& rhs)
|
||||
fixed_vector(VectorContainer&& rhs)
|
||||
{
|
||||
constexpr bool is_const_or_lvalue_reference = AZStd::is_lvalue_reference_v<VectorContainer>
|
||||
|| AZStd::is_const_v<VectorContainer>;
|
||||
@@ -459,12 +459,12 @@ namespace AZStd
|
||||
}
|
||||
}
|
||||
|
||||
constexpr fixed_vector(AZStd::initializer_list<value_type> ilist)
|
||||
fixed_vector(AZStd::initializer_list<value_type> ilist)
|
||||
: base_type(ilist)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr fixed_vector& operator=(const fixed_vector& rhs)
|
||||
fixed_vector& operator=(const fixed_vector& rhs)
|
||||
{
|
||||
if (this == &rhs)
|
||||
{
|
||||
@@ -475,7 +475,7 @@ namespace AZStd
|
||||
return assign_helper(rhs);
|
||||
}
|
||||
|
||||
constexpr fixed_vector& operator=(fixed_vector&& rhs)
|
||||
fixed_vector& operator=(fixed_vector&& rhs)
|
||||
{
|
||||
if (this == &rhs)
|
||||
{
|
||||
@@ -487,23 +487,23 @@ namespace AZStd
|
||||
}
|
||||
|
||||
template <typename VectorContainer>
|
||||
constexpr AZStd::enable_if_t<!AZStd::is_same_v<AZStd::remove_cvref_t<VectorContainer>, fixed_vector>, fixed_vector>& operator=(VectorContainer&& rhs)
|
||||
AZStd::enable_if_t<!AZStd::is_same_v<AZStd::remove_cvref_t<VectorContainer>, fixed_vector>, fixed_vector>& operator=(VectorContainer&& rhs)
|
||||
{
|
||||
return assign_helper(AZStd::forward<VectorContainer>(rhs));
|
||||
}
|
||||
|
||||
constexpr iterator begin() { return iterator(data()); }
|
||||
constexpr const_iterator begin() const { return const_iterator(data()); }
|
||||
constexpr const_iterator cbegin() const { return const_iterator(data()); }
|
||||
constexpr iterator end() { return iterator(data() + size()); }
|
||||
constexpr const_iterator end() const { return const_iterator(data() + size()); }
|
||||
constexpr const_iterator cend() const { return const_iterator(data() + size()); }
|
||||
constexpr reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
constexpr const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
constexpr const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
|
||||
constexpr reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
constexpr const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
constexpr const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
|
||||
iterator begin() { return iterator(data()); }
|
||||
const_iterator begin() const { return const_iterator(data()); }
|
||||
const_iterator cbegin() const { return const_iterator(data()); }
|
||||
iterator end() { return iterator(data() + size()); }
|
||||
const_iterator end() const { return const_iterator(data() + size()); }
|
||||
const_iterator cend() const { return const_iterator(data() + size()); }
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
// bring in fixed_vector_storage functions into scope
|
||||
using base_type::data;
|
||||
@@ -514,7 +514,7 @@ namespace AZStd
|
||||
// extension method
|
||||
using base_type::resize_no_construct;
|
||||
|
||||
constexpr size_type size() const noexcept
|
||||
size_type size() const noexcept
|
||||
{
|
||||
return base_type::size();
|
||||
}
|
||||
@@ -527,12 +527,12 @@ namespace AZStd
|
||||
return base_type::max_size();
|
||||
}
|
||||
|
||||
constexpr void resize(size_type newSize)
|
||||
void resize(size_type newSize)
|
||||
{
|
||||
return resize(newSize, value_type{});
|
||||
}
|
||||
|
||||
constexpr void resize(size_type newSize, const_reference value)
|
||||
void resize(size_type newSize, const_reference value)
|
||||
{
|
||||
size_type dataSize = size();
|
||||
if (dataSize < newSize)
|
||||
@@ -547,7 +547,7 @@ namespace AZStd
|
||||
|
||||
// Removes unused capacity - For fixed_vector this only asserts
|
||||
// that the supplied capacity is not longer than the fixed_vector capacity
|
||||
constexpr void reserve(size_type newCapacity)
|
||||
void reserve(size_type newCapacity)
|
||||
{
|
||||
// No-op - Implemented to provide consistent std::vector
|
||||
AZSTD_CONTAINER_ASSERT(newCapacity <= capacity(),
|
||||
@@ -556,79 +556,79 @@ namespace AZStd
|
||||
}
|
||||
|
||||
// Removes unused capacity - For fixed_vector this does nothing
|
||||
constexpr void shrink_to_fit()
|
||||
void shrink_to_fit()
|
||||
{
|
||||
// No-op - Implemented to provide consistent std::vector
|
||||
}
|
||||
|
||||
constexpr reference at(size_type position)
|
||||
reference at(size_type position)
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(position < size(), "AZStd::fixed_vector<>::at - position is out of range");
|
||||
return *(data() + position);
|
||||
}
|
||||
constexpr const_reference at(size_type position) const
|
||||
const_reference at(size_type position) const
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(position < size(), "AZStd::fixed_vector<>::at - position is out of range");
|
||||
return *(data() + position);
|
||||
}
|
||||
|
||||
constexpr reference operator[](size_type position)
|
||||
reference operator[](size_type position)
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(position < size(), "AZStd::fixed_vector<>::at - position is out of range");
|
||||
return *(data() + position);
|
||||
}
|
||||
constexpr const_reference operator[](size_type position) const
|
||||
const_reference operator[](size_type position) const
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(position < size(), "AZStd::fixed_vector<>::at - position is out of range");
|
||||
return *(data() + position);
|
||||
}
|
||||
|
||||
constexpr reference front()
|
||||
reference front()
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(!empty(), "AZStd::fixed_vector<>::front - container is empty!");
|
||||
return *data();
|
||||
}
|
||||
constexpr const_reference front() const
|
||||
const_reference front() const
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(!empty(), "AZStd::fixed_vector<>::front - container is empty!");
|
||||
return *data();
|
||||
}
|
||||
constexpr reference back()
|
||||
reference back()
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(!empty(), "AZStd::fixed_vector<>::back - container is empty!");
|
||||
return *(data() + size() - 1);
|
||||
}
|
||||
constexpr const_reference back() const
|
||||
const_reference back() const
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(!empty(), "AZStd::fixed_vector<>::back - container is empty!");
|
||||
return *(data() + size() - 1);
|
||||
}
|
||||
|
||||
constexpr void push_back(const_reference value)
|
||||
void push_back(const_reference value)
|
||||
{
|
||||
emplace_back(value);
|
||||
}
|
||||
|
||||
constexpr void assign(size_type numElements, const_reference value)
|
||||
void assign(size_type numElements, const_reference value)
|
||||
{
|
||||
clear();
|
||||
insert(end(), numElements, value);
|
||||
}
|
||||
|
||||
template <class InputIt, typename = AZStd::enable_if_t<Internal::is_input_iterator_v<InputIt>>>
|
||||
constexpr void assign(InputIt first, InputIt last)
|
||||
void assign(InputIt first, InputIt last)
|
||||
{
|
||||
clear();
|
||||
insert(end(), first, last);
|
||||
}
|
||||
|
||||
constexpr void assign(AZStd::initializer_list<value_type> ilist)
|
||||
void assign(AZStd::initializer_list<value_type> ilist)
|
||||
{
|
||||
assign(ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template <typename... Args, typename = AZStd::enable_if_t<is_constructible_v<T, Args...>>>
|
||||
constexpr iterator emplace(const_iterator insertPos, Args&&... args)
|
||||
iterator emplace(const_iterator insertPos, Args&&... args)
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(!full(), "Cannot emplace on a full fixed_vector");
|
||||
AZSTD_CONTAINER_ASSERT(insertPos >= cbegin() && insertPos <= cend(), "insert position must be in range of container");
|
||||
@@ -645,18 +645,18 @@ namespace AZStd
|
||||
AZStd::construct_at(insertPosPtr, AZStd::forward<Args>(args)...);
|
||||
return iterator(insertPosPtr);
|
||||
}
|
||||
constexpr iterator insert(const_iterator insertPos, const_reference value)
|
||||
iterator insert(const_iterator insertPos, const_reference value)
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(insertPos >= cbegin() && insertPos <= cend(), "insert position must be in range of container");
|
||||
return emplace(insertPos, value);
|
||||
}
|
||||
constexpr iterator insert(const_iterator insertPos, value_type&& value)
|
||||
iterator insert(const_iterator insertPos, value_type&& value)
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(insertPos >= cbegin() && insertPos <= cend(), "insert position must be in range of container");
|
||||
return emplace(insertPos, AZStd::move(value));
|
||||
}
|
||||
|
||||
constexpr void insert(const_iterator insertPos, size_type numElements, const_reference value)
|
||||
void insert(const_iterator insertPos, size_type numElements, const_reference value)
|
||||
{
|
||||
if (numElements == 0)
|
||||
{
|
||||
@@ -708,24 +708,24 @@ namespace AZStd
|
||||
}
|
||||
|
||||
template<class InputIt, typename = AZStd::enable_if_t<Internal::is_input_iterator_v<InputIt>>>
|
||||
constexpr void insert(const_iterator insertPos, InputIt first, InputIt last)
|
||||
void insert(const_iterator insertPos, InputIt first, InputIt last)
|
||||
{
|
||||
// specialize for iterator categories.
|
||||
AZSTD_CONTAINER_ASSERT(insertPos >= cbegin() && insertPos <= cend(), "insert position must be in range of container");
|
||||
insert_iter(insertPos, first, last, typename iterator_traits<InputIt>::iterator_category());
|
||||
};
|
||||
|
||||
constexpr void insert(const_iterator insertPos, AZStd::initializer_list<value_type> ilist)
|
||||
void insert(const_iterator insertPos, AZStd::initializer_list<value_type> ilist)
|
||||
{
|
||||
insert(insertPos, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
constexpr iterator erase(const_iterator elementIter)
|
||||
iterator erase(const_iterator elementIter)
|
||||
{
|
||||
return erase(elementIter, elementIter + 1);
|
||||
}
|
||||
|
||||
constexpr iterator erase(const_iterator first, const_iterator last)
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(first >= cbegin() && last <= cend(), "erase iterator must be inside the range of fixed_vector container");
|
||||
iterator dataStart = begin();
|
||||
@@ -741,12 +741,12 @@ namespace AZStd
|
||||
return dataStart + offset;
|
||||
}
|
||||
|
||||
constexpr void clear()
|
||||
void clear()
|
||||
{
|
||||
base_type::unsafe_destroy_all();
|
||||
resize_no_construct(0);
|
||||
}
|
||||
constexpr void swap(fixed_vector& rhs)
|
||||
void swap(fixed_vector& rhs)
|
||||
{
|
||||
// Fixed containers cannot swap pointers, they need to do full copies.
|
||||
// The strategy is to extend the smaller fixed_vector to be the size
|
||||
@@ -776,12 +776,12 @@ namespace AZStd
|
||||
}
|
||||
|
||||
// Validate container status.
|
||||
constexpr bool validate() const
|
||||
bool validate() const
|
||||
{
|
||||
return size() <= max_size();
|
||||
}
|
||||
// Validate iterator.
|
||||
constexpr int validate_iterator(const_iterator iter) const
|
||||
int validate_iterator(const_iterator iter) const
|
||||
{
|
||||
const_pointer start = data();
|
||||
const_pointer end = data() + size();
|
||||
@@ -799,19 +799,19 @@ namespace AZStd
|
||||
}
|
||||
|
||||
// pushes back an empty without a provided instance.
|
||||
constexpr void push_back()
|
||||
void push_back()
|
||||
{
|
||||
emplace_back();
|
||||
}
|
||||
|
||||
constexpr void leak_and_reset()
|
||||
void leak_and_reset()
|
||||
{
|
||||
resize_no_construct(0);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename VectorContainer>
|
||||
constexpr fixed_vector& assign_helper(VectorContainer&& rhs)
|
||||
fixed_vector& assign_helper(VectorContainer&& rhs)
|
||||
{
|
||||
constexpr bool is_const_or_lvalue_reference = AZStd::is_lvalue_reference_v<VectorContainer>
|
||||
|| AZStd::is_const_v<VectorContainer>;
|
||||
@@ -872,7 +872,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
template<class Iterator>
|
||||
constexpr void insert_iter(const_iterator insertPos, Iterator first, Iterator last, const forward_iterator_tag&)
|
||||
void insert_iter(const_iterator insertPos, Iterator first, Iterator last, const forward_iterator_tag&)
|
||||
{
|
||||
size_type numElements = AZStd::distance(first, last);
|
||||
if (numElements == 0)
|
||||
@@ -923,7 +923,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
template<class Iterator>
|
||||
constexpr void insert_iter(const_iterator insertPos, Iterator first, Iterator last, const input_iterator_tag&)
|
||||
void insert_iter(const_iterator insertPos, Iterator first, Iterator last, const input_iterator_tag&)
|
||||
{
|
||||
iterator dataStart = data();
|
||||
size_type offset = AZStd::distance(dataStart, insertPos);
|
||||
@@ -974,4 +974,22 @@ namespace AZStd
|
||||
{
|
||||
return !operator<(a, b);
|
||||
}
|
||||
|
||||
// C++20 erase free functions
|
||||
template<class T, size_t Capacity, class U>
|
||||
constexpr decltype(auto) erase(fixed_vector<T, Capacity>& container, const U& value)
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), value);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
template<class T, size_t Capacity, class Predicate>
|
||||
constexpr decltype(auto) erase_if(fixed_vector<T, Capacity>& container, Predicate predicate)
|
||||
{
|
||||
auto iter = AZStd::remove_if(container.begin(), container.end(), predicate);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,6 +1275,11 @@ namespace AZStd
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
template<class T, class Allocator, class U>
|
||||
decltype(auto) erase(forward_list<T, Allocator>& container, const U& value)
|
||||
{
|
||||
return container.remove(value);
|
||||
}
|
||||
template<class T, class Allocator, class Predicate>
|
||||
decltype(auto) erase_if(forward_list<T, Allocator>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -1340,6 +1340,11 @@ namespace AZStd
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
template<class T, class Allocator, class U>
|
||||
decltype(auto) erase(list<T, Allocator>& container, const U& value)
|
||||
{
|
||||
return container.remove(value);
|
||||
}
|
||||
template<class T, class Allocator, class Predicate>
|
||||
decltype(auto) erase_if(list<T, Allocator>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -1387,6 +1387,14 @@ namespace AZStd
|
||||
}
|
||||
//#pragma endregion
|
||||
|
||||
template<class T, class Allocator, class U>
|
||||
decltype(auto) erase(vector<T, Allocator>& container, const U& value)
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), value);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
template<class T, class Allocator, class Predicate>
|
||||
decltype(auto) erase_if(vector<T, Allocator>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -465,6 +465,15 @@ namespace AZStd
|
||||
template<class Element, size_t MaxElementCount, class Traits>
|
||||
constexpr bool operator>=(const Element* lhs, const basic_fixed_string<Element, MaxElementCount, Traits>& rhs);
|
||||
|
||||
// C++20 erase helpers
|
||||
template<class Element, size_t MaxElementCount, class Traits, class U>
|
||||
constexpr auto erase(basic_fixed_string<Element, MaxElementCount, Traits>& container, const U& element)
|
||||
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type;
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits, class Predicate>
|
||||
constexpr auto erase_if(basic_fixed_string<Element, MaxElementCount, Traits>& container, Predicate predicate)
|
||||
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type;
|
||||
|
||||
template<class T>
|
||||
struct hash;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <AzCore/std/typetraits/is_integral.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
|
||||
#include <AzCore/std/string/fixed_string_Platform.inl>
|
||||
|
||||
@@ -1680,6 +1680,26 @@ namespace AZStd
|
||||
return !operator<(lhs, rhs);
|
||||
}
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits, class U>
|
||||
inline constexpr auto erase(basic_fixed_string<Element, MaxElementCount, Traits>& container, const U& element)
|
||||
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), element);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits, class Predicate>
|
||||
inline constexpr auto erase_if(basic_fixed_string<Element, MaxElementCount, Traits>& container, Predicate predicate)
|
||||
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type
|
||||
{
|
||||
auto iter = AZStd::remove_if(container.begin(), container.end(), predicate);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits>
|
||||
struct hash<basic_fixed_string<Element, MaxElementCount, Traits>>
|
||||
{
|
||||
|
||||
@@ -1955,6 +1955,16 @@ namespace AZStd
|
||||
{
|
||||
return basic_string<Element, Traits, Allocator>(lhs).compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
template<class Element, class Traits, class Allocator, class U>
|
||||
decltype(auto) erase(basic_string<Element, Traits, Allocator>& container, const U& element)
|
||||
{
|
||||
auto iter = AZStd::remove(container.begin(), container.end(), element);
|
||||
auto removedCount = AZStd::distance(iter, container.end());
|
||||
container.erase(iter, container.end());
|
||||
return removedCount;
|
||||
}
|
||||
|
||||
template<class Element, class Traits, class Allocator, class Predicate>
|
||||
decltype(auto) erase_if(basic_string<Element, Traits, Allocator>& container, Predicate predicate)
|
||||
{
|
||||
|
||||
@@ -53,10 +53,8 @@
|
||||
// Compiler traits ...
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 1
|
||||
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 1
|
||||
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 0
|
||||
|
||||
@@ -53,10 +53,8 @@
|
||||
// Compiler traits ...
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 0
|
||||
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 1
|
||||
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 1
|
||||
|
||||
@@ -53,10 +53,8 @@
|
||||
// Compiler traits ...
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 0
|
||||
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 0
|
||||
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 1
|
||||
|
||||
@@ -53,10 +53,8 @@
|
||||
// Compiler traits ...
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 0
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 0
|
||||
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 0
|
||||
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 1
|
||||
|
||||
@@ -53,10 +53,8 @@
|
||||
// Compiler traits ...
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 1
|
||||
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 0
|
||||
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 0
|
||||
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 1
|
||||
|
||||
@@ -2376,17 +2376,52 @@ namespace UnitTest
|
||||
static_assert(AZStd::wildcard_match_case(filter1, blahValue));
|
||||
}
|
||||
|
||||
TEST_F(String, StringEraseIf_Succeeds)
|
||||
TEST_F(String, StringCXX20Erase_Succeeds)
|
||||
{
|
||||
|
||||
AZStd::string eraseIfTest = "ABC CBA";
|
||||
auto eraseCount = AZStd::erase_if(eraseIfTest, [](AZStd::string::value_type ch)
|
||||
{
|
||||
return ch == 'C';
|
||||
});
|
||||
auto erasePredicate = [](AZStd::string::value_type ch)
|
||||
{
|
||||
return ch == 'C';
|
||||
};
|
||||
auto eraseCount = AZStd::erase_if(eraseIfTest, erasePredicate);
|
||||
EXPECT_EQ(2, eraseCount);
|
||||
EXPECT_EQ(5, eraseIfTest.size());
|
||||
EXPECT_STREQ("AB BA", eraseIfTest.c_str());
|
||||
|
||||
// Now erase the letter 'A';
|
||||
eraseCount = AZStd::erase(eraseIfTest, 'A');
|
||||
EXPECT_EQ(2, eraseCount);
|
||||
EXPECT_EQ(3, eraseIfTest.size());
|
||||
EXPECT_EQ("B B", eraseIfTest);
|
||||
}
|
||||
|
||||
TEST_F(String, FixedStringCXX20Erase_Succeeds)
|
||||
{
|
||||
// Erase 'l' from the phrase "Hello" World"
|
||||
constexpr auto eraseTest = [](const char* testString) constexpr
|
||||
{
|
||||
AZStd::fixed_string<16> testResult{ testString };
|
||||
AZStd::erase(testResult, 'l');
|
||||
return testResult;
|
||||
}("HelloWorld");
|
||||
|
||||
static_assert(eraseTest == "HeoWord");
|
||||
EXPECT_EQ("HeoWord", eraseTest);
|
||||
|
||||
// Use erase_if to erase both 'H' and 'e' from the remaining eraseTest string
|
||||
constexpr auto eraseIfTest = [](AZStd::string_view testString) constexpr
|
||||
{
|
||||
AZStd::fixed_string<16> testResult{ testString };
|
||||
auto erasePredicate = [](char ch)
|
||||
{
|
||||
return ch == 'H' || ch == 'e';
|
||||
};
|
||||
AZStd::erase_if(testResult, erasePredicate);
|
||||
return testResult;
|
||||
}(eraseTest);
|
||||
|
||||
static_assert(eraseIfTest == "oWord");
|
||||
EXPECT_EQ("oWord", eraseIfTest);
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
|
||||
@@ -753,7 +753,7 @@ namespace UnitTest
|
||||
|
||||
TEST_F(Arrays, FixedVectorCanCopyAndMoveWithDifferentCapacity)
|
||||
{
|
||||
constexpr AZStd::fixed_vector<int, 32> sourceVector{ 1,2,3,4,5 };
|
||||
AZStd::fixed_vector<int, 32> sourceVector{ 1,2,3,4,5 };
|
||||
|
||||
AZStd::fixed_vector<int, 8> copyConstructVector{ sourceVector };
|
||||
EXPECT_EQ(sourceVector, copyConstructVector);
|
||||
@@ -768,32 +768,63 @@ namespace UnitTest
|
||||
|
||||
AZStd::fixed_vector<int, 16> moveAssignVector = AZStd::move(moveConstructVector);
|
||||
|
||||
constexpr AZStd::fixed_vector expectedVector{ 1,2,3,4,5,6 };
|
||||
AZStd::fixed_vector expectedVector{ 1,2,3,4,5,6 };
|
||||
EXPECT_EQ(expectedVector, moveAssignVector);
|
||||
}
|
||||
|
||||
TEST_F(Arrays, FixedVectorComparisonOperatorsSucceedAsExpected)
|
||||
{
|
||||
constexpr AZStd::fixed_vector<int, 32> testVector{ 1,2,3,4,5 };
|
||||
constexpr AZStd::fixed_vector<int, 32> equalVector{ 1,2,3,4,5 };
|
||||
constexpr AZStd::fixed_vector<int, 32> notEqualVectorDifferentSize{ 1,2,3,4,5,6 };
|
||||
constexpr AZStd::fixed_vector<int, 32> lessVector{ 1,2,3,4,4 };
|
||||
constexpr AZStd::fixed_vector<int, 32> greaterVectorDifferentSize{ 1,2,3,4,5, 1 };
|
||||
AZStd::fixed_vector<int, 32> testVector{ 1,2,3,4,5 };
|
||||
AZStd::fixed_vector<int, 32> equalVector{ 1,2,3,4,5 };
|
||||
AZStd::fixed_vector<int, 32> notEqualVectorDifferentSize{ 1,2,3,4,5,6 };
|
||||
AZStd::fixed_vector<int, 32> lessVector{ 1,2,3,4,4 };
|
||||
AZStd::fixed_vector<int, 32> greaterVectorDifferentSize{ 1,2,3,4,5, 1 };
|
||||
|
||||
static_assert(testVector == equalVector);
|
||||
static_assert(testVector != notEqualVectorDifferentSize);
|
||||
static_assert(testVector != lessVector);
|
||||
static_assert(lessVector < testVector);
|
||||
static_assert(lessVector < greaterVectorDifferentSize);
|
||||
static_assert(lessVector <= lessVector);
|
||||
static_assert(lessVector <= testVector);
|
||||
static_assert(lessVector <= greaterVectorDifferentSize);
|
||||
static_assert(testVector > lessVector);
|
||||
static_assert(testVector > lessVector);
|
||||
static_assert(notEqualVectorDifferentSize > testVector);
|
||||
static_assert(testVector >= testVector);
|
||||
static_assert(testVector >= lessVector);
|
||||
static_assert(greaterVectorDifferentSize > lessVector);
|
||||
EXPECT_EQ(testVector, equalVector);
|
||||
EXPECT_NE(testVector, notEqualVectorDifferentSize);
|
||||
EXPECT_NE(testVector, lessVector);
|
||||
EXPECT_LT(lessVector, testVector);
|
||||
EXPECT_LT(lessVector, greaterVectorDifferentSize);
|
||||
EXPECT_LE(lessVector, lessVector);
|
||||
EXPECT_LE(lessVector, testVector);
|
||||
EXPECT_LE(lessVector, greaterVectorDifferentSize);
|
||||
EXPECT_GT(testVector, lessVector);
|
||||
EXPECT_GT(testVector, lessVector);
|
||||
EXPECT_GT(notEqualVectorDifferentSize, testVector);
|
||||
EXPECT_GE(testVector, testVector);
|
||||
EXPECT_GE(testVector, lessVector);
|
||||
EXPECT_GT(greaterVectorDifferentSize, lessVector);
|
||||
}
|
||||
|
||||
TEST_F(Arrays, FixedVectorCXX20Erase_Succeeds)
|
||||
{
|
||||
// Erase 'l' from the phrase "Hello" World"
|
||||
auto eraseTest = [](AZStd::initializer_list<char> testInit)
|
||||
{
|
||||
AZStd::fixed_vector<char, 16> testResult{ testInit };
|
||||
AZStd::erase(testResult, 'l');
|
||||
return testResult;
|
||||
}({ 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' });
|
||||
|
||||
constexpr AZStd::string_view expectedEraseString = "HeoWord";
|
||||
AZStd::string_view testEraseString{ eraseTest.begin(), eraseTest.end() };
|
||||
EXPECT_EQ(expectedEraseString, testEraseString);
|
||||
|
||||
// Use erase_if to erase both 'H' and 'e' from the remaining eraseTest string
|
||||
auto eraseIfTest = [](const AZStd::fixed_vector<char, 16>& testVector)
|
||||
{
|
||||
AZStd::fixed_vector<char, 16> testResult{ testVector };
|
||||
auto erasePredicate = [](char ch)
|
||||
{
|
||||
return ch == 'H' || ch == 'e';
|
||||
};
|
||||
AZStd::erase_if(testResult, erasePredicate);
|
||||
return testResult;
|
||||
}(testEraseString);
|
||||
|
||||
constexpr AZStd::string_view expectedEraseIfString = "oWord";
|
||||
AZStd::string_view testEraseIfString{ eraseIfTest.begin(), eraseIfTest.end() };
|
||||
EXPECT_EQ(expectedEraseIfString, testEraseIfString);
|
||||
}
|
||||
|
||||
TEST_F(Arrays, VectorSwap)
|
||||
|
||||
@@ -33,6 +33,15 @@ namespace MathTestData
|
||||
AZ::Matrix3x3::CreateScale(AZ::Vector3(0.7f, 1.3f, 0.9f))
|
||||
};
|
||||
|
||||
static const AZ::Matrix4x4 Matrix4x4s[] = {
|
||||
AZ::Matrix4x4::CreateIdentity(),
|
||||
AZ::Matrix4x4::CreateFromQuaternionAndTranslation(AZ::Quaternion(-0.46f, 0.26f, -0.22f, 0.82f), AZ::Vector3(1.0f, 5.0f, 10.0f)),
|
||||
AZ::Matrix4x4::CreateFromTransform(AZ::Transform::CreateFromMatrix3x3AndTranslation(
|
||||
AZ::Matrix3x3::CreateScale(AZ::Vector3(1.0f, 2.0f, 3.0f)), AZ::Vector3(2.0f, 4.0f, 6.0f))),
|
||||
AZ::Matrix4x4::CreateScale(AZ::Vector3(5.0f, 10.0f, 15.0f)),
|
||||
AZ::Matrix4x4::CreateRotationZ(AZ::DegToRad(45.0f))
|
||||
};
|
||||
|
||||
using AxisPair = AZStd::pair<AZ::Constants::Axis, AZ::Vector3>;
|
||||
static const AxisPair Axes[] = {
|
||||
{ AZ::Constants::Axis::XPositive, AZ::Vector3::CreateAxisX(1.0f) },
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/Math/Matrix3x4.h>
|
||||
#include <AzCore/Math/Matrix3x3.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Math/VectorConversions.h>
|
||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||
#include "MathTestData.h"
|
||||
|
||||
@@ -392,6 +393,32 @@ namespace UnitTest
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MATH_Matrix3x4, Matrix3x4CreateFromMatrix3x3Fixture, ::testing::ValuesIn(MathTestData::Matrix3x3s));
|
||||
|
||||
using Matrix3x4CreateFromMatrix4x4Fixture = ::testing::TestWithParam<AZ::Matrix4x4>;
|
||||
|
||||
TEST_P(Matrix3x4CreateFromMatrix4x4Fixture, UnsafeCreateFromMatrix4x4)
|
||||
{
|
||||
const AZ::Matrix4x4 matrix4x4 = GetParam();
|
||||
const AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::UnsafeCreateFromMatrix4x4(matrix4x4);
|
||||
EXPECT_THAT(matrix3x4.GetTranslation(), IsClose(matrix4x4.GetTranslation()));
|
||||
const AZ::Vector3 vector(2.3f, -0.6, 1.8f);
|
||||
EXPECT_THAT(matrix3x4.TransformVector(vector), IsClose((matrix4x4 * AZ::Vector3ToVector4(vector, 0.0f)).GetAsVector3()));
|
||||
const AZ::Vector3 point(12.3f, -5.6, 7.3f);
|
||||
EXPECT_THAT(matrix3x4.TransformPoint(point), IsClose((matrix4x4 * AZ::Vector3ToVector4(point, 1.0f)).GetAsVector3()));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MATH_Matrix3x4, Matrix3x4CreateFromMatrix4x4Fixture, ::testing::ValuesIn(MathTestData::Matrix4x4s));
|
||||
|
||||
TEST(MATH_Matrix3x4, TransformPoint)
|
||||
{
|
||||
const AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromMatrix3x3AndTranslation(
|
||||
AZ::Matrix3x3::CreateRotationY(AZ::DegToRad(90.0f)), AZ::Vector3(5.0f, 0.0f, 0.0f));
|
||||
|
||||
const AZ::Vector3 result = matrix3x4.TransformPoint(AZ::Vector3(1.0f, 0.0f, 0.0f));
|
||||
const AZ::Vector3 expected = AZ::Vector3(5.0f, 0.0f, -1.0f);
|
||||
|
||||
EXPECT_THAT(result, expected);
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, CreateScale)
|
||||
{
|
||||
const AZ::Vector3 scale(1.7f, 0.3f, 2.4f);
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/IO/ByteContainerStream.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/IO/Path/PathReflect.h>
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
@@ -8151,5 +8152,98 @@ namespace UnitTest
|
||||
m_serializeContext->Class<TestClassWithEnumFieldThatSpecializesTypeInfo>();
|
||||
m_serializeContext->DisableRemoveReflection();
|
||||
}
|
||||
|
||||
template <typename ParamType>
|
||||
class PathSerializationParamFixture
|
||||
: public ScopedAllocatorSetupFixture
|
||||
, public ::testing::WithParamInterface<ParamType>
|
||||
{
|
||||
public:
|
||||
PathSerializationParamFixture()
|
||||
: ScopedAllocatorSetupFixture(
|
||||
[]() { AZ::SystemAllocator::Descriptor desc; desc.m_stackRecordLevels = 30; return desc; }()
|
||||
)
|
||||
{}
|
||||
|
||||
// We must expose the class for serialization first.
|
||||
void SetUp() override
|
||||
{
|
||||
m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
|
||||
AZ::IO::PathReflect(m_serializeContext.get());
|
||||
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_serializeContext->EnableRemoveReflection();
|
||||
AZ::IO::PathReflect(m_serializeContext.get());
|
||||
m_serializeContext->DisableRemoveReflection();
|
||||
|
||||
m_serializeContext.reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
|
||||
};
|
||||
|
||||
struct PathSerializationParams
|
||||
{
|
||||
const char m_preferredSeparator{};
|
||||
const char* m_testPath{};
|
||||
};
|
||||
using PathSerializationFixture = PathSerializationParamFixture<PathSerializationParams>;
|
||||
|
||||
TEST_P(PathSerializationFixture, PathSerializer_SerializesStringBackedPath_Succeeds)
|
||||
{
|
||||
const auto& testParams = GetParam();
|
||||
{
|
||||
// Path serialization
|
||||
AZ::IO::Path testPath{ testParams.m_testPath, testParams.m_preferredSeparator };
|
||||
|
||||
AZStd::vector<char> byteBuffer;
|
||||
AZ::IO::ByteContainerStream byteStream(&byteBuffer);
|
||||
auto objStream = AZ::ObjectStream::Create(&byteStream, *m_serializeContext, AZ::ObjectStream::ST_XML);
|
||||
objStream->WriteClass(&testPath);
|
||||
objStream->Finalize();
|
||||
|
||||
byteStream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
|
||||
AZ::IO::Path loadPath{ testParams.m_preferredSeparator };
|
||||
EXPECT_TRUE(AZ::Utils::LoadObjectFromStreamInPlace(byteStream, loadPath, m_serializeContext.get()));
|
||||
EXPECT_EQ(testPath.LexicallyNormal(), loadPath);
|
||||
}
|
||||
|
||||
{
|
||||
// FixedMaxPath serialization
|
||||
AZ::IO::FixedMaxPath testFixedMaxPath{ testParams.m_testPath, testParams.m_preferredSeparator };
|
||||
|
||||
AZStd::vector<char> byteBuffer;
|
||||
AZ::IO::ByteContainerStream byteStream(&byteBuffer);
|
||||
auto objStream = AZ::ObjectStream::Create(&byteStream, *m_serializeContext, AZ::ObjectStream::ST_XML);
|
||||
objStream->WriteClass(&testFixedMaxPath);
|
||||
objStream->Finalize();
|
||||
|
||||
byteStream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
|
||||
AZ::IO::FixedMaxPath loadPath{ testParams.m_preferredSeparator };
|
||||
EXPECT_TRUE(AZ::Utils::LoadObjectFromStreamInPlace(byteStream, loadPath, m_serializeContext.get()));
|
||||
EXPECT_EQ(testFixedMaxPath.LexicallyNormal(), loadPath);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
PathSerialization,
|
||||
PathSerializationFixture,
|
||||
::testing::Values(
|
||||
PathSerializationParams{ AZ::IO::PosixPathSeparator, "" },
|
||||
PathSerializationParams{ AZ::IO::PosixPathSeparator, "test" },
|
||||
PathSerializationParams{ AZ::IO::PosixPathSeparator, "/test" },
|
||||
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "test" },
|
||||
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "/test" },
|
||||
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "D:test" },
|
||||
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "D:/test" },
|
||||
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "test/foo/../bar" }
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -539,6 +539,22 @@ tags=tools,renderer,metal)"
|
||||
EXPECT_STREQ("Bat", commandLine.GetMiscValue(2).c_str());
|
||||
}
|
||||
|
||||
TEST_F(SettingsRegistryMergeUtilsCommandLineFixture, RegsetFileArgument_DoesNotMergeNUL)
|
||||
{
|
||||
AZStd::string regsetFile = AZ::IO::SystemFile::GetNullFilename();
|
||||
AZ::CommandLine commandLine;
|
||||
commandLine.Parse({ "--regset-file", regsetFile });
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_registry, commandLine, false);
|
||||
|
||||
// Add a settings path to anchor loaded settings underneath
|
||||
regsetFile = AZStd::string::format("%s::/AnchorPath/Of/Settings", AZ::IO::SystemFile::GetNullFilename());
|
||||
commandLine.Parse({ "--regset-file", regsetFile });
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_registry, commandLine, false);
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/AnchorPath/Of/Settings"));
|
||||
}
|
||||
|
||||
using SettingsRegistryAncestorDescendantOrEqualPathFixture = SettingsRegistryMergeUtilsCommandLineFixture;
|
||||
|
||||
TEST_F(SettingsRegistryAncestorDescendantOrEqualPathFixture, ValidateThatAncestorOrDescendantOrPathWithTheSameValue_Succeeds)
|
||||
|
||||
Reference in New Issue
Block a user