mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Remove extra containers.
They must be implemented without binding library for them to compete in terms of performance.
This commit is contained in:
parent
f661d13d24
commit
0ed82f66e1
@ -86,8 +86,6 @@ add_library(SqModule MODULE SqBase.hpp Main.cpp
|
|||||||
Library/System/Path.cpp Library/System/Path.hpp
|
Library/System/Path.cpp Library/System/Path.hpp
|
||||||
Library/Utils.cpp Library/Utils.hpp
|
Library/Utils.cpp Library/Utils.hpp
|
||||||
Library/Utils/Announce.cpp Library/Utils/Announce.hpp
|
Library/Utils/Announce.cpp Library/Utils/Announce.hpp
|
||||||
Library/Utils/Dictionary.cpp Library/Utils/Dictionary.hpp
|
|
||||||
Library/Utils/Map.cpp Library/Utils/Map.hpp
|
|
||||||
Library/Utils/String.cpp Library/Utils/String.hpp
|
Library/Utils/String.cpp Library/Utils/String.hpp
|
||||||
Library/Utils/Vector.cpp Library/Utils/Vector.hpp
|
Library/Utils/Vector.cpp Library/Utils/Vector.hpp
|
||||||
Library/XML.cpp Library/XML.hpp
|
Library/XML.cpp Library/XML.hpp
|
||||||
|
@ -83,9 +83,7 @@ static SQInteger SqExtractIPv4(HSQUIRRELVM vm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
extern void Register_Map(HSQUIRRELVM vm, Table & ns);
|
|
||||||
extern void Register_Vector(HSQUIRRELVM vm, Table & ns);
|
extern void Register_Vector(HSQUIRRELVM vm, Table & ns);
|
||||||
extern void Register_Dictionary(HSQUIRRELVM vm, Table & ns);
|
|
||||||
extern void Register_Native_String(HSQUIRRELVM vm, Table & ns);
|
extern void Register_Native_String(HSQUIRRELVM vm, Table & ns);
|
||||||
extern void Register_ServerAnnouncer(HSQUIRRELVM vm, Table & ns);
|
extern void Register_ServerAnnouncer(HSQUIRRELVM vm, Table & ns);
|
||||||
|
|
||||||
@ -94,9 +92,7 @@ void Register_Utils(HSQUIRRELVM vm)
|
|||||||
{
|
{
|
||||||
Table ns(vm);
|
Table ns(vm);
|
||||||
|
|
||||||
Register_Map(vm, ns);
|
|
||||||
Register_Vector(vm, ns);
|
Register_Vector(vm, ns);
|
||||||
Register_Dictionary(vm, ns);
|
|
||||||
Register_Native_String(vm, ns);
|
Register_Native_String(vm, ns);
|
||||||
Register_ServerAnnouncer(vm, ns);
|
Register_ServerAnnouncer(vm, ns);
|
||||||
|
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
#include "Library/Utils/Dictionary.hpp"
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
namespace SqMod {
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
SQMOD_DECL_TYPENAME(SqDictionaryTn, _SC("SqDictionary"))
|
|
||||||
|
|
||||||
// ================================================================================================
|
|
||||||
void Register_Dictionary(HSQUIRRELVM vm, Table & ns)
|
|
||||||
{
|
|
||||||
ns.Bind(_SC("Dictionary"),
|
|
||||||
Class< SqDictionary >(vm, SqDictionaryTn::Str)
|
|
||||||
// Constructors
|
|
||||||
.Ctor()
|
|
||||||
.Ctor< SQInteger >()
|
|
||||||
// Meta-methods
|
|
||||||
.SquirrelFunc(_SC("_typename"), &SqDictionaryTn::Fn)
|
|
||||||
// Properties
|
|
||||||
.Prop(_SC("Empty"), &SqDictionary::Empty)
|
|
||||||
.Prop(_SC("Size"), &SqDictionary::Size)
|
|
||||||
// Member Methods
|
|
||||||
.Func(_SC("Get"), &SqDictionary::Get)
|
|
||||||
.Func(_SC("GetOr"), &SqDictionary::GetOr)
|
|
||||||
.Func(_SC("Set"), &SqDictionary::Set)
|
|
||||||
.Func(_SC("SetOr"), &SqDictionary::SetOr)
|
|
||||||
.Func(_SC("Update"), &SqDictionary::Update)
|
|
||||||
.Func(_SC("Create"), &SqDictionary::Create)
|
|
||||||
.Func(_SC("Clear"), &SqDictionary::Clear)
|
|
||||||
.Func(_SC("Erase"), &SqDictionary::Erase)
|
|
||||||
.Func(_SC("Contains"), &SqDictionary::Contains)
|
|
||||||
.CbFunc(_SC("Each"), &SqDictionary::Each)
|
|
||||||
.CbFunc(_SC("EachWith"), &SqDictionary::EachWith)
|
|
||||||
.CbFunc(_SC("While"), &SqDictionary::While)
|
|
||||||
.CbFunc(_SC("WhileWith"), &SqDictionary::WhileWith)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Namespace:: SqMod
|
|
@ -1,373 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
#include "Core/Utility.hpp"
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
#include <vector>
|
|
||||||
#include <random>
|
|
||||||
#include <iterator>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
namespace Sqrat {
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* Helper type used to retrieve the hash of a value instead of the value itself.
|
|
||||||
*/
|
|
||||||
struct SqKeyHash
|
|
||||||
{
|
|
||||||
SQHash mH{};
|
|
||||||
constexpr SqKeyHash() noexcept = default;
|
|
||||||
constexpr explicit SqKeyHash(SQHash h) noexcept : mH(h) { }
|
|
||||||
constexpr SqKeyHash(const SqKeyHash &) noexcept = default;
|
|
||||||
constexpr SqKeyHash & operator = (const SqKeyHash &) noexcept = default;
|
|
||||||
constexpr operator SQHash () const noexcept { return mH; } //NOLINT (explicit)
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* Allows the binding system to know how to interact with SqKeyHash type.
|
|
||||||
*/
|
|
||||||
template < > struct Var< SqKeyHash > {
|
|
||||||
|
|
||||||
SqKeyHash value;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Base constructor.
|
|
||||||
*/
|
|
||||||
Var(HSQUIRRELVM vm, SQInteger idx) noexcept : value(sq_gethash(vm, idx)) { }
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Push the associated object on the stack.
|
|
||||||
*/
|
|
||||||
static void push(HSQUIRRELVM vm, const SqKeyHash& value)
|
|
||||||
{
|
|
||||||
sq_pushinteger(vm, static_cast< SQInteger >(value));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* Specialization for SqKeyHash reference.
|
|
||||||
*/
|
|
||||||
template < > struct Var< SqKeyHash & > : Var< SqKeyHash >
|
|
||||||
{
|
|
||||||
Var(HSQUIRRELVM vm, SQInteger idx) noexcept : Var< SqKeyHash >(vm, idx) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* Specialization for constant SqKeyHash reference.
|
|
||||||
*/
|
|
||||||
template < > struct Var< const SqKeyHash & > : Var< SqKeyHash >
|
|
||||||
{
|
|
||||||
Var(HSQUIRRELVM vm, SQInteger idx) noexcept : Var< SqKeyHash >(vm, idx) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Namespace:: Sqrat
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
namespace SqMod {
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* Wrapper around a std::vector of std::pair values. Efficient contiguous associative container.
|
|
||||||
*/
|
|
||||||
struct SqDictionary
|
|
||||||
{
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Type stored in the container.
|
|
||||||
*/
|
|
||||||
using Element = std::pair< SQHash, LightObj >;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* The typeof container that will be used.
|
|
||||||
*/
|
|
||||||
using Container = std::vector< Element >;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Container instance.
|
|
||||||
*/
|
|
||||||
Container mC{};
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Default constructor.
|
|
||||||
*/
|
|
||||||
SqDictionary() = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Construct with initial capacity. No element is created.
|
|
||||||
*/
|
|
||||||
explicit SqDictionary(SQInteger n)
|
|
||||||
: SqDictionary()
|
|
||||||
{
|
|
||||||
mC.reserve(static_cast< size_t >(n));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copy constructor.
|
|
||||||
*/
|
|
||||||
SqDictionary(const SqDictionary &) = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Move constructor.
|
|
||||||
*/
|
|
||||||
SqDictionary(SqDictionary &&) noexcept = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Destroys the Statement.
|
|
||||||
*/
|
|
||||||
~SqDictionary() = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Assignment operator.
|
|
||||||
*/
|
|
||||||
SqDictionary & operator = (const SqDictionary &) = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Move assignment.
|
|
||||||
*/
|
|
||||||
SqDictionary & operator = (SqDictionary &&) noexcept = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Retrieve a value from the container.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD LightObj & Get(SqKeyHash k)
|
|
||||||
{
|
|
||||||
for (auto & e : mC)
|
|
||||||
{
|
|
||||||
if (e.first == k.mH) return e.second;
|
|
||||||
}
|
|
||||||
// See if we can get the specified value as a string
|
|
||||||
StackStrF val(SqVM(), 2);
|
|
||||||
// Include the value in the error if we can
|
|
||||||
if (SQ_SUCCEEDED(val.Proc(false)))
|
|
||||||
{
|
|
||||||
STHROWF("No element found for ({}) key", val.ToStr());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
STHROWF("No element found for specified key");
|
|
||||||
}
|
|
||||||
// This should not be reached
|
|
||||||
SQ_UNREACHABLE
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Retrieve a value from the container or a fall-back if it doesn't exist.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD LightObj & GetOr(SqKeyHash k, LightObj & v)
|
|
||||||
{
|
|
||||||
for (auto & e : mC)
|
|
||||||
{
|
|
||||||
if (e.first == k.mH) return e.second;
|
|
||||||
}
|
|
||||||
// Use fall-back
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Modify a value from the container.
|
|
||||||
*/
|
|
||||||
bool Set(SqKeyHash k, LightObj & v)
|
|
||||||
{
|
|
||||||
for (auto & e : mC)
|
|
||||||
{
|
|
||||||
if (e.first == k.mH)
|
|
||||||
{
|
|
||||||
e.second = std::move(v);
|
|
||||||
// We updated the element
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create the element now
|
|
||||||
mC.emplace_back(k.mH, std::move(v));
|
|
||||||
// We created the element
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Modify a value from the container. Use different values for update and create.
|
|
||||||
*/
|
|
||||||
bool SetOr(SqKeyHash k, LightObj & a, LightObj & b)
|
|
||||||
{
|
|
||||||
for (auto & e : mC)
|
|
||||||
{
|
|
||||||
if (e.first == k.mH)
|
|
||||||
{
|
|
||||||
e.second = std::move(a);
|
|
||||||
// We updated the element
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create the element now
|
|
||||||
mC.emplace_back(k.mH, std::move(b));
|
|
||||||
// We created the element
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Update a value from the container. Does not create one if it doesn't exist.
|
|
||||||
*/
|
|
||||||
bool Update(SqKeyHash k, LightObj & v)
|
|
||||||
{
|
|
||||||
for (auto & e : mC)
|
|
||||||
{
|
|
||||||
if (e.first == k.mH)
|
|
||||||
{
|
|
||||||
e.second = std::move(v);
|
|
||||||
// We updated the element
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// No element was updated
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Create a value in the container. Does not update value from existing element.
|
|
||||||
*/
|
|
||||||
bool Create(SqKeyHash k, LightObj & v)
|
|
||||||
{
|
|
||||||
for (auto & e : mC)
|
|
||||||
{
|
|
||||||
if (e.first == k.mH)
|
|
||||||
{
|
|
||||||
return false; // No element was created
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create the element now
|
|
||||||
mC.emplace_back(k.mH, std::move(v));
|
|
||||||
// We created the element
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Check if the container has no elements.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD bool Empty() const
|
|
||||||
{
|
|
||||||
return mC.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Retrieve the number of elements in the container.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD SQInteger Size() const
|
|
||||||
{
|
|
||||||
return static_cast< SQInteger >(mC.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Retrieve the number of elements that the container has currently allocated space for.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD SQInteger Capacity() const
|
|
||||||
{
|
|
||||||
return static_cast< SQInteger >(mC.capacity());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Increase the capacity of the container to a value that's greater or equal to the one specified.
|
|
||||||
*/
|
|
||||||
SqDictionary & Reserve(SQInteger n)
|
|
||||||
{
|
|
||||||
mC.reserve(ClampL< SQInteger, size_t >(n));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Request the removal of unused capacity.
|
|
||||||
*/
|
|
||||||
void Compact()
|
|
||||||
{
|
|
||||||
mC.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Erase all elements from the container.
|
|
||||||
*/
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
mC.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Erase the element with the specified key.
|
|
||||||
*/
|
|
||||||
bool Erase(SqKeyHash k)
|
|
||||||
{
|
|
||||||
auto itr = std::find_if(mC.cbegin(), mC.cend(),
|
|
||||||
[&](Container::const_reference e) -> bool { return e.first == k.mH; });
|
|
||||||
if (itr != mC.end())
|
|
||||||
{
|
|
||||||
mC.erase(itr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Check whether an element exists.
|
|
||||||
*/
|
|
||||||
bool Contains(SqKeyHash k) const
|
|
||||||
{
|
|
||||||
for (auto & e : mC)
|
|
||||||
{
|
|
||||||
if (e.first == k.mH) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Iterate all values through a functor.
|
|
||||||
*/
|
|
||||||
void Each(Function & fn) const
|
|
||||||
{
|
|
||||||
for (const auto & e : mC)
|
|
||||||
{
|
|
||||||
fn.Execute(static_cast< SQInteger >(e.first), e.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Iterate all values through a functor.
|
|
||||||
*/
|
|
||||||
void EachWith(LightObj & ctx, Function & fn) const
|
|
||||||
{
|
|
||||||
for (const auto & e : mC)
|
|
||||||
{
|
|
||||||
fn.Execute(ctx, static_cast< SQInteger >(e.first), e.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Iterate all values through a functor until stopped (i.e false is returned).
|
|
||||||
*/
|
|
||||||
void While(Function & fn) const
|
|
||||||
{
|
|
||||||
for (const auto & e : mC)
|
|
||||||
{
|
|
||||||
auto ret = fn.Eval(static_cast< SQInteger >(e.first), e.second);
|
|
||||||
// (null || true) == continue & false == break
|
|
||||||
if (!ret.IsNull() || !ret.template Cast< bool >())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Iterate all values through a functor until stopped (i.e false is returned).
|
|
||||||
*/
|
|
||||||
void WhileWith(LightObj & ctx, Function & fn) const
|
|
||||||
{
|
|
||||||
for (const auto & e : mC)
|
|
||||||
{
|
|
||||||
auto ret = fn.Eval(ctx, static_cast< SQInteger >(e.first), e.second);
|
|
||||||
// (null || true) == continue & false == break
|
|
||||||
if (!ret.IsNull() || !ret.template Cast< bool >())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Namespace:: SqMod
|
|
@ -1,42 +0,0 @@
|
|||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
#include "Library/Utils/Map.hpp"
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
namespace SqMod {
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
SQMOD_DECL_TYPENAME(SqMapInteger, _SC("SqMapInteger"))
|
|
||||||
SQMOD_DECL_TYPENAME(SqMapString, _SC("SqMapString"))
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
template < class T, class U >
|
|
||||||
static void Register_Map(HSQUIRRELVM vm, Table & ns, const SQChar * name)
|
|
||||||
{
|
|
||||||
using Container = SqMap< T >;
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
ns.Bind(name,
|
|
||||||
Class< Container, NoCopy< Container > >(vm, U::Str)
|
|
||||||
// Constructors
|
|
||||||
.Ctor()
|
|
||||||
// Meta-methods
|
|
||||||
.SquirrelFunc(_SC("_typename"), &U::Fn)
|
|
||||||
// Properties
|
|
||||||
.Prop(_SC("Null"), &Container::IsNull)
|
|
||||||
.Prop(_SC("Empty"), &Container::Empty)
|
|
||||||
.Prop(_SC("Size"), &Container::Size)
|
|
||||||
// Member Methods
|
|
||||||
.Func(_SC("Get"), &Container::Get)
|
|
||||||
.Func(_SC("Set"), &Container::Set)
|
|
||||||
.Func(_SC("Clear"), &Container::Clear)
|
|
||||||
.Func(_SC("Erase"), &Container::Erase)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================================================
|
|
||||||
void Register_Map(HSQUIRRELVM vm, Table & ns)
|
|
||||||
{
|
|
||||||
Register_Map< SQInteger, SqMapInteger >(vm, ns, _SC("IntMap"));
|
|
||||||
Register_Map< String, SqMapString >(vm, ns, _SC("StrMap"));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Namespace:: SqMod
|
|
@ -1,270 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
#include "Core/Utility.hpp"
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
#include <map>
|
|
||||||
#include <random>
|
|
||||||
#include <iterator>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
namespace SqMod {
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* Utility used to transform optimal argument type to stored type.
|
|
||||||
*/
|
|
||||||
template < class T > struct SqMapOpt
|
|
||||||
{
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Optimal argument type.
|
|
||||||
*/
|
|
||||||
using Type = T;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Container type.
|
|
||||||
*/
|
|
||||||
using Container = std::map< T, LightObj >;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Convert the optimal type to the stored type. Does nothing special in this case.
|
|
||||||
*/
|
|
||||||
inline static Type & Get(Type & k) { return k; }
|
|
||||||
inline static const Type & Get(const Type & k) { return k; }
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
inline static void Put(Container & c, LightObj & v, Type & k)
|
|
||||||
{
|
|
||||||
c[k] = v;
|
|
||||||
}
|
|
||||||
inline static void Put(Container & c, LightObj & v, const Type & k)
|
|
||||||
{
|
|
||||||
c[k] = v;
|
|
||||||
}
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
inline static void Put(Container & c, LightObj && v, Type & k)
|
|
||||||
{
|
|
||||||
c[k] = std::move(v);
|
|
||||||
}
|
|
||||||
inline static void Put(Container & c, LightObj && v, const Type & k)
|
|
||||||
{
|
|
||||||
c[k] = std::move(v);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* Specialization of SqMapOpt for String type.
|
|
||||||
*/
|
|
||||||
template < > struct SqMapOpt< String >
|
|
||||||
{
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Optimal argument type.
|
|
||||||
*/
|
|
||||||
using Type = StackStrF;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Container type.
|
|
||||||
*/
|
|
||||||
using Container = std::map< String, LightObj >;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Convert the optimal type to the stored type.
|
|
||||||
*/
|
|
||||||
inline static String Get(Type & k) { return k.ToStr(); }
|
|
||||||
inline static String Get(const Type & k) { return k.ToStr(); }
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
inline static void Put(Container & c, LightObj & v, Type & k)
|
|
||||||
{
|
|
||||||
c[k.ToStr()] = v;
|
|
||||||
}
|
|
||||||
inline static void Put(Container & c, LightObj & v, const Type & k)
|
|
||||||
{
|
|
||||||
c[k.ToStr()] = v;
|
|
||||||
}
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
inline static void Put(Container & c, LightObj && v, Type & k)
|
|
||||||
{
|
|
||||||
c[k.ToStr()] = std::move(v);
|
|
||||||
}
|
|
||||||
inline static void Put(Container & c, LightObj && v, const Type & k)
|
|
||||||
{
|
|
||||||
c[k.ToStr()] = std::move(v);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* Wrapper around a std::map of values. Space efficient table.
|
|
||||||
*/
|
|
||||||
template < class T > struct SqMap
|
|
||||||
{
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Type given via the template parameter.
|
|
||||||
*/
|
|
||||||
using Type = T;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* The typeof container that will be used.
|
|
||||||
*/
|
|
||||||
using Container = std::map< T, LightObj >;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Type stored in the container.
|
|
||||||
*/
|
|
||||||
using Element = typename Container::value_type;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Reference to the container.
|
|
||||||
*/
|
|
||||||
using Reference = std::shared_ptr< Container >;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Type given used to interact with specialized value cases.
|
|
||||||
*/
|
|
||||||
using Opt = SqMapOpt< T >;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Optimal type to receive a value of this type as function argument. Mainly for strings.
|
|
||||||
*/
|
|
||||||
using OptimalType = typename Opt::Type;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Same as OptimalType but preferably with a reference qualifier to avoid copies.
|
|
||||||
*/
|
|
||||||
using OptimalArg = typename std::conditional< std::is_same< T, OptimalType >::value, T, OptimalType & >::type;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Reference to the container instance.
|
|
||||||
*/
|
|
||||||
Reference mC;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Default constructor.
|
|
||||||
*/
|
|
||||||
SqMap()
|
|
||||||
: mC(std::make_shared< Container >())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copy constructor from reference.
|
|
||||||
*/
|
|
||||||
explicit SqMap(const Reference & v)
|
|
||||||
: mC(v)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Move constructor from reference.
|
|
||||||
*/
|
|
||||||
explicit SqMap(Reference && v) noexcept
|
|
||||||
: mC(std::move(v))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Move constructor.
|
|
||||||
*/
|
|
||||||
SqMap(SqMap &&) noexcept = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Destroys the Statement.
|
|
||||||
*/
|
|
||||||
~SqMap() = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Assignment operator.
|
|
||||||
*/
|
|
||||||
SqMap & operator = (const SqMap &) = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Move assignment.
|
|
||||||
*/
|
|
||||||
SqMap & operator = (SqMap &&) noexcept = default;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Make sure a container instance is referenced.
|
|
||||||
*/
|
|
||||||
void Validate() const
|
|
||||||
{
|
|
||||||
if (!mC)
|
|
||||||
{
|
|
||||||
STHROWF("Invalid map container instance");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Make sure a container instance is referenced and return it.
|
|
||||||
*/
|
|
||||||
Container & Valid() const { Validate(); return *mC; }
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Make sure a container instance is referenced and is populated, then return it.
|
|
||||||
*/
|
|
||||||
Container & ValidPop() const
|
|
||||||
{
|
|
||||||
Validate();
|
|
||||||
if (mC->empty())
|
|
||||||
{
|
|
||||||
STHROWF("Vector container is empty");
|
|
||||||
}
|
|
||||||
return *mC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Check if a container instance is referenced.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD bool IsNull() const
|
|
||||||
{
|
|
||||||
return static_cast< bool >(mC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Retrieve a value from the container.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD const LightObj & Get(OptimalArg k) const
|
|
||||||
{
|
|
||||||
return Valid()[Opt::Get(k)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Modify a value from the container.
|
|
||||||
*/
|
|
||||||
void Set(LightObj & v, OptimalArg k)
|
|
||||||
{
|
|
||||||
Opt::Put(Valid(), std::move(v), k);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Check if the container has no elements.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD bool Empty() const
|
|
||||||
{
|
|
||||||
return Valid().empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Retrieve the number of elements in the container.
|
|
||||||
*/
|
|
||||||
SQMOD_NODISCARD SQInteger Size() const
|
|
||||||
{
|
|
||||||
return static_cast< SQInteger >(Valid().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Erase all elements from the container.
|
|
||||||
*/
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
return Valid().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Erase the element with a certain key from the container.
|
|
||||||
*/
|
|
||||||
void Erase(OptimalArg k)
|
|
||||||
{
|
|
||||||
Valid().erase(Opt::Get(k));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Namespace:: SqMod
|
|
Loading…
Reference in New Issue
Block a user