1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +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:
Sandu Liviu Catalin 2021-07-04 04:15:38 +03:00
parent f661d13d24
commit 0ed82f66e1
6 changed files with 0 additions and 731 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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