511 lines
9.2 KiB
C++
511 lines
9.2 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: auContainerUtils.hpp
|
|
Date: 2022-2-1
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
template<typename T, bool all>
|
|
static bool _AuRemoveIfBase(T &in, const AuPredicate<const AuToValueType_t<T> &> &predicate);
|
|
|
|
template<typename T>
|
|
static bool AuRemoveAllIf(T &in, const AuPredicate<const AuToValueType_t<T> &> &predicate)
|
|
{
|
|
return _AuRemoveIfBase<T, true>(in, predicate);
|
|
}
|
|
|
|
template<typename T>
|
|
static bool AuRemoveIf(T &in, const AuPredicate<const AuToValueType_t<T> &> &predicate)
|
|
{
|
|
return _AuRemoveIfBase<T, false>(in, predicate);
|
|
}
|
|
|
|
template<typename T, typename Z>
|
|
static bool AuTryRemove(T &in, const Z &type)
|
|
{
|
|
try
|
|
{
|
|
auto itr = in.find(type);
|
|
if (itr == in.end())
|
|
{
|
|
return false;
|
|
}
|
|
in.erase(itr);
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename T, typename Z>
|
|
static void AuRemove(T &in, const Z &type)
|
|
{
|
|
auto itr = in.find(type);
|
|
if (itr == in.end())
|
|
{
|
|
return;
|
|
}
|
|
in.erase(itr);
|
|
}
|
|
|
|
template<typename T>
|
|
static void AuRemoveRange(T &in, AuUInt index, AuUInt length)
|
|
{
|
|
if (index + length > in.size())
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto begin = in.begin();
|
|
std::advance(begin, index);
|
|
|
|
auto end = begin;
|
|
|
|
std::advance(end, length);
|
|
|
|
while (begin != end)
|
|
{
|
|
in.erase(begin++);
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
static bool AuTryRemoveRange(T &in, AuUInt index, AuUInt length)
|
|
{
|
|
try
|
|
{
|
|
if (index + length > in.size())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
auto begin = in.begin();
|
|
auto end = begin;
|
|
|
|
std::advance(end, index + length);
|
|
|
|
while (begin != end)
|
|
{
|
|
in.erase(begin++);
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template<typename Map, class Key, typename Value>
|
|
static auline bool AuTryFind(Map &map, const Key &key, Value *&ptr)
|
|
{
|
|
auto itr = map.find(key);
|
|
if (itr != map.end())
|
|
{
|
|
ptr = &itr->second;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
ptr = nullptr;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Map, class Key, typename Value>
|
|
static auline bool AuTryFind(Map *map, const Key &key, Value *&ptr)
|
|
{
|
|
auto itr = map->find(key);
|
|
if (itr != map->end())
|
|
{
|
|
ptr = &itr->second;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
ptr = nullptr;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Map, class Key>
|
|
static auline bool AuTryFind(Map &map, const Key &key)
|
|
{
|
|
auto itr = map.find(key);
|
|
if (itr != map.end())
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<AuUInt N, typename List, class Key>
|
|
static auline auto AuTryFindByTupleN(List &list, const Key &key)
|
|
{
|
|
for (auto itr = list.begin(); itr != list.end(); )
|
|
{
|
|
if (AuGet<N>(*itr) == key)
|
|
{
|
|
return itr;
|
|
}
|
|
else
|
|
{
|
|
itr++;
|
|
}
|
|
}
|
|
return list.end();
|
|
}
|
|
|
|
template<typename Range, class Key>
|
|
static auline bool AuExists(Range &a, const Key &item)
|
|
{
|
|
return std::find(a.begin(), a.end(), item) != a.end();
|
|
}
|
|
|
|
template<typename Map, class Key>
|
|
static auline bool AuTryFind(Map *map, const Key &key)
|
|
{
|
|
auto itr = map->find(key);
|
|
if (itr != map->end())
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Map, class Key, typename Value>
|
|
static auline bool AuTryFindGeneric(Map &map, const Key &key, Value *&ptr)
|
|
{
|
|
auto itr = map.find(key);
|
|
if (itr != map.end())
|
|
{
|
|
ptr = &*itr;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
ptr = nullptr;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Map, class Key>
|
|
static auline bool AuTryFindGeneric(Map &map, const Key &key)
|
|
{
|
|
if (map.find(key) != map.end())
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Container>
|
|
static auline bool AuTryClear(Container &container)
|
|
{
|
|
container.clear(); // clears are generally noexcept.
|
|
return true;
|
|
}
|
|
|
|
template<typename Map, class Key>
|
|
static auline bool AuTryDelete(Map &map, const Key &key)
|
|
{
|
|
auto itr = map.find(key);
|
|
if (itr != map.end())
|
|
{
|
|
map.erase(itr);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// @deprecated -> Should've been named AuTryRemoveList
|
|
template<typename List, class Key>
|
|
static auline bool AuTryDeleteList(List &list, const Key &key)
|
|
{
|
|
auto itr = std::find(list.begin(), list.end(), key);
|
|
if (itr != list.end())
|
|
{
|
|
list.erase(itr);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename List, class Key>
|
|
static auline bool AuTryRemoveList(List &list, const Key &key)
|
|
{
|
|
auto itr = std::find(list.begin(), list.end(), key);
|
|
if (itr != list.end())
|
|
{
|
|
list.erase(itr);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<AuUInt N, typename List, class Key>
|
|
static auline bool AuTryRemoveByTupleN(List &list, const Key &key)
|
|
{
|
|
for (auto itr = list.begin(); itr != list.end(); )
|
|
{
|
|
if (AuGet<N>(*itr) == key)
|
|
{
|
|
itr = list.erase(itr);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
itr++;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#include <auROXTL/auTupleUtils.hpp>
|
|
|
|
template<typename Container, typename Key_t, typename Type_t>
|
|
static auline bool AuTryInsert(Container &container, const Key_t &key, Type_t &&value)
|
|
{
|
|
try
|
|
{
|
|
auto itr = container.find(key);
|
|
if (itr == container.end())
|
|
{
|
|
container.insert(AuMakePair(key, value));
|
|
}
|
|
else
|
|
{
|
|
itr->second = value;
|
|
}
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Container, typename Type>
|
|
static auline bool AuTryInsert(Container &container, const Type &value)
|
|
{
|
|
try
|
|
{
|
|
container.insert(container.end(), value);
|
|
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
template<typename Container, typename Type>
|
|
static auline bool AuTryInsert(Container &container, Type &&value)
|
|
{
|
|
try
|
|
{
|
|
container.insert(container.end(), value);
|
|
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Container, typename Type>
|
|
static auline bool AuTryInsert(Container *container, const Type &value)
|
|
{
|
|
try
|
|
{
|
|
container->insert(container->end(), value);
|
|
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Container, typename Type>
|
|
static auline bool AuTryInsert(Container *container, Type &&value)
|
|
{
|
|
try
|
|
{
|
|
container->insert(container->end(), value);
|
|
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Container, typename Type>
|
|
static auline bool AuTryInsertNoEnd(Container &container, Type &&value) // move
|
|
{
|
|
try
|
|
{
|
|
container.insert(value);
|
|
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Container, typename Type>
|
|
static auline bool AuTryInsertNoEnd(Container &container, const Type &value) // copy
|
|
{
|
|
try
|
|
{
|
|
container.insert(value);
|
|
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Container, typename Type>
|
|
static auline bool AuTryInsertNoEnd(Container *container, Type &&value) // move
|
|
{
|
|
try
|
|
{
|
|
container->insert(value);
|
|
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename Container, typename Type>
|
|
static auline bool AuTryInsertNoEnd(Container *container, const Type &value) // copy
|
|
{
|
|
try
|
|
{
|
|
container->insert(value);
|
|
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
namespace Aurora::Memory
|
|
{
|
|
struct ByteBuffer;
|
|
}
|
|
|
|
template<typename T>
|
|
static auline bool AuTryResize(T &list, AuUInt length)
|
|
{
|
|
try
|
|
{
|
|
if constexpr (AuIsSame_v<T, Aurora::Memory::ByteBuffer>)
|
|
{
|
|
return list.Resize(length);
|
|
}
|
|
else
|
|
{
|
|
list.resize(length);
|
|
return true;
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
static auline bool AuTryDownsize(T &list, AuUInt length)
|
|
{
|
|
try
|
|
{
|
|
if constexpr (AuIsSame_v<T, Aurora::Memory::ByteBuffer>)
|
|
{
|
|
if (!list.Resize(length))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
list.GC();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
list.resize(length);
|
|
list.shrink_to_fit();
|
|
return true;
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename T, bool all>
|
|
static bool _AuRemoveIfBase(T &in, const AuPredicate<const AuToValueType_t<T> &> &predicate)
|
|
{
|
|
bool retOne {};
|
|
|
|
for (auto itr = in.begin(); itr != in.end(); )
|
|
{
|
|
if (predicate(*itr))
|
|
{
|
|
itr = in.erase(itr);
|
|
if constexpr (!all)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
retOne = true;
|
|
}
|
|
else
|
|
{
|
|
itr++;
|
|
}
|
|
}
|
|
|
|
// optimization hint
|
|
if constexpr (all) return retOne;
|
|
return {};
|
|
} |