Skip to content

Commit

Permalink
Arithmatic method template override cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Foereaper committed Nov 10, 2024
1 parent b59c832 commit 6c46a95
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 68 deletions.
48 changes: 46 additions & 2 deletions ElunaTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class ElunaTemplate
lua_setfield(L, metatable, "__add");

// make new indexes saved to methods
lua_pushcfunction(L, Substract);
lua_pushcfunction(L, Subtract);
lua_setfield(L, metatable, "__sub");

// make new indexes saved to methods
Expand Down Expand Up @@ -474,10 +474,54 @@ class ElunaTemplate
return 1;
}

template <typename T>
static int PerformBinaryOp(lua_State* L, std::function<T(T, T)> binaryOp)
{
Eluna* E = Eluna::GetEluna(L);

T val1 = E->CHECKVAL<T>(1);
T val2 = E->CHECKVAL<T>(2);
E->Push(binaryOp(val1, val2));
return 1;
}

template <typename T>
static int PerformUnaryOp(lua_State* L, std::function<T(T)> unaryOp)
{
Eluna* E = Eluna::GetEluna(L);

T val1 = E->CHECKVAL<T>(1);
E->Push(unaryOp(val1));
return 1;
}

template <typename T>
static int ToStringHelper(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);

T val = E->CHECKVAL<T>(1);
std::ostringstream ss;
ss << val;
E->Push(ss.str());
return 1;
}

template <typename T>
static int PowHelper(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);

T val1 = E->CHECKVAL<T>(1);
T val2 = E->CHECKVAL<T>(2);
E->Push(static_cast<T>(powl(static_cast<long double>(val1), static_cast<long double>(val2))));
return 1;
}

static int ArithmeticError(lua_State* L) { return luaL_error(L, "attempt to perform arithmetic on a %s value", tname); }
static int CompareError(lua_State* L) { return luaL_error(L, "attempt to compare %s", tname); }
static int Add(lua_State* L) { return ArithmeticError(L); }
static int Substract(lua_State* L) { return ArithmeticError(L); }
static int Subtract(lua_State* L) { return ArithmeticError(L); }
static int Multiply(lua_State* L) { return ArithmeticError(L); }
static int Divide(lua_State* L) { return ArithmeticError(L); }
static int Mod(lua_State* L) { return ArithmeticError(L); }
Expand Down
102 changes: 36 additions & 66 deletions LuaFunctions.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 - 2023 Eluna Lua Engine <https://elunaluaengine.github.io/>
* Copyright (C) 2010 - 2024 Eluna Lua Engine <https://elunaluaengine.github.io/>
* This program is free software licensed under GPL version 3
* Please see the included DOCS/LICENSE.md for more information
*/
Expand Down Expand Up @@ -78,71 +78,6 @@ ElunaConstrainedObjectRef<Vehicle> GetWeakPtrFor(Vehicle const* obj)
#endif
#endif

// Template by Mud from http://stackoverflow.com/questions/4484437/lua-integer-type/4485511#4485511
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; }
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; }
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; }
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; }
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; }
// template<> int ElunaTemplate<unsigned long long>::UnaryMinus(lua_State* L) { Eluna::GetEluna(L)->Push(-E->CHECKVAL<unsigned long long>(L, 1)); return 1; }
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; }
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; }
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; }
template<> int ElunaTemplate<unsigned long long>::Pow(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);
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)))));
return 1;
}
template<> int ElunaTemplate<unsigned long long>::ToString(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);

unsigned long long l = E->CHECKVAL<unsigned long long>(1);
std::ostringstream ss;
ss << l;
E->Push(ss.str());
return 1;
}

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; }
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; }
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; }
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; }
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; }
template<> int ElunaTemplate<long long>::UnaryMinus(lua_State* L) { Eluna* E = Eluna::GetEluna(L); E->Push(-E->CHECKVAL<long long>(1)); return 1; }
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; }
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; }
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; }
template<> int ElunaTemplate<long long>::Pow(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);
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)))));
return 1;
}
template<> int ElunaTemplate<long long>::ToString(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);

long long l = E->CHECKVAL<long long>(1);
std::ostringstream ss;
ss << l;
E->Push(ss.str());
return 1;
}

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; }
template<> int ElunaTemplate<ObjectGuid>::ToString(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);
#if defined ELUNA_TRINITY
E->Push(E->CHECKVAL<ObjectGuid>(1).ToString());
#else
E->Push(E->CHECKVAL<ObjectGuid>(1).GetString());
#endif
return 1;
}

void RegisterFunctions(Eluna* E)
{
ElunaTemplate<>::SetMethods(E, LuaGlobalFunctions::GlobalMethods);
Expand Down Expand Up @@ -225,3 +160,38 @@ void RegisterFunctions(Eluna* E)

LuaVal::Register(E->L);
}

template<> int ElunaTemplate<unsigned long long>::Add(lua_State* L) { return PerformBinaryOp<unsigned long long>(L, std::plus<unsigned long long>()); }
template<> int ElunaTemplate<unsigned long long>::Subtract(lua_State* L) { return PerformBinaryOp<unsigned long long>(L, std::minus<unsigned long long>()); }
template<> int ElunaTemplate<unsigned long long>::Multiply(lua_State* L) { return PerformBinaryOp<unsigned long long>(L, std::multiplies<unsigned long long>()); }
template<> int ElunaTemplate<unsigned long long>::Divide(lua_State* L) { return PerformBinaryOp<unsigned long long>(L, std::divides<unsigned long long>()); }
template<> int ElunaTemplate<unsigned long long>::Mod(lua_State* L) { return PerformBinaryOp<unsigned long long>(L, std::modulus<unsigned long long>()); }
template<> int ElunaTemplate<unsigned long long>::Equal(lua_State* L) { return PerformBinaryOp<unsigned long long>(L, std::equal_to<unsigned long long>()); }
template<> int ElunaTemplate<unsigned long long>::Less(lua_State* L) { return PerformBinaryOp<unsigned long long>(L, std::less<unsigned long long>()); }
template<> int ElunaTemplate<unsigned long long>::LessOrEqual(lua_State* L) { return PerformBinaryOp<unsigned long long>(L, std::less_equal<unsigned long long>()); }
template<> int ElunaTemplate<unsigned long long>::ToString(lua_State* L) { return ToStringHelper<unsigned long long>(L); }
template<> int ElunaTemplate<unsigned long long>::Pow(lua_State* L) { return PowHelper<unsigned long long>(L); }

template<> int ElunaTemplate<long long>::Add(lua_State* L) { return PerformBinaryOp<long long>(L, std::plus<long long>()); }
template<> int ElunaTemplate<long long>::Subtract(lua_State* L) { return PerformBinaryOp<long long>(L, std::minus<long long>()); }
template<> int ElunaTemplate<long long>::Multiply(lua_State* L) { return PerformBinaryOp<long long>(L, std::multiplies<long long>()); }
template<> int ElunaTemplate<long long>::Divide(lua_State* L) { return PerformBinaryOp<long long>(L, std::divides<long long>()); }
template<> int ElunaTemplate<long long>::Mod(lua_State* L) { return PerformBinaryOp<long long>(L, std::modulus<long long>()); }
template<> int ElunaTemplate<long long>::UnaryMinus(lua_State* L) { return PerformUnaryOp<long long>(L, std::negate<long long>()); }
template<> int ElunaTemplate<long long>::Equal(lua_State* L) { return PerformBinaryOp<long long>(L, std::equal_to<long long>()); }
template<> int ElunaTemplate<long long>::Less(lua_State* L) { return PerformBinaryOp<long long>(L, std::less<long long>()); }
template<> int ElunaTemplate<long long>::LessOrEqual(lua_State* L) { return PerformBinaryOp<long long>(L, std::less_equal<long long>()); }
template<> int ElunaTemplate<long long>::ToString(lua_State* L) { return ToStringHelper<long long>(L); }
template<> int ElunaTemplate<long long>::Pow(lua_State* L) { return PowHelper<long long>(L); }

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; }
template<> int ElunaTemplate<ObjectGuid>::ToString(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);
#if defined ELUNA_TRINITY
E->Push(E->CHECKVAL<ObjectGuid>(1).ToString());
#else
E->Push(E->CHECKVAL<ObjectGuid>(1).GetString());
#endif
return 1;
}

0 comments on commit 6c46a95

Please sign in to comment.