GCC Support for Linux

Updates and fixes to support GCC for Linux

Signed-off-by: Steve Pham <82231385+spham-amzn@users.noreply.github.com>

Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
Steve Pham
2022-01-20 13:00:02 -08:00
committed by GitHub
parent 3479b6e2d9
commit 59e43813f0
98 changed files with 1050 additions and 429 deletions
+7 -2
View File
@@ -23,6 +23,11 @@
#include <AzCore/EBus/Results.h>
#include <AzCore/EBus/Internal/Debug.h>
// Included for backwards compatibility purposes
#include <AzCore/std/typetraits/typetraits.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/std/containers/unordered_set.h>
#include <AzCore/std/typetraits/is_same.h>
#include <AzCore/std/utils.h>
@@ -515,7 +520,7 @@ namespace AZ
* This is not EBus Context Mutex when LocklessDispatch is set
*/
template <typename DispatchMutex>
using DispatchLockGuard = typename ImplTraits::template DispatchLockGuard<DispatchMutex>;
using DispatchLockGuardTemplate = typename ImplTraits::template DispatchLockGuard<DispatchMutex>;
//////////////////////////////////////////////////////////////////////////
// Check to help identify common mistakes
@@ -645,7 +650,7 @@ namespace AZ
* during broadcast/event dispatch.
* @see EBusTraits::LocklessDispatch
*/
using DispatchLockGuard = DispatchLockGuard<ContextMutexType>;
using DispatchLockGuard = DispatchLockGuardTemplate<ContextMutexType>;
/**
* The scoped lock guard to use during connection. Some specialized policies execute handler methods which
@@ -93,14 +93,14 @@ namespace AZ
// This struct will hold the handlers per address
struct HandlerHolder;
// This struct will hold each handler
using HandlerNode = HandlerNode<Interface, Traits, HandlerHolder>;
using HandlerNode = AZ::Internal::HandlerNode<Interface, Traits, HandlerHolder>;
// Defines how handler holders are stored (will be some sort of map-like structure from id -> handler holder)
using AddressStorage = AddressStoragePolicy<Traits, HandlerHolder>;
// Defines how handlers are stored per address (will be some sort of list)
using HandlerStorage = HandlerStoragePolicy<Interface, Traits, HandlerNode>;
using Handler = IdHandler<Interface, Traits, ContainerType>;
using MultiHandler = MultiHandler<Interface, Traits, ContainerType>;
using MultiHandler = AZ::Internal::MultiHandler<Interface, Traits, ContainerType>;
using BusPtr = AZStd::intrusive_ptr<HandlerHolder>;
EBusContainer() = default;
@@ -774,13 +774,13 @@ namespace AZ
// This struct will hold the handler per address
struct HandlerHolder;
// This struct will hold each handler
using HandlerNode = HandlerNode<Interface, Traits, HandlerHolder>;
using HandlerNode = AZ::Internal::HandlerNode<Interface, Traits, HandlerHolder>;
// Defines how handler holders are stored (will be some sort of map-like structure from id -> handler holder)
using AddressStorage = AddressStoragePolicy<Traits, HandlerHolder>;
// No need for HandlerStorage, there's only 1 so it will always just be a HandlerNode*
using Handler = IdHandler<Interface, Traits, ContainerType>;
using MultiHandler = MultiHandler<Interface, Traits, ContainerType>;
using MultiHandler = AZ::Internal::MultiHandler<Interface, Traits, ContainerType>;
using BusPtr = AZStd::intrusive_ptr<HandlerHolder>;
EBusContainer() = default;
@@ -1316,7 +1316,7 @@ namespace AZ
// This struct will hold the handlers per address
struct HandlerHolder;
// This struct will hold each handler
using HandlerNode = HandlerNode<Interface, Traits, HandlerHolder>;
using HandlerNode = AZ::Internal::HandlerNode<Interface, Traits, HandlerHolder>;
// Defines how handlers are stored per address (will be some sort of list)
using HandlerStorage = HandlerStoragePolicy<Interface, Traits, HandlerNode>;
// No need for AddressStorage, there's only 1
@@ -161,7 +161,7 @@ namespace AZ
template <class C>
struct EBusCallstackStorage<C, true>
{
AZ_THREAD_LOCAL static C* s_entry;
static AZ_THREAD_LOCAL C* s_entry;
EBusCallstackStorage() = default;
~EBusCallstackStorage() = default;
+43 -51
View File
@@ -13,50 +13,6 @@
#include <AzCore/IO/Path/PathIterable.inl>
// extern instantiations of Path templates to prevent implicit instantiations
namespace AZ::IO
{
// Class templates explicit declarations
extern template class BasicPath<AZStd::string>;
extern template class BasicPath<FixedMaxPathString>;
extern template class PathIterator<PathView>;
extern template class PathIterator<Path>;
extern template class PathIterator<FixedMaxPath>;
// Swap function explicit declarations
extern template void swap<AZStd::string>(Path& lhs, Path& rhs) noexcept;
extern template void swap<FixedMaxPathString>(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept;
// Hash function explicit declarations
extern template size_t hash_value<AZStd::string>(const Path& pathToHash);
extern template size_t hash_value<FixedMaxPathString>(const FixedMaxPath& pathToHash);
// Append operator explicit declarations
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, const PathView& rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, const PathView& rhs);
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, AZStd::string_view rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, AZStd::string_view rhs);
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs,
const typename BasicPath<AZStd::string>::value_type* rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs,
const typename BasicPath<FixedMaxPathString>::value_type* rhs);
// Iterator compare explicit declarations
extern template bool operator==<PathView>(const PathIterator<PathView>& lhs,
const PathIterator<PathView>& rhs);
extern template bool operator==<Path>(const PathIterator<Path>& lhs,
const PathIterator<Path>& rhs);
extern template bool operator==<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
extern template bool operator!=<PathView>(const PathIterator<PathView>& lhs,
const PathIterator<PathView>& rhs);
extern template bool operator!=<Path>(const PathIterator<Path>& lhs,
const PathIterator<Path>& rhs);
extern template bool operator!=<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
}
//! PathView implementation
namespace AZ::IO
{
@@ -939,13 +895,13 @@ namespace AZ::IO
// then it has no root directory nor filename
if (rootNameView.end() == m_path.end())
{
// has_root_directory || has_filename = false
// If the root name is of the form
// # C: - then it isn't absolute unless it has a root directory C:\
// # \\?\ = is a UNC path that can't exist without a root directory
// # \\server - Is absolute, but has no root directory
// Therefore if the rootName is larger than three characters
// then append the path separator
/* has_root_directory || has_filename = false
If the root name is of the form
C: - then it isn't absolute unless it has a root directory C:\.
\\?\ = is a UNC path that can't exist without a root directory.
\\server - Is absolute, but has no root directory.
Therefore if the rootName is larger than three characters
then append the path separator. */
if (rootNameView.size() >= 3)
{
m_path.push_back(m_preferred_separator);
@@ -1550,3 +1506,39 @@ namespace AZ::IO
return AZStd::hash<PathView>{}(pathToHash);
}
}
// extern instantiations of Path templates to prevent implicit instantiations
namespace AZ::IO
{
// Swap function explicit declarations
extern template void swap<AZStd::string>(Path& lhs, Path& rhs) noexcept;
extern template void swap<FixedMaxPathString>(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept;
// Hash function explicit declarations
extern template size_t hash_value<AZStd::string>(const Path& pathToHash);
extern template size_t hash_value<FixedMaxPathString>(const FixedMaxPath& pathToHash);
// Append operator explicit declarations
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, const PathView& rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, const PathView& rhs);
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, AZStd::string_view rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, AZStd::string_view rhs);
extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs,
const typename BasicPath<AZStd::string>::value_type* rhs);
extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs,
const typename BasicPath<FixedMaxPathString>::value_type* rhs);
// Iterator compare explicit declarations
extern template bool operator==<PathView>(const PathIterator<PathView>& lhs,
const PathIterator<PathView>& rhs);
extern template bool operator==<Path>(const PathIterator<Path>& lhs,
const PathIterator<Path>& rhs);
extern template bool operator==<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
extern template bool operator!=<PathView>(const PathIterator<PathView>& lhs,
const PathIterator<PathView>& rhs);
extern template bool operator!=<Path>(const PathIterator<Path>& lhs,
const PathIterator<Path>& rhs);
extern template bool operator!=<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
}
@@ -14,7 +14,7 @@
#define az_clz_u64(x) _lzcnt_u64(x)
#define az_popcnt_u32(x) __popcnt(x)
#define az_popcnt_u64(x) __popcnt64(x)
#elif defined(AZ_COMPILER_CLANG)
#elif defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC)
#define az_ctz_u32(x) __builtin_ctz(x)
#define az_ctz_u64(x) __builtin_ctzll(x)
#define az_clz_u32(x) __builtin_clz(x)
@@ -22,5 +22,5 @@
#define az_popcnt_u32(x) __builtin_popcount(x)
#define az_popcnt_u64(x) __builtin_popcountll(x)
#else
#error Count Leading Zeros, Count Trailing Zeros and Pop Count intrinsics isn't supported for this compiler
#error Count Leading Zeros, Count Trailing Zeros and Pop Count intrinsics isnt supported for this compiler
#endif
@@ -39,6 +39,9 @@ namespace AZ
template<typename T> constexpr friend void AZStd::destroy_at(T*);
public:
AllocatorManager();
typedef AZStd::function<void (IAllocator* allocator, size_t /*byteSize*/, size_t /*alignment*/, int/* flags*/, const char* /*name*/, const char* /*fileName*/, int lineNum /*=0*/)> OutOfMemoryCBType;
static void PreRegisterAllocator(IAllocator* allocator); // Only call if the environment is not yet attached
@@ -185,7 +188,6 @@ namespace AZ
AZ::Debug::AllocationRecords::Mode m_defaultTrackingRecordMode;
AZStd::unique_ptr<AZ::MallocSchema, void(*)(AZ::MallocSchema*)> m_mallocSchema;
AllocatorManager();
~AllocatorManager();
static AllocatorManager g_allocMgr; ///< The single instance of the allocator manager
@@ -45,7 +45,9 @@ namespace AZ
//! that already exist.
class NameDictionary final
{
public:
AZ_CLASS_ALLOCATOR(NameDictionary, AZ::OSAllocator, 0);
private:
friend Module;
friend Name;
@@ -75,8 +77,8 @@ namespace AZ
//! @return A Name instance. If the hash was not found, the Name will be empty.
Name FindName(Name::Hash hash) const;
private:
NameDictionary();
private:
~NameDictionary();
void ReportStats() const;
+85 -7
View File
@@ -10,10 +10,17 @@
//////////////////////////////////////////////////////////////////////////
// Platforms
#include <AzCore/variadic.h>
#include "PlatformRestrictedFileDef.h"
#if defined(__clang__)
#define AZ_COMPILER_CLANG __clang_major__
#elif defined(__GNUC__)
// Assign AZ_COMPILER_GCC to a number that represents the major+minor (2 digits) + path level (2 digits) i.e. 3.2.0 == 30200
#define AZ_COMPILER_GCC (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#elif defined(_MSC_VER)
#define AZ_COMPILER_MSVC _MSC_VER
#else
@@ -29,7 +36,7 @@
#define AZ_DYNAMIC_LIBRARY_PREFIX AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX
#define AZ_DYNAMIC_LIBRARY_EXTENSION AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION
#if defined(AZ_COMPILER_CLANG)
#if defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC)
#define AZ_DLL_EXPORT AZ_TRAIT_OS_DLL_EXPORT_CLANG
#define AZ_DLL_IMPORT AZ_TRAIT_OS_DLL_IMPORT_CLANG
#elif defined(AZ_COMPILER_MSVC)
@@ -67,12 +74,36 @@
#if defined(AZ_COMPILER_MSVC)
/// Disables a warning using push style. For use matched with an AZ_POP_WARNING
#define AZ_PUSH_DISABLE_WARNING(_msvcOption, __) \
__pragma(warning(push)) \
// Compiler specific AZ_PUSH_DISABLE_WARNING
#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption) \
__pragma(warning(push)) \
__pragma(warning(disable : _msvcOption))
#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption)
#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption)
/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs
#define AZ_POP_DISABLE_WARNING_CLANG
#define AZ_POP_DISABLE_WARNING_MSVC \
__pragma(warning(pop))
#define AZ_POP_DISABLE_WARNING_GCC
// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler
#define AZ_PUSH_DISABLE_WARNING_1(_msvcOption) \
__pragma(warning(push)) \
__pragma(warning(disable : _msvcOption))
#define AZ_PUSH_DISABLE_WARNING_2(_msvcOption, _2) \
__pragma(warning(push)) \
__pragma(warning(disable : _msvcOption))
#define AZ_PUSH_DISABLE_WARNING_3(_msvcOption, _2, _3) \
__pragma(warning(push)) \
__pragma(warning(disable : _msvcOption))
/// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING
#define AZ_POP_DISABLE_WARNING \
#define AZ_POP_DISABLE_WARNING \
__pragma(warning(pop))
@@ -94,17 +125,62 @@
# define AZ_FUNCTION_SIGNATURE __FUNCSIG__
//////////////////////////////////////////////////////////////////////////
#elif defined(AZ_COMPILER_CLANG)
#elif defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC)
#if defined(AZ_COMPILER_CLANG)
/// Disables a single warning using push style. For use matched with an AZ_POP_WARNING
#define AZ_PUSH_DISABLE_WARNING(__, _clangOption) \
_Pragma("clang diagnostic push") \
// Compiler specific AZ_PUSH_DISABLE_WARNING
#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) \
_Pragma("clang diagnostic push") \
_Pragma(AZ_STRINGIZE(clang diagnostic ignored _clangOption))
#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption)
#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption)
/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs
#define AZ_POP_DISABLE_WARNING_CLANG \
_Pragma("clang diagnostic pop")
#define AZ_POP_DISABLE_WARNING_MSVC
#define AZ_POP_DISABLE_WARNING_GCC
// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler
#define AZ_PUSH_DISABLE_WARNING_1(_1)
#define AZ_PUSH_DISABLE_WARNING_2(_1, _clangOption) AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption)
#define AZ_PUSH_DISABLE_WARNING_3(_1, _clangOption, _2) AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption)
/// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING
#define AZ_POP_DISABLE_WARNING \
_Pragma("clang diagnostic pop")
#else
/// Disables a single warning using push style. For use matched with an AZ_POP_WARNING
// Compiler specific AZ_PUSH_DISABLE_WARNING
#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) \
_Pragma("GCC diagnostic push") \
_Pragma(AZ_STRINGIZE(GCC diagnostic ignored _gccOption))
#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption)
#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption)
/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs
#define AZ_POP_DISABLE_WARNING_CLANG
#define AZ_POP_DISABLE_WARNING_MSVC
#define AZ_POP_DISABLE_WARNING_GCC \
_Pragma("GCC diagnostic pop")
// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler
#define AZ_PUSH_DISABLE_WARNING_1(_1)
#define AZ_PUSH_DISABLE_WARNING_2(_1, _2)
#define AZ_PUSH_DISABLE_WARNING_3(_1, _2, _gccOption) AZ_PUSH_DISABLE_WARNING_GCC(_gccOption)
/// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING
#define AZ_POP_DISABLE_WARNING
_Pragma("GCC diagnostic pop")
#endif // defined(AZ_COMPILER_CLANG)
#define AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
#define AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
#define AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
@@ -121,6 +197,8 @@
#error Compiler not supported
#endif
#define AZ_PUSH_DISABLE_WARNING(...) AZ_MACRO_SPECIALIZE(AZ_PUSH_DISABLE_WARNING_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
// We need to define AZ_DEBUG_BUILD in debug mode. We can also define it in debug optimized mode (left up to the user).
// note that _DEBUG is not in fact always defined on all platforms, and only AZ_DEBUG_BUILD should be relied on.
#if !defined(AZ_DEBUG_BUILD) && defined(_DEBUG)
@@ -1541,7 +1541,7 @@ namespace AZ
}
template<class T>
static bool SetClassEqualityComparer(BehaviorClass* behaviorClass, const T*)
static void SetClassEqualityComparer(BehaviorClass* behaviorClass, const T*)
{
behaviorClass->m_equalityComparer = &DefaultEqualityComparer<T>;
}
@@ -2341,8 +2341,6 @@ namespace AZ
// For some reason the Script.cpp test validates that an incomplete type can be used with the SetResult struct
template<typename T, typename U, typename = void>
static constexpr bool IsCopyAssignable = false;
template<typename T, typename U>
static constexpr bool IsCopyAssignable<T, U, AZStd::void_t<decltype(AZStd::declval<T>() = AZStd::declval<U>())>> = true;
template<class T>
static bool Set(BehaviorValueParameter& param, T&& result, bool IsValueCopy)
@@ -2402,6 +2400,9 @@ namespace AZ
}
};
template<typename T, typename U>
constexpr bool SetResult::IsCopyAssignable<T, U, AZStd::void_t<decltype(AZStd::declval<T>() = AZStd::declval<U>())>> = true;
AZ_FORCE_INLINE BehaviorValueParameter& BehaviorValueParameter::operator=(BehaviorValueParameter&& other)
{
*static_cast<BehaviorParameter*>(this) = AZStd::move(static_cast<BehaviorParameter&&>(other));
+21 -8
View File
@@ -977,26 +977,32 @@ namespace AZ
{
return AzGenericTypeInfo::Uuid<U>();
}
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class U, typename = void>
#else
template<template<auto...> class U, typename = void>
#endif // defined(AZ_COMPILER_MSVC)
inline const AZ::TypeId& RttiTypeId()
{
return AzGenericTypeInfo::Uuid<U>();
}
template<template<typename, AZStd::size_t> class U, typename = void>
template<template<typename, auto> class U, typename = void>
inline const AZ::TypeId& RttiTypeId()
{
return AzGenericTypeInfo::Uuid<U>();
}
template<template<typename, typename, AZStd::size_t> class U, typename = void>
template<template<typename, typename, auto> class U, typename = void>
inline const AZ::TypeId& RttiTypeId()
{
return AzGenericTypeInfo::Uuid<U>();
}
template<template<typename, typename, typename, AZStd::size_t> class U, typename = void>
template<template<typename, typename, typename, auto> class U, typename = void>
inline const AZ::TypeId& RttiTypeId()
{
return AzGenericTypeInfo::Uuid<U>();
@@ -1027,15 +1033,22 @@ namespace AZ
}
// Returns true if the type is contained, otherwise false. Safe to call for type not supporting AZRtti (returns false unless type fully match).
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class T, class U>
inline bool RttiIsTypeOf(const U&)
#else
template<template<auto...> class T, class U>
#endif // defined(AZ_COMPILER_MSVC)
inline bool RttiIsTypeOf(const U&)
{
using CheckType = typename AZ::Internal::RttiRemoveQualifiers<U>::type;
return AzGenericTypeInfo::Uuid<T>() == RttiTypeId<CheckType, AZ::GenericTypeIdTag>();
}
// Returns true if the type is contained, otherwise false. Safe to call for type not supporting AZRtti (returns false unless type fully match).
template<template<typename, AZStd::size_t> class T, class U>
template<template<typename, auto> class T, class U>
inline bool RttiIsTypeOf(const U&)
{
using CheckType = typename AZ::Internal::RttiRemoveQualifiers<U>::type;
@@ -1043,7 +1056,7 @@ namespace AZ
}
// Returns true if the type is contained, otherwise false.Safe to call for type not supporting AZRtti(returns false unless type fully match).
template<template<typename, typename, AZStd::size_t> class T, class U>
template<template<typename, typename, auto> class T, class U>
inline bool RttiIsTypeOf(const U&)
{
using CheckType = typename AZ::Internal::RttiRemoveQualifiers<U>::type;
@@ -1051,7 +1064,7 @@ namespace AZ
}
// Returns true if the type is contained, otherwise false.Safe to call for type not supporting AZRtti(returns false unless type fully match).
template<template<typename, typename, typename, AZStd::size_t> class T, class U>
template<template<typename, typename, typename, auto> class T, class U>
inline bool RttiIsTypeOf(const U&)
{
using CheckType = typename AZ::Internal::RttiRemoveQualifiers<U>::type;
+24 -12
View File
@@ -148,11 +148,18 @@ namespace AZ
{
/// Needs to match declared parameter type.
template <template <typename...> class> constexpr bool false_v1 = false;
template <template <AZStd::size_t...> class> constexpr bool false_v2 = false;
template <template <typename, AZStd::size_t> class> constexpr bool false_v3 = false;
template <template <typename, typename, AZStd::size_t> class> constexpr bool false_v4 = false;
template <template <typename, typename, typename, AZStd::size_t> class> constexpr bool false_v5 = false;
template <template <typename, AZStd::size_t, typename> class> constexpr bool false_v6 = false;
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class> constexpr bool false_v2 = false;
#else
template<template<auto...> class> constexpr bool false_v2 = false;
#endif // defined(AZ_COMPILER_MSVC)
template<template<typename, auto> class>
constexpr bool false_v3 = false;
template <template <typename, typename, auto> class> constexpr bool false_v4 = false;
template <template <typename, typename, typename, auto> class> constexpr bool false_v5 = false;
template <template <typename, auto, typename> class> constexpr bool false_v6 = false;
template<typename T>
inline const AZ::TypeId& Uuid()
@@ -167,8 +174,13 @@ namespace AZ
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
return s_uuid;
}
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class T>
#else
template<template<auto...> class T>
#endif // defined(AZ_COMPILER_MSVC)
inline const AZ::TypeId& Uuid()
{
static_assert(false_v2<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -176,7 +188,8 @@ namespace AZ
return s_uuid;
}
template<template<typename, AZStd::size_t> class T>
template<template<typename, auto> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v3<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -184,7 +197,7 @@ namespace AZ
return s_uuid;
}
template<template<typename, typename, AZStd::size_t> class T>
template<template<typename, typename, auto> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v4<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -192,7 +205,7 @@ namespace AZ
return s_uuid;
}
template<template<typename, typename, typename, AZStd::size_t> class T>
template<template<typename, typename, typename, auto> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v5<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -200,7 +213,7 @@ namespace AZ
return s_uuid;
}
template<template<typename, AZStd::size_t, typename> class T>
template<template<typename, auto, typename> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v6<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
@@ -689,8 +702,7 @@ namespace AZ
#define AZ_TYPE_INFO_INTERNAL_CLASS_VARARGS__UUID(Tag, A) AZ::Internal::AggregateTypes< A... >::template Uuid< Tag >()
#define AZ_TYPE_INFO_INTERNAL_CLASS_VARARGS__NAME(A) AZ::Internal::AggregateTypes< A... >::TypeName(typeName, AZ_ARRAY_SIZE(typeName));
// Once C++17 has been introduced size_t can be replaced with auto for all integer non-type arguments
#define AZ_TYPE_INFO_INTERNAL_AUTO__TYPE AZStd::size_t
#define AZ_TYPE_INFO_INTERNAL_AUTO__TYPE auto
#define AZ_TYPE_INFO_INTERNAL_AUTO__ARG(A) A
#define AZ_TYPE_INFO_INTERNAL_AUTO__UUID(Tag, A) AZ::Internal::GetTypeId< A , Tag >()
#define AZ_TYPE_INFO_INTERNAL_AUTO__NAME(A) AZ::Internal::AzTypeInfoSafeCat(typeName, AZ_ARRAY_SIZE(typeName), AZ::Internal::GetTypeName< A >())
@@ -796,7 +796,7 @@ namespace AZ
// Note: Always use l over context->NativeContext(), as require may be called from a thread.
using RequireHook = AZStd::function<int(lua_State* lua, ScriptContext* context, const char* module)>;
using StackVariableAllocator = StackVariableAllocator;
using StackVariableAllocator = AZ::StackVariableAllocator;
/// Stack temporary memory
/**
@@ -69,7 +69,13 @@ namespace AZ
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
}
#if defined(AZ_COMPILER_MSVC)
// There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template
// template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack.
template<template<AZStd::size_t...> class T>
#else
template<template<auto...> class T>
#endif // defined(AZ_COMPILER_MSVC)
SerializerBuilder* HandlesType(bool overwriteExisting = false)
{
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
@@ -17,16 +17,9 @@
#if defined(HAVE_BENCHMARK)
#if defined(AZ_COMPILER_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif // clang
AZ_PUSH_DISABLE_WARNING(, "-Wdeprecated-declarations", "-Wdeprecated-declarations")
#include <benchmark/benchmark.h>
#if defined(AZ_COMPILER_CLANG)
#pragma clang diagnostic pop
#endif // clang
AZ_POP_DISABLE_WARNING
#endif // HAVE_BENCHMARK
@@ -9,6 +9,7 @@
set(FILES
base.h
Docs.h
variadic.h
Platform.cpp
Platform.h
PlatformDef.h
+1 -60
View File
@@ -7,6 +7,7 @@
*/
#pragma once
#include <AzCore/variadic.h>
#include <AzCore/PlatformDef.h> ///< Platform/compiler specific defines
#include <AzCore/base_Platform.h>
@@ -135,66 +136,6 @@
#define AZ_INVALID_POINTER reinterpret_cast<void*>(0x0badf00dul)
// Variadic MACROS util functions
/**
* AZ_VA_NUM_ARGS
* counts number of parameters (up to 10).
* example. AZ_VA_NUM_ARGS(x,y,z) -> expands to 3
*/
#ifndef AZ_VA_NUM_ARGS
# define AZ_VA_HAS_ARGS(...) ""#__VA_ARGS__[0] != 0
// we add the zero to avoid the case when we require at least 1 param at the end...
# define AZ_VA_NUM_ARGS(...) AZ_VA_NUM_ARGS_IMPL_((__VA_ARGS__, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
# define AZ_VA_NUM_ARGS_IMPL_(tuple) AZ_VA_NUM_ARGS_IMPL tuple
# define AZ_VA_NUM_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, N, ...) N
// Expands a macro and calls a different macro based on the number of arguments.
//
// Example: We need to specialize a macro for 1 and 2 arguments
// #define AZ_MY_MACRO(...) AZ_MACRO_SPECIALIZE(AZ_MY_MACRO_,AZ_VA_NUM_ARGS(__VA_ARGS__),(__VA_ARGS__))
//
// #define AZ_MY_MACRO_1(_1) /* code for 1 param */
// #define AZ_MY_MACRO_2(_1,_2) /* code for 2 params */
// ... etc.
//
//
// We have 3 levels of macro expansion...
# define AZ_MACRO_SPECIALIZE_II(MACRO_NAME, NPARAMS, PARAMS) MACRO_NAME##NPARAMS PARAMS
# define AZ_MACRO_SPECIALIZE_I(MACRO_NAME, NPARAMS, PARAMS) AZ_MACRO_SPECIALIZE_II(MACRO_NAME, NPARAMS, PARAMS)
# define AZ_MACRO_SPECIALIZE(MACRO_NAME, NPARAMS, PARAMS) AZ_MACRO_SPECIALIZE_I(MACRO_NAME, NPARAMS, PARAMS)
#endif // AZ_VA_NUM_ARGS
// Out of all supported compilers, mwerks is the only one
// that requires variadic macros to have at least 1 param.
// This is a pain they we use macros to call functions (with no params).
// we implement functions for up to 10 params
#define AZ_FUNCTION_CALL_1(_1) _1()
#define AZ_FUNCTION_CALL_2(_1, _2) _1(_2)
#define AZ_FUNCTION_CALL_3(_1, _2, _3) _1(_2, _3)
#define AZ_FUNCTION_CALL_4(_1, _2, _3, _4) _1(_2, _3, _4)
#define AZ_FUNCTION_CALL_5(_1, _2, _3, _4, _5) _1(_2, _3, _4, _5)
#define AZ_FUNCTION_CALL_6(_1, _2, _3, _4, _5, _6) _1(_2, _3, _4, _5, _6)
#define AZ_FUNCTION_CALL_7(_1, _2, _3, _4, _5, _6, _7) _1(_2, _3, _4, _5, _6, _7)
#define AZ_FUNCTION_CALL_8(_1, _2, _3, _4, _5, _6, _7, _8) _1(_2, _3, _4, _5, _6, _7, _8)
#define AZ_FUNCTION_CALL_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) _1(_2, _3, _4, _5, _6, _7, _8, _9)
#define AZ_FUNCTION_CALL_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) _1(_2, _3, _4, _5, _6, _7, _8, _9, _10)
// We require at least 1 param FunctionName
#define AZ_FUNCTION_CALL(...) AZ_MACRO_SPECIALIZE(AZ_FUNCTION_CALL_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
// Based on boost macro expansion fix...
#define AZ_PREVENT_MACRO_SUBSTITUTION
//////////////////////////////////////////////////////////////////////////
#include <cstddef> // the macros NULL and offsetof as well as the types ptrdiff_t, wchar_t, and size_t.
@@ -8,6 +8,7 @@
#pragma once
#include <AzCore/std/utils.h>
#include <AzCore/std/typetraits/is_same.h>
#include <AzCore/std/typetraits/is_constructible.h>
#include <AzCore/std/typetraits/remove_cvref.h>
@@ -253,7 +253,7 @@ namespace AZStd::Internal
}
template <typename U, typename = enable_if_t<is_convertible_v<U, T>>>
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(this->emplace_back(AZStd::declval<U>())))
{
AZSTD_CONTAINER_ASSERT(ilist.size() <= capacity(), "Initializer list cannot be larger than storage capacity");
for (const U& element : ilist)
@@ -79,7 +79,7 @@ namespace AZStd
typedef typename tree_type::const_reverse_iterator const_reverse_iterator;
using node_type = map_node_handle<map_node_traits<key_type, mapped_type, allocator_type, typename tree_type::node_type, typename tree_type::node_deleter>>;
using insert_return_type = insert_return_type<iterator, node_type>;
using insert_return_type = AZStd::AssociativeInternal::insert_return_type<iterator, node_type>;
AZ_FORCE_INLINE explicit map(const Compare& comp = Compare(), const Allocator& alloc = Allocator())
: m_tree(comp, alloc) {}
@@ -123,7 +123,8 @@ namespace AZStd
}
}
friend void swap(node_handle& lhs, node_handle& rhs);
template <typename SwapNodeTraits, template <typename, typename> class SwapMapOrSetNodeHandleBase>
friend void swap(node_handle<SwapNodeTraits, SwapMapOrSetNodeHandleBase>& lhs, node_handle<SwapNodeTraits, SwapMapOrSetNodeHandleBase>& rhs);
private:
node_handle(node_pointer_type node, const allocator_type& allocator)
@@ -152,8 +153,8 @@ namespace AZStd
optional<allocator_type> m_allocator;
};
template <typename NodeTraits, template <typename, typename> class MapOrSetNodeHandleBase>
void swap(node_handle<NodeTraits, MapOrSetNodeHandleBase>& lhs, node_handle<NodeTraits, MapOrSetNodeHandleBase>& rhs)
template <typename SwapNodeTraits, template <typename, typename> class SwapMapOrSetNodeHandleBase>
void swap(node_handle<SwapNodeTraits, SwapMapOrSetNodeHandleBase>& lhs, node_handle<SwapNodeTraits, SwapMapOrSetNodeHandleBase>& rhs)
{
lhs.swap(rhs);
}
@@ -68,7 +68,7 @@ namespace AZStd
typedef typename tree_type::const_reverse_iterator const_reverse_iterator;
using node_type = set_node_handle<set_node_traits<value_type, allocator_type, typename tree_type::node_type, typename tree_type::node_deleter>>;
using insert_return_type = insert_return_type<iterator, node_type>;
using insert_return_type = AZStd::AssociativeInternal::insert_return_type<iterator, node_type>;
AZ_FORCE_INLINE explicit set(const Compare& comp = Compare(), const Allocator& alloc = Allocator())
: m_tree(comp, alloc) {}
@@ -102,7 +102,7 @@ namespace AZStd
typedef typename base_type::pair_iter_bool pair_iter_bool;
using node_type = map_node_handle<map_node_traits<key_type, mapped_type, allocator_type, typename base_type::list_node_type, typename base_type::node_deleter>>;
using insert_return_type = insert_return_type<iterator, node_type>;
using insert_return_type = AZStd::AssociativeInternal::insert_return_type<iterator, node_type>;
AZ_FORCE_INLINE unordered_map()
: base_type(hasher(), key_eq(), allocator_type()) {}
@@ -87,7 +87,7 @@ namespace AZStd
typedef typename base_type::const_local_iterator const_local_iterator;
using node_type = set_node_handle<set_node_traits<value_type, allocator_type, typename base_type::list_node_type, typename base_type::node_deleter>>;
using insert_return_type = insert_return_type<iterator, node_type>;
using insert_return_type = AZStd::AssociativeInternal::insert_return_type<iterator, node_type>;
AZ_FORCE_INLINE unordered_set()
: base_type(hasher(), key_eq(), allocator_type()) {}
@@ -279,11 +279,11 @@ namespace AZStd
reinterpret_cast<functor_type*>(&in_buffer.data);
if (op == clone_functor_tag)
{
new ((void*)&out_buffer.data)functor_type(*in_functor);
AZStd::construct_at(reinterpret_cast<functor_type*>(&out_buffer), functor_type(*in_functor));
}
else if (op == move_functor_tag)
{
new ((void*)&out_buffer.data)functor_type(AZStd::move(*in_functor));
AZStd::construct_at(reinterpret_cast<functor_type*>(&out_buffer), functor_type(AZStd::move(*in_functor)));
// Casting via union to get around compiler warnings (strict type on GCC, unused variable on MSVC)
union
{
@@ -291,7 +291,7 @@ namespace AZStd
assign_functor(FunctionObj&& f, function_buffer& functor, AZStd::true_type)
{
using RawFunctorObjType = AZStd::decay_t<FunctionObj>;
new ((void*)&functor.data)RawFunctorObjType(AZStd::forward<FunctionObj>(f));
AZStd::construct_at(reinterpret_cast<RawFunctorObjType*>(&functor), RawFunctorObjType(AZStd::forward<FunctionObj>(f)));
}
template<typename FunctionObj, typename Allocator>
void
@@ -8,6 +8,7 @@
#pragma once
#include <AzCore/std/typetraits/typetraits.h>
#include <AzCore/std/typetraits/invoke_traits.h>
namespace AZStd
@@ -30,9 +30,8 @@ namespace AZStd
// #3
template<class Element, size_t MaxElementCount, class Traits>
inline constexpr basic_fixed_string<Element, MaxElementCount, Traits>::basic_fixed_string(const basic_fixed_string& rhs,
size_type rhsOffset)
size_type rhsOffset) : basic_fixed_string(rhs, rhsOffset, npos)
{ // construct from rhs [rhsOffset, npos)
assign(rhs, rhsOffset, npos);
}
// #3
@@ -40,7 +39,15 @@ namespace AZStd
inline constexpr basic_fixed_string<Element, MaxElementCount, Traits>::basic_fixed_string(const basic_fixed_string& rhs,
size_type rhsOffset, size_type count)
{ // construct from rhs [rhsOffset, rhsOffset + count)
assign(rhs, rhsOffset, count);
AZSTD_CONTAINER_ASSERT(rhs.size() >= rhsOffset, "Invalid offset");
size_type num = AZStd::min(count, rhs.size() - rhsOffset);
// make room and assign new stuff
pointer data = m_buffer;
const_pointer rhsData = rhs.m_buffer;
Traits::copy(data, rhsData + rhsOffset, num);
m_size = static_cast<internal_size_type>(num);
Traits::assign(data[num], Element()); // terminate
}
// #4
@@ -68,15 +75,18 @@ namespace AZStd
// #7
template<class Element, size_t MaxElementCount, class Traits>
inline constexpr basic_fixed_string<Element, MaxElementCount, Traits>::basic_fixed_string(const basic_fixed_string& rhs)
: basic_fixed_string(rhs, size_type(0), npos)
{
assign(rhs, size_type(0), npos);
}
// #8
template<class Element, size_t MaxElementCount, class Traits>
inline constexpr basic_fixed_string<Element, MaxElementCount, Traits>::basic_fixed_string(basic_fixed_string&& rhs)
{
assign(AZStd::move(rhs));
Traits::copy(m_buffer, rhs.m_buffer, rhs.size() + 1);
m_size = rhs.m_size;
rhs.m_size = 0;
Traits::assign(rhs.m_buffer[0], Element{});
}
// #9
@@ -18,6 +18,8 @@
#include <AzCore/std/allocator.h>
#include <AzCore/std/allocator_traits.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/typetraits/alignment_of.h>
#include <AzCore/std/typetraits/is_convertible.h>
#include <AzCore/std/typetraits/is_integral.h>
#include <AzCore/std/string/string_view.h>
@@ -1483,11 +1485,11 @@ namespace AZStd
}
};
// Clang supports compile-time check for printf-like signatures
// Clang/GCC supports compile-time check for printf-like signatures
// On MSVC, *only* if /analyze flag is enabled(defines _PREFAST_) we can also do a compile-time check
// For not affecting final release binary size, we don't use the templated version on Release configuration either
#if AZ_COMPILER_CLANG || defined(_PREFAST_) || defined(_RELEASE)
# if AZ_COMPILER_CLANG
#if AZ_COMPILER_CLANG || AZ_COMPILER_GCC || defined(_PREFAST_) || defined(_RELEASE)
# if AZ_COMPILER_CLANG || AZ_COMPILER_GCC
# define FORMAT_FUNC __attribute__((format(printf, 1, 2)))
# define FORMAT_FUNC_ARG
# elif AZ_COMPILER_MSVC
@@ -308,34 +308,71 @@ namespace AZStd
}
static constexpr bool eq(char_type left, char_type right) noexcept { return left == right; }
static constexpr bool lt(char_type left, char_type right) noexcept { return left < right; }
static constexpr int compare(const char_type* s1, const char_type* s2, size_t count) noexcept
static constexpr int compare(const char_type* s1, const char_type* s2, size_t count) noexcept
{
// In GCC versions prior to major version 10, __builtin_memcmp fails in valid checks in constexpr evaluation
#if !defined(AZ_COMPILER_GCC) || AZ_COMPILER_GCC >= 100000
if constexpr (AZStd::is_same_v<char_type, char>)
{
return __builtin_memcmp(s1, s2, count);
}
else if constexpr (AZStd::is_same_v<char_type, wchar_t>)
{
return __builtin_wmemcmp(s1, s2, count);
} else
#endif
{
if (az_builtin_is_constant_evaluated())
{
for (; count; --count, ++s1, ++s2)
{
if (lt(*s1, *s2))
{
return -1;
}
else if (lt(*s2, *s1))
{
return 1;
}
}
return 0;
}
else
{
return ::memcmp(s1, s2, count * sizeof(char_type));
}
}
}
static constexpr size_t length(const char_type* s) noexcept
{
// For GCC versions less than 10, __builtin_strlen and __builtin_wcslen is not supported as const expressions
// so for that case it will need to manually count the characters (at compile time) instead
#if defined(AZ_COMPILER_GCC) && AZ_COMPILER_GCC < 100000
if constexpr (AZStd::is_same_v<char_type, char>)
{
return __builtin_memcmp(s1, s2, count);
if (!az_builtin_is_constant_evaluated())
{
return strlen(s);
}
}
else if constexpr (AZStd::is_same_v<char_type, wchar_t>)
{
return __builtin_wmemcmp(s1, s2, count);
}
else
{
for (; count; --count, ++s1, ++s2)
if (!az_builtin_is_constant_evaluated())
{
if (lt(*s1, *s2))
{
return -1;
}
else if (lt(*s2, *s1))
{
return 1;
}
return wcslen(s);
}
return 0;
}
}
static constexpr size_t length(const char_type* s) noexcept
{
size_t strLength{};
for (; *s; ++s, ++strLength)
{
;
}
return strLength;
#else
if constexpr (AZStd::is_same_v<char_type, char>)
{
return __builtin_strlen(s);
@@ -353,9 +390,39 @@ namespace AZStd
}
return strLength;
}
#endif // defined(AZ_COMPILER_GCC) && AZ_COMPILER_GCC < 100000
}
static constexpr const char_type* find(const char_type* s, size_t count, const char_type& ch) noexcept
{
// For GCC versions less than 10, __builtin_char_memchr and __builtin_wmemchr is not supported, and
// __builtin_memchr is not supported as const expressions. In those cases we will manually locate and
// return the pointer to 's' (at compile time)
#if defined(AZ_COMPILER_GCC) && AZ_COMPILER_GCC < 100000
if constexpr (AZStd::is_same_v<char_type, char>)
{
if (!az_builtin_is_constant_evaluated())
{
return static_cast<const char_type*>(__builtin_memchr(s, ch, count));
}
}
else if constexpr (AZStd::is_same_v<char_type, wchar_t>)
{
if (!az_builtin_is_constant_evaluated())
{
return wmemchr(s, ch, count);
}
}
for (; count; --count, ++s)
{
if (eq(*s, ch))
{
return s;
}
}
return nullptr;
#else
if constexpr (AZStd::is_same_v<char_type, char>)
{
return __builtin_char_memchr(s, ch, count);
@@ -363,7 +430,6 @@ namespace AZStd
else if constexpr (AZStd::is_same_v<char_type, wchar_t>)
{
return __builtin_wmemchr(s, ch, count);
}
else
{
@@ -376,6 +442,7 @@ namespace AZStd
}
return nullptr;
}
#endif
}
static constexpr char_type* move(char_type* dest, const char_type* src, size_t count) noexcept
{
@@ -438,8 +505,6 @@ namespace AZStd
}
static constexpr char_type* copy(char_type* dest, const char_type* src, size_t count) noexcept
{
AZ_Assert(dest != nullptr && src != nullptr, "Invalid input!");
#if az_has_builtin_memcpy
__builtin_memcpy(dest, src, count * sizeof(char_type));
#else
@@ -455,6 +520,7 @@ namespace AZStd
}
else
{
AZ_Assert(dest1 != nullptr && src1 != nullptr, "Invalid input!");
::memcpy(dest1, src1, count1 * sizeof(char_type));
}
return dest1;
@@ -7,6 +7,7 @@
*/
#pragma once
#include <AzCore/std/typetraits/typetraits.h>
#include <AzCore/std/typetraits/conditional.h>
#include <AzCore/std/typetraits/integral_constant.h> // for true_type
@@ -58,14 +58,13 @@
# define AZSTD_IS_ABSTRACT(T) __is_abstract(T)
# define AZSTD_IS_BASE_OF(T, U) (__is_base_of(T, U) && !is_same<T, U>::value)
# define AZSTD_IS_CLASS(T) __is_class(T)
// This one doesn't quite always do the right thing:
# define AZSTD_IS_CONVERTIBLE(_From, _To) __is_convertible_to(_From, _To)
# define AZSTD_IS_ENUM(T) __is_enum(T)
// This one doesn't quite always do the right thing:
# define AZSTD_IS_CONVERTIBLE(_From, _To) __is_convertible_to(_From, _To)
// # define AZSTD_IS_POLYMORPHIC(T) __is_polymorphic(T)
#endif
#if defined(AZ_COMPILER_CLANG)
#if defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC)
# include <AzCore/std/typetraits/is_same.h>
# include <AzCore/std/typetraits/is_reference.h>
# include <AzCore/std/typetraits/is_volatile.h>
@@ -86,8 +85,8 @@
# define AZSTD_IS_ABSTRACT(T) __is_abstract(T)
# define AZSTD_IS_BASE_OF(T, U) (__is_base_of(T, U) && !is_same<T, U>::value)
# define AZSTD_IS_CLASS(T) __is_class(T)
# define AZSTD_IS_CONVERTIBLE(_From, _To) __is_convertible_to(_From, _To)
# define AZSTD_IS_ENUM(T) __is_enum(T)
# define AZSTD_IS_CONVERTIBLE(_From, _To) AZStd::is_convertible_v<_From, _To>
# define AZSTD_IS_POLYMORPHIC(T) __is_polymorphic(T)
#endif
+64
View File
@@ -0,0 +1,64 @@
/*
* 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
// Variadic MACROS util functions
/**
* AZ_VA_NUM_ARGS
* counts number of parameters (up to 10).
* example. AZ_VA_NUM_ARGS(x,y,z) -> expands to 3
*/
#ifndef AZ_VA_NUM_ARGS
# define AZ_VA_HAS_ARGS(...) ""#__VA_ARGS__[0] != 0
// we add the zero to avoid the case when we require at least 1 param at the end...
# define AZ_VA_NUM_ARGS(...) AZ_VA_NUM_ARGS_IMPL_((__VA_ARGS__, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
# define AZ_VA_NUM_ARGS_IMPL_(tuple) AZ_VA_NUM_ARGS_IMPL tuple
# define AZ_VA_NUM_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, N, ...) N
// Expands a macro and calls a different macro based on the number of arguments.
//
// Example: We need to specialize a macro for 1 and 2 arguments
// #define AZ_MY_MACRO(...) AZ_MACRO_SPECIALIZE(AZ_MY_MACRO_,AZ_VA_NUM_ARGS(__VA_ARGS__),(__VA_ARGS__))
//
// #define AZ_MY_MACRO_1(_1) /* code for 1 param */
// #define AZ_MY_MACRO_2(_1,_2) /* code for 2 params */
// ... etc.
//
//
// We have 3 levels of macro expansion...
# define AZ_MACRO_SPECIALIZE_II(MACRO_NAME, NPARAMS, PARAMS) MACRO_NAME##NPARAMS PARAMS
# define AZ_MACRO_SPECIALIZE_I(MACRO_NAME, NPARAMS, PARAMS) AZ_MACRO_SPECIALIZE_II(MACRO_NAME, NPARAMS, PARAMS)
# define AZ_MACRO_SPECIALIZE(MACRO_NAME, NPARAMS, PARAMS) AZ_MACRO_SPECIALIZE_I(MACRO_NAME, NPARAMS, PARAMS)
#endif // AZ_VA_NUM_ARGS
// Out of all supported compilers, mwerks is the only one
// that requires variadic macros to have at least 1 param.
// This is a pain they we use macros to call functions (with no params).
// we implement functions for up to 10 params
#define AZ_FUNCTION_CALL_1(_1) _1()
#define AZ_FUNCTION_CALL_2(_1, _2) _1(_2)
#define AZ_FUNCTION_CALL_3(_1, _2, _3) _1(_2, _3)
#define AZ_FUNCTION_CALL_4(_1, _2, _3, _4) _1(_2, _3, _4)
#define AZ_FUNCTION_CALL_5(_1, _2, _3, _4, _5) _1(_2, _3, _4, _5)
#define AZ_FUNCTION_CALL_6(_1, _2, _3, _4, _5, _6) _1(_2, _3, _4, _5, _6)
#define AZ_FUNCTION_CALL_7(_1, _2, _3, _4, _5, _6, _7) _1(_2, _3, _4, _5, _6, _7)
#define AZ_FUNCTION_CALL_8(_1, _2, _3, _4, _5, _6, _7, _8) _1(_2, _3, _4, _5, _6, _7, _8)
#define AZ_FUNCTION_CALL_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) _1(_2, _3, _4, _5, _6, _7, _8, _9)
#define AZ_FUNCTION_CALL_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) _1(_2, _3, _4, _5, _6, _7, _8, _9, _10)
// We require at least 1 param FunctionName
#define AZ_FUNCTION_CALL(...) AZ_MACRO_SPECIALIZE(AZ_FUNCTION_CALL_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
// Based on boost macro expansion fix...
#define AZ_PREVENT_MACRO_SUBSTITUTION
@@ -23,7 +23,7 @@ namespace AZ
public:
virtual SystemInformation GetSystemInformation() override
{
SystemInformation result;
SystemInformation result {0, 0};
return result;
}
@@ -16,6 +16,7 @@ set(LY_BUILD_DEPENDENCIES
PRIVATE
pthread
3rdParty::unwind
dl
atomic
PUBLIC
${CMAKE_DL_LIBS}
)
+27 -27
View File
@@ -19,6 +19,7 @@
#include <AzCore/std/string/regex.h>
#include <AzCore/std/string/wildcard.h>
#include <AzCore/std/string/fixed_string.h>
#include <AzCore/std/typetraits/is_convertible.h>
// we need this for AZ_TEST_FLOAT compare
#include <cinttypes>
@@ -1458,34 +1459,33 @@ namespace UnitTest
using ValidFormatArg = AZStd::string::_Format_Internal::ValidFormatArg;
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v1), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v2), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v3), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v4), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v5), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v6), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v7), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v8), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v9), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v10), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v11), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v12), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v13), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v14), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v15), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v16), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v17), ValidFormatArg), "Should be valid format argument");
static_assert(AZSTD_IS_CONVERTIBLE(decltype(v18), ValidFormatArg), "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v1), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v2), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v3), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v4), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v5), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v7), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v8), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v9), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v10), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v11), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v12), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v13), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v14), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v15), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v16), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v17), ValidFormatArg>, "Should be valid format argument");
static_assert(AZStd::is_convertible_v<decltype(v18), ValidFormatArg>, "Should be valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(AZStd::string, ValidFormatArg), "AZStd::string shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(std::string, ValidFormatArg), "std::string shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(AZStd::wstring, ValidFormatArg), "AZStd::wstring shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(std::wstring, ValidFormatArg), "std::wstring shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(WrappedInt, ValidFormatArg), "WrappedInt shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(AZStd::string_view, ValidFormatArg), "AZStd::string_view shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(AZStd::wstring_view, ValidFormatArg), "AZStd::wstring_view shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(std::string_view, ValidFormatArg), "string_view shouldn't be a valid format argument");
static_assert(!AZSTD_IS_CONVERTIBLE(std::wstring_view, ValidFormatArg), "wstring_view shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<AZStd::string, ValidFormatArg>, "AZStd::string shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<std::string, ValidFormatArg>, "std::string shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<AZStd::wstring, ValidFormatArg>, "AZStd::wstring shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<std::wstring, ValidFormatArg>, "std::wstring shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<WrappedInt, ValidFormatArg>, "WrappedInt shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<AZStd::string_view, ValidFormatArg>, "AZStd::string_view shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<AZStd::wstring_view, ValidFormatArg>, "AZStd::wstring_view shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<std::string_view, ValidFormatArg>, "string_view shouldn't be a valid format argument");
static_assert(!AZStd::is_convertible_v<std::wstring_view, ValidFormatArg>, "wstring_view shouldn't be a valid format argument");
}
TEST_F(String, StringViewPrintf)
+15 -15
View File
@@ -373,8 +373,8 @@ namespace UnitTest
: public AllocatorsFixture
{
public:
using Handler = Handler<Bus>;
using MultiHandlerById = MultiHandlerById<Bus>;
using BusHandler = Handler<Bus>;
using BusMultiHandlerById = MultiHandlerById<Bus>;
EBusTestAll()
{
@@ -402,7 +402,7 @@ namespace UnitTest
{
for (int handler = 0; handler < numHandlersPerAddress; ++handler)
{
m_handlers[address].emplace_back(aznew Handler(address, connectOnConstruct));
m_handlers[address].emplace_back(aznew BusHandler(address, connectOnConstruct));
++m_numHandlers;
}
}
@@ -429,7 +429,7 @@ namespace UnitTest
{
for (const auto& handlerPair : m_handlers)
{
for (Handler* handler : handlerPair.second)
for (BusHandler* handler : handlerPair.second)
{
delete handler;
}
@@ -452,7 +452,7 @@ namespace UnitTest
if (AddressesAreOrdered())
{
// Collect the first handler from each address
using PairType = AZStd::pair<int, Handler*>;
using PairType = AZStd::pair<int, BusHandler*>;
AZStd::vector<PairType> sortedHandlers;
for (const auto& handlerPair : m_handlers)
{
@@ -495,7 +495,7 @@ namespace UnitTest
{
auto& handlers = m_handlers[id];
for (Handler* handler : handlers)
for (BusHandler* handler : handlers)
{
EXPECT_EQ(expected, handler->m_eventCalls);
}
@@ -505,11 +505,11 @@ namespace UnitTest
{
// Sort the handlers the same way we expect the bus to sort them
auto sortedHandlers = handlers;
AZStd::sort(sortedHandlers.begin(), sortedHandlers.end(), AZStd::bind(&Handler::Compare, AZStd::placeholders::_1, AZStd::placeholders::_2));
AZStd::sort(sortedHandlers.begin(), sortedHandlers.end(), AZStd::bind(&BusHandler::Compare, AZStd::placeholders::_1, AZStd::placeholders::_2));
// Iterate over the list, and validate that they were called in the correct order
unsigned int lastExecuted = 0;
for (const Handler* handler : sortedHandlers)
for (const BusHandler* handler : sortedHandlers)
{
if (lastExecuted > 0)
{
@@ -550,7 +550,7 @@ namespace UnitTest
}
protected:
AZStd::unordered_map<int, AZStd::vector<Handler*>> m_handlers;
AZStd::unordered_map<int, AZStd::vector<BusHandler*>> m_handlers;
int m_numHandlers = 0;
};
TYPED_TEST_CASE(EBusTestAll, BusTypesAll);
@@ -578,7 +578,7 @@ namespace UnitTest
TYPED_TEST(EBusTestAll, ConnectDisconnect)
{
using Bus = TypeParam;
using Handler = typename EBusTestAll<Bus>::Handler;
using Handler = typename EBusTestAll<Bus>::BusHandler;
constexpr bool connectOnConstruct{ true };
Handler meh(0, connectOnConstruct);
@@ -602,13 +602,13 @@ namespace UnitTest
TYPED_TEST(EBusTestIdMultiHandlers, EnumerateHandlers_MultiHandler)
{
using Bus = TypeParam;
using MultiHandlerById = typename EBusTestAll<Bus>::MultiHandlerById;
using BusMultiHandlerById = typename EBusTestAll<Bus>::BusMultiHandlerById;
MultiHandlerById sourceMultiHandler{ 0, 1, 2 };
MultiHandlerById multiHandlerWithOverlappingIds{ 1, 3, 5 };
BusMultiHandlerById sourceMultiHandler{ 0, 1, 2 };
BusMultiHandlerById multiHandlerWithOverlappingIds{ 1, 3, 5 };
// Test handlers' enumeration functionality
Bus::EnumerateHandlers([](typename MultiHandlerById::Interface* interfaceInst) -> bool
Bus::EnumerateHandlers([](typename BusMultiHandlerById::Interface* interfaceInst) -> bool
{
interfaceInst->OnEvent();
return true;
@@ -618,7 +618,7 @@ namespace UnitTest
TYPED_TEST(EBusTestId, FindFirstHandler)
{
using Bus = TypeParam;
using Handler = typename EBusTestAll<Bus>::Handler;
using Handler = typename EBusTestAll<Bus>::BusHandler;
constexpr bool connectOnConstruct{ true };
Handler meh0(0, connectOnConstruct); /// <-- Bind to bus 0
Handler meh1(1, connectOnConstruct); /// <-- Bind to bus 1
+11 -6
View File
@@ -4014,9 +4014,12 @@ TEST_F(SerializeBasicTest, BasicTypeTest_Succeed)
};
}
} // namespace UnitTest
AZ_TYPE_INFO_SPECIALIZE(UnitTest::EditTest::MyEditStruct3::EditEnum, "{4AF433C2-055E-4E34-921A-A7D16AB548CA}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::EditTest::MyEditStruct3::EditEnumClass, "{4FEC2F0B-A599-4FCD-836B-89E066791793}");
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(UnitTest::EditTest::MyEditStruct3::EditEnum, "{4AF433C2-055E-4E34-921A-A7D16AB548CA}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::EditTest::MyEditStruct3::EditEnumClass, "{4FEC2F0B-A599-4FCD-836B-89E066791793}");
}
namespace UnitTest
{
@@ -7798,10 +7801,12 @@ namespace UnitTest
};
}
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestUnscopedSerializationEnum, "{83383BFA-F6DA-4124-BE4F-2FAAB7C594E7}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestScopedSerializationEnum, "{17341C5E-81C3-44CB-A40D-F97D49C2531D}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestUnsignedEnum, "{0F91A5AE-DADA-4455-B158-8DB79D277495}");
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestUnscopedSerializationEnum, "{83383BFA-F6DA-4124-BE4F-2FAAB7C594E7}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestScopedSerializationEnum, "{17341C5E-81C3-44CB-A40D-F97D49C2531D}");
AZ_TYPE_INFO_SPECIALIZE(UnitTest::TestUnsignedEnum, "{0F91A5AE-DADA-4455-B158-8DB79D277495}");
}
namespace UnitTest
{