Remove MCore::Array

This translates all usages of MCore::Array to AZStd::vector. It is
designed to be as minimal of a change as possible (no changing to
range-for loops or other C++11 stuff).

We can decide to submit this wholesale, or submit it to a separate
branch that we can then integrate individual files from once we're ready
to do a specific class's transition.

It does not completely solve the `uint32`->`size_t` transition.

One important finding from doing this: `MCore::Array` uses a `memcpy`
when it reallocates. `AZStd::vector` will use the contained type's copy
or move constructor, per element. This is a significant change in
behavior. If you have type, `SomeStruct` that defines a destructor, that
type is copyable and not movable. So if you have a
`MCore::Array<SomeStruct>`, and you call `Add(); Add(); Add()`, that
reallocates 3 times, copying the contents using `memcpy`, and never
invokes `SomeStruct`'s copy constructor or destructor. Translating that
to `AZStd::vector<SomeStruct>` and calling `push_back(); push_back();
push_back();` will still reallocate 3 times, but it sees that
`SomeStruct` is non-movable, and uses the copy constructor to make the
copies, and then the destructor on the previous values. This call to the
destructor wasn't there before, and can cause things to be deleted that
weren't before. The solution to this is to make that struct be a
move-only type. Where possible, this was done by changing that type to
use `AZStd::unique_ptr` instead of a raw pointer, to get the proper move
behavior. Where that is not possible (types that inherit from
`MCore::MemoryObject`), a hand-written move constructor was created.

In general:
GetLength() becomes size()
GetMaxLength() becomes capacity()
GetIsEmpty() becomes empty()
Reserve() becomes reserve()
ReserveExact() becomes reserve()
Resize() becomes resize()
ResizeFast() becomes resize_no_construct()
Add() becomes emplace_back()
AddExact() becomes emplace_back()
AddEmpty() becomes emplace_back()
AddEmptyExact() becomes emplace_back()
GetPtr() becomes data()
GetItem() becomes at()
Shrink() becomes shrink_to_fit()
GetFirst() becomes front()
GetLast() becomes back()
Remove() becomes erase()
RemoveFirst() becomes erase()
RemoveLast() becomes pop_back()
RemoveByValue() becomes if (const auto it = AZStd::find(...); it != end(container)) container.erase(it);
Insert() becomes emplace()
Swap() becomes swap()
Clear(true) becomes clear(); shrink_to_fit()
Clear() becomes clear(); shrink_to_fit()
Clear(false) becomes clear()
Swap() becomes swap()
Find() becomes AZStd::find
MoveElements() becomes AZStd::move
SetMemoryCategory() is removed

Signed-off-by: Chris Burel <burelc@amazon.com>
This commit is contained in:
Chris Burel
2021-05-24 12:03:11 -07:00
parent 211432fe5f
commit 8884227fe6
189 changed files with 1489 additions and 3798 deletions
+25 -43
View File
@@ -10,8 +10,6 @@
#include <AzCore/PlatformIncl.h>
#include "LogManager.h"
#include <iostream>
namespace MCore
{
// static mutex
@@ -60,8 +58,6 @@ namespace MCore
// constructor
LogManager::LogManager()
{
mLogCallbacks.SetMemoryCategory(MCORE_MEMCATEGORY_LOGMANAGER);
// initialize the enabled log levels
InitLogLevels();
}
@@ -82,7 +78,7 @@ namespace MCore
LockGuard lock(mMutex);
// add the callback to the stack
mLogCallbacks.Add(callback);
mLogCallbacks.emplace_back(callback);
// collect the enabled log levels
InitLogLevels();
@@ -90,16 +86,16 @@ namespace MCore
// remove a specific log callback from the stack
void LogManager::RemoveLogCallback(uint32 index)
void LogManager::RemoveLogCallback(size_t index)
{
MCORE_ASSERT(mLogCallbacks.GetIsValidIndex(index));
MCORE_ASSERT(index < mLogCallbacks.size());
LockGuard lock(mMutex);
// delete it from memory
delete mLogCallbacks[index];
// remove the callback from the stack
mLogCallbacks.Remove(index);
mLogCallbacks.erase(AZStd::next(begin(mLogCallbacks), index));
// collect the enabled log levels
InitLogLevels();
@@ -110,25 +106,16 @@ namespace MCore
{
LockGuard lock(mMutex);
// iterate through all log callbacks
for (uint32 i = 0; i < mLogCallbacks.GetLength(); )
// Put all the callbacks of the type to be removed at the end of the vector
mLogCallbacks.erase(AZStd::remove_if(begin(mLogCallbacks), end(mLogCallbacks), [type](const LogCallback* callback)
{
LogCallback* callback = mLogCallbacks[i];
// check if we are dealing with a log file
if (callback->GetType() == type)
{
// get rid of the callback instance
delete callback;
// remove the callback from the stack
mLogCallbacks.Remove(i);
return true;
}
else
{
i++;
}
}
return false;
}));
// collect the enabled log levels
InitLogLevels();
@@ -141,13 +128,12 @@ namespace MCore
LockGuard lock(mMutex);
// get rid of the callbacks
const uint32 num = mLogCallbacks.GetLength();
for (uint32 i = 0; i < num; ++i)
for (auto* logCallback : mLogCallbacks)
{
delete mLogCallbacks[i];
delete logCallback;
}
mLogCallbacks.Clear(true);
mLogCallbacks.clear();
// collect the enabled log levels
InitLogLevels();
@@ -155,15 +141,15 @@ namespace MCore
// retrieve a pointer to the given log callback
LogCallback* LogManager::GetLogCallback(uint32 index)
LogCallback* LogManager::GetLogCallback(size_t index)
{
return mLogCallbacks[index];
}
// return number of log callbacks in the stack
uint32 LogManager::GetNumLogCallbacks() const
size_t LogManager::GetNumLogCallbacks() const
{
return mLogCallbacks.GetLength();
return mLogCallbacks.size();
}
// collect all enabled log levels
@@ -173,10 +159,9 @@ namespace MCore
int32 logLevels = LogCallback::LOGLEVEL_NONE;
// enable all log levels that are enabled by any of the callbacks
const uint32 num = mLogCallbacks.GetLength();
for (uint32 i = 0; i < num; ++i)
for (auto* logCallback : mLogCallbacks)
{
logLevels |= (int32)mLogCallbacks[i]->GetLogLevels();
logLevels |= (int32)logCallback->GetLogLevels();
}
mLogLevels = (LogCallback::ELogLevel)logLevels;
@@ -187,10 +172,9 @@ namespace MCore
void LogManager::SetLogLevels(LogCallback::ELogLevel logLevels)
{
// iterate through all log callbacks and set it to the given log levels
const uint32 num = mLogCallbacks.GetLength();
for (uint32 i = 0; i < num; ++i)
for (auto* logCallback : mLogCallbacks)
{
mLogCallbacks[i]->SetLogLevels(logLevels);
logCallback->SetLogLevels(logLevels);
}
// force set the log manager's log levels to the given one as well
@@ -204,23 +188,21 @@ namespace MCore
LockGuard lock(mMutex);
// iterate through all callbacks
const uint32 num = mLogCallbacks.GetLength();
for (uint32 i = 0; i < num; ++i)
for (auto* logCallback : mLogCallbacks)
{
if (mLogCallbacks[i]->GetLogLevels() & logLevel)
if (logCallback->GetLogLevels() & logLevel)
{
mLogCallbacks[i]->Log(message, logLevel);
logCallback->Log(message, logLevel);
}
}
}
// find the index of a given callback
uint32 LogManager::FindLogCallback(LogCallback* callback) const
size_t LogManager::FindLogCallback(LogCallback* callback) const
{
// iterate through all callbacks
const uint32 num = mLogCallbacks.GetLength();
for (uint32 i = 0; i < num; ++i)
for (size_t i = 0; i < mLogCallbacks.size(); ++i)
{
if (mLogCallbacks[i] == callback)
{
@@ -228,7 +210,7 @@ namespace MCore
}
}
return MCORE_INVALIDINDEX32;
return InvalidIndex;
}