Skip to content

Commit 6db9ab5

Browse files
authored
ElunaTemplate specialization rewrite (#498)
1 parent 58b9753 commit 6db9ab5

File tree

2 files changed

+69
-60
lines changed

2 files changed

+69
-60
lines changed

ElunaTemplate.h

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ class ElunaTemplate
227227
lua_setfield(L, metatable, "__add");
228228

229229
// make new indexes saved to methods
230-
lua_pushcfunction(L, Substract);
230+
lua_pushcfunction(L, Subtract);
231231
lua_setfield(L, metatable, "__sub");
232232

233233
// make new indexes saved to methods
@@ -477,7 +477,7 @@ class ElunaTemplate
477477
static int ArithmeticError(lua_State* L) { return luaL_error(L, "attempt to perform arithmetic on a %s value", tname); }
478478
static int CompareError(lua_State* L) { return luaL_error(L, "attempt to compare %s", tname); }
479479
static int Add(lua_State* L) { return ArithmeticError(L); }
480-
static int Substract(lua_State* L) { return ArithmeticError(L); }
480+
static int Subtract(lua_State* L) { return ArithmeticError(L); }
481481
static int Multiply(lua_State* L) { return ArithmeticError(L); }
482482
static int Divide(lua_State* L) { return ArithmeticError(L); }
483483
static int Mod(lua_State* L) { return ArithmeticError(L); }
@@ -496,4 +496,48 @@ class ElunaTemplate
496496

497497
template<typename T> const char* ElunaTemplate<T>::tname = NULL;
498498

499+
template <typename T>
500+
class ElunaTemplateHelper
501+
{
502+
public:
503+
static int PerformOp(lua_State* L, std::function<T(T, T)> op)
504+
{
505+
Eluna* E = Eluna::GetEluna(L);
506+
T val1 = E->CHECKVAL<T>(1);
507+
T val2 = E->CHECKVAL<T>(2);
508+
E->Push(op(val1, val2));
509+
return 1;
510+
}
511+
512+
static int PerformOp(lua_State* L, std::function<T(T)> op)
513+
{
514+
Eluna* E = Eluna::GetEluna(L);
515+
516+
T val = E->CHECKVAL<T>(1);
517+
E->Push(op(val));
518+
return 1;
519+
}
520+
521+
static int ToString(lua_State* L)
522+
{
523+
Eluna* E = Eluna::GetEluna(L);
524+
525+
T val = E->CHECKVAL<T>(1);
526+
std::ostringstream ss;
527+
ss << val;
528+
E->Push(ss.str());
529+
return 1;
530+
}
531+
532+
static int Pow(lua_State* L)
533+
{
534+
Eluna* E = Eluna::GetEluna(L);
535+
536+
T val1 = E->CHECKVAL<T>(1);
537+
T val2 = E->CHECKVAL<T>(2);
538+
E->Push(static_cast<T>(powl(static_cast<long double>(val1), static_cast<long double>(val2))));
539+
return 1;
540+
}
541+
};
542+
499543
#endif

LuaFunctions.cpp

Lines changed: 23 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
/*
2-
* Copyright (C) 2010 - 2023 Eluna Lua Engine <https://elunaluaengine.github.io/>
2+
* Copyright (C) 2010 - 2024 Eluna Lua Engine <https://elunaluaengine.github.io/>
33
* This program is free software licensed under GPL version 3
44
* Please see the included DOCS/LICENSE.md for more information
55
*/
66

7-
extern "C"
8-
{
9-
#include "lua.h"
10-
};
11-
127
// Eluna
138
#include "LuaEngine.h"
149
#include "ElunaEventMgr.h"
@@ -78,58 +73,28 @@ ElunaConstrainedObjectRef<Vehicle> GetWeakPtrFor(Vehicle const* obj)
7873
#endif
7974
#endif
8075

81-
// Template by Mud from http://stackoverflow.com/questions/4484437/lua-integer-type/4485511#4485511
82-
template<> int ElunaTemplate<unsigned long long>::Add(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<unsigned long long>(1) + E->CHECKVAL<unsigned long long>(2)); return 1; }
83-
template<> int ElunaTemplate<unsigned long long>::Substract(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<unsigned long long>(1) - E->CHECKVAL<unsigned long long>(2)); return 1; }
84-
template<> int ElunaTemplate<unsigned long long>::Multiply(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<unsigned long long>(1) * E->CHECKVAL<unsigned long long>(2)); return 1; }
85-
template<> int ElunaTemplate<unsigned long long>::Divide(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<unsigned long long>(1) / E->CHECKVAL<unsigned long long>(2)); return 1; }
86-
template<> int ElunaTemplate<unsigned long long>::Mod(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<unsigned long long>(1) % E->CHECKVAL<unsigned long long>(2)); return 1; }
87-
// template<> int ElunaTemplate<unsigned long long>::UnaryMinus(lua_State* L) { Eluna::GetEluna(L)->Push(-E->CHECKVAL<unsigned long long>(L, 1)); return 1; }
88-
template<> int ElunaTemplate<unsigned long long>::Equal(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<unsigned long long>(1) == E->CHECKVAL<unsigned long long>(2)); return 1; }
89-
template<> int ElunaTemplate<unsigned long long>::Less(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<unsigned long long>(1) < E->CHECKVAL<unsigned long long>(2)); return 1; }
90-
template<> int ElunaTemplate<unsigned long long>::LessOrEqual(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<unsigned long long>(1) <= E->CHECKVAL<unsigned long long>(2)); return 1; }
91-
template<> int ElunaTemplate<unsigned long long>::Pow(lua_State* L)
92-
{
93-
Eluna* E = Eluna::GetEluna(L);
94-
E->Push(static_cast<unsigned long long>(powl(static_cast<long double>(E->CHECKVAL<unsigned long long>(1)), static_cast<long double>(E->CHECKVAL<unsigned long long>(2)))));
95-
return 1;
96-
}
97-
template<> int ElunaTemplate<unsigned long long>::ToString(lua_State* L)
98-
{
99-
Eluna* E = Eluna::GetEluna(L);
100-
101-
unsigned long long l = E->CHECKVAL<unsigned long long>(1);
102-
std::ostringstream ss;
103-
ss << l;
104-
E->Push(ss.str());
105-
return 1;
106-
}
107-
108-
template<> int ElunaTemplate<long long>::Add(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<long long>(1) + E->CHECKVAL<long long>(2)); return 1; }
109-
template<> int ElunaTemplate<long long>::Substract(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<long long>(1) - E->CHECKVAL<long long>(2)); return 1; }
110-
template<> int ElunaTemplate<long long>::Multiply(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<long long>(1) * E->CHECKVAL<long long>(2)); return 1; }
111-
template<> int ElunaTemplate<long long>::Divide(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<long long>(1) / E->CHECKVAL<long long>(2)); return 1; }
112-
template<> int ElunaTemplate<long long>::Mod(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<long long>(1) % E->CHECKVAL<long long>(2)); return 1; }
113-
template<> int ElunaTemplate<long long>::UnaryMinus(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(-E->CHECKVAL<long long>(1)); return 1; }
114-
template<> int ElunaTemplate<long long>::Equal(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<long long>(1) == E->CHECKVAL<long long>(2)); return 1; }
115-
template<> int ElunaTemplate<long long>::Less(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<long long>(1) < E->CHECKVAL<long long>(2)); return 1; }
116-
template<> int ElunaTemplate<long long>::LessOrEqual(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<long long>(1) <= E->CHECKVAL<long long>(2)); return 1; }
117-
template<> int ElunaTemplate<long long>::Pow(lua_State* L)
118-
{
119-
Eluna* E = Eluna::GetEluna(L);
120-
E->Push(static_cast<long long>(powl(static_cast<long double>(E->CHECKVAL<long long>(1)), static_cast<long double>(E->CHECKVAL<long long>(2)))));
121-
return 1;
122-
}
123-
template<> int ElunaTemplate<long long>::ToString(lua_State* L)
124-
{
125-
Eluna* E = Eluna::GetEluna(L);
126-
127-
long long l = E->CHECKVAL<long long>(1);
128-
std::ostringstream ss;
129-
ss << l;
130-
E->Push(ss.str());
131-
return 1;
132-
}
76+
template<> int ElunaTemplate<unsigned long long>::Add(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::plus()); }
77+
template<> int ElunaTemplate<unsigned long long>::Subtract(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::minus()); }
78+
template<> int ElunaTemplate<unsigned long long>::Multiply(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::multiplies()); }
79+
template<> int ElunaTemplate<unsigned long long>::Divide(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::divides()); }
80+
template<> int ElunaTemplate<unsigned long long>::Mod(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::modulus()); }
81+
template<> int ElunaTemplate<unsigned long long>::Equal(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::equal_to()); }
82+
template<> int ElunaTemplate<unsigned long long>::Less(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::less()); }
83+
template<> int ElunaTemplate<unsigned long long>::LessOrEqual(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::PerformOp(L, std::less_equal()); }
84+
template<> int ElunaTemplate<unsigned long long>::ToString(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::ToString(L); }
85+
template<> int ElunaTemplate<unsigned long long>::Pow(lua_State* L) { return ElunaTemplateHelper<unsigned long long>::Pow(L); }
86+
87+
template<> int ElunaTemplate<long long>::Add(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::plus()); }
88+
template<> int ElunaTemplate<long long>::Subtract(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::minus()); }
89+
template<> int ElunaTemplate<long long>::Multiply(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::multiplies()); }
90+
template<> int ElunaTemplate<long long>::Divide(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::divides()); }
91+
template<> int ElunaTemplate<long long>::Mod(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::modulus()); }
92+
template<> int ElunaTemplate<long long>::UnaryMinus(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::negate()); }
93+
template<> int ElunaTemplate<long long>::Equal(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::equal_to()); }
94+
template<> int ElunaTemplate<long long>::Less(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::less()); }
95+
template<> int ElunaTemplate<long long>::LessOrEqual(lua_State* L) { return ElunaTemplateHelper<long long>::PerformOp(L, std::less_equal()); }
96+
template<> int ElunaTemplate<long long>::ToString(lua_State* L) { return ElunaTemplateHelper<long long>::ToString(L); }
97+
template<> int ElunaTemplate<long long>::Pow(lua_State* L) { return ElunaTemplateHelper<long long>::Pow(L); }
13398

13499
template<> int ElunaTemplate<ObjectGuid>::Equal(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(E->CHECKVAL<ObjectGuid>(1) == E->CHECKVAL<ObjectGuid>(2)); return 1; }
135100
template<> int ElunaTemplate<ObjectGuid>::ToString(lua_State* L)

0 commit comments

Comments
 (0)