1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-04 08:34:32 +00:00

Merge branch openmw:master into master

This commit is contained in:
Andy Lanzone 2025-07-27 13:21:40 -07:00
commit 31580ffb71
149 changed files with 6962 additions and 5791 deletions

View file

@ -1 +1 @@
VCPKG_DEPS_TAG=2024-11-10
VCPKG_DEPS_TAG=2025-07-23

View file

@ -63,7 +63,7 @@ add_openmw_dir (mwlua
context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings coremwscriptbindings
mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings dialoguebindings
postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker landbindings magicbindings factionbindings
classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings
classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings weatherbindings
types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc
types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus
types/potion types/ingredient types/misc types/repair types/armor types/light types/static

View file

@ -781,7 +781,6 @@ void OMW::Engine::prepareEngine()
const auto userdefault = mCfgMgr.getUserConfigPath() / "gamecontrollerdb.txt";
const auto localdefault = mCfgMgr.getLocalPath() / "gamecontrollerdb.txt";
const auto globaldefault = mCfgMgr.getGlobalPath() / "gamecontrollerdb.txt";
std::filesystem::path userGameControllerdb;
if (std::filesystem::exists(userdefault))
@ -790,9 +789,13 @@ void OMW::Engine::prepareEngine()
std::filesystem::path gameControllerdb;
if (std::filesystem::exists(localdefault))
gameControllerdb = localdefault;
else if (std::filesystem::exists(globaldefault))
gameControllerdb = globaldefault;
// else if it doesn't exist, pass in an empty string
else if (!mCfgMgr.getGlobalPath().empty())
{
const auto globaldefault = mCfgMgr.getGlobalPath() / "gamecontrollerdb.txt";
if (std::filesystem::exists(globaldefault))
gameControllerdb = globaldefault;
}
// else if it doesn't exist, pass in an empty path
// gui needs our shaders path before everything else
mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders");

View file

@ -22,6 +22,7 @@
namespace osg
{
class Vec3f;
class Vec4f;
class Matrixf;
class Quat;
class Image;
@ -93,6 +94,7 @@ namespace MWWorld
class RefData;
class Cell;
class DateTimeManager;
class Weather;
typedef std::vector<std::pair<MWWorld::Ptr, MWMechanics::Movement>> PtrMovementList;
}
@ -216,9 +218,21 @@ namespace MWBase
virtual void changeWeather(const ESM::RefId& region, const unsigned int id) = 0;
virtual int getCurrentWeather() const = 0;
virtual void changeWeather(const ESM::RefId& region, const ESM::RefId& id) = 0;
virtual int getNextWeather() const = 0;
virtual const std::vector<MWWorld::Weather>& getAllWeather() const = 0;
virtual int getCurrentWeatherScriptId() const = 0;
virtual const MWWorld::Weather& getCurrentWeather() const = 0;
virtual const MWWorld::Weather* getWeather(size_t index) const = 0;
virtual const MWWorld::Weather* getWeather(const ESM::RefId& id) const = 0;
virtual int getNextWeatherScriptId() const = 0;
virtual const MWWorld::Weather* getNextWeather() const = 0;
virtual float getWeatherTransition() const = 0;
@ -478,6 +492,7 @@ namespace MWBase
// Allow NPCs to use torches?
virtual bool useTorches() const = 0;
virtual const osg::Vec4f& getSunLightPosition() const = 0;
virtual float getSunVisibility() const = 0;
virtual float getSunPercentage() const = 0;

View file

@ -501,7 +501,7 @@ int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) cons
case ESM::DialogueCondition::Function_Weather:
return MWBase::Environment::get().getWorld()->getCurrentWeather();
return MWBase::Environment::get().getWorld()->getCurrentWeatherScriptId();
case ESM::DialogueCondition::Function_Reputation:
if (!mActor.getClass().isNpc())

View file

@ -27,6 +27,7 @@
#include "magicbindings.hpp"
#include "soundbindings.hpp"
#include "stats.hpp"
#include "weatherbindings.hpp"
namespace MWLua
{
@ -104,6 +105,9 @@ namespace MWLua
api["land"] = context.cachePackage("openmw_core_land", [context]() { return initCoreLandBindings(context); });
api["weather"]
= context.cachePackage("openmw_core_weather", [context]() { return initCoreWeatherBindings(context); });
api["factions"]
= context.cachePackage("openmw_core_factions", [context]() { return initCoreFactionBindings(context); });
api["dialogue"]

View file

@ -0,0 +1,185 @@
#include "weatherbindings.hpp"
#include <osg/Vec4f>
#include <components/esm3/loadregn.hpp>
#include <components/lua/util.hpp>
#include <components/misc/color.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/weather.hpp"
#include "context.hpp"
namespace
{
class WeatherStore
{
public:
const MWWorld::Weather* get(size_t index) const
{
return MWBase::Environment::get().getWorld()->getWeather(index);
}
const MWWorld::Weather* get(const ESM::RefId& id) const
{
return MWBase::Environment::get().getWorld()->getWeather(id);
}
size_t size() const { return MWBase::Environment::get().getWorld()->getAllWeather().size(); }
};
Misc::Color color(const osg::Vec4f& color)
{
return Misc::Color(color.r(), color.g(), color.b(), color.a());
}
}
namespace MWLua
{
sol::table initCoreWeatherBindings(const Context& context)
{
sol::state_view lua = context.sol();
sol::table api(lua, sol::create);
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
auto weatherT = lua.new_usertype<MWWorld::Weather>("Weather");
weatherT[sol::meta_function::to_string]
= [](const MWWorld::Weather& w) -> std::string { return "Weather[" + w.mName + "]"; };
weatherT["name"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mName; });
weatherT["windSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mWindSpeed; });
weatherT["cloudSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mCloudSpeed; });
weatherT["cloudTexture"] = sol::readonly_property([vfs](const MWWorld::Weather& w) {
return Misc::ResourceHelpers::correctTexturePath(w.mCloudTexture, vfs);
});
weatherT["cloudsMaximumPercent"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mCloudsMaximumPercent; });
weatherT["isStorm"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mIsStorm; });
weatherT["stormDirection"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mStormDirection; });
weatherT["glareView"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mGlareView; });
weatherT["rainSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainSpeed; });
weatherT["rainEntranceSpeed"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainEntranceSpeed; });
weatherT["rainEffect"] = sol::readonly_property([](const MWWorld::Weather& w) -> sol::optional<std::string> {
if (w.mRainEffect.empty())
return sol::nullopt;
return w.mRainEffect;
});
weatherT["rainMaxRaindrops"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMaxRaindrops; });
weatherT["rainDiameter"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainDiameter; });
weatherT["rainThreshold"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainThreshold; });
weatherT["rainMaxHeight"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMaxHeight; });
weatherT["rainMinHeight"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMinHeight; });
weatherT["rainLoopSoundID"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainLoopSoundID.serializeText(); });
weatherT["thunderSoundID"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
for (const auto& soundId : w.mThunderSoundID)
result.add(soundId.serializeText());
return result;
});
weatherT["sunDiscSunsetColor"]
= sol::readonly_property([](const MWWorld::Weather& w) { return color(w.mSunDiscSunsetColor); });
weatherT["ambientLoopSoundID"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mAmbientLoopSoundID.serializeText(); });
weatherT["ambientColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = color(w.mAmbientColor.getSunriseValue());
result["day"] = color(w.mAmbientColor.getDayValue());
result["sunset"] = color(w.mAmbientColor.getSunsetValue());
result["night"] = color(w.mAmbientColor.getNightValue());
return result;
});
weatherT["fogColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = color(w.mFogColor.getSunriseValue());
result["day"] = color(w.mFogColor.getDayValue());
result["sunset"] = color(w.mFogColor.getSunsetValue());
result["night"] = color(w.mFogColor.getNightValue());
return result;
});
weatherT["skyColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = color(w.mSkyColor.getSunriseValue());
result["day"] = color(w.mSkyColor.getDayValue());
result["sunset"] = color(w.mSkyColor.getSunsetValue());
result["night"] = color(w.mSkyColor.getNightValue());
return result;
});
weatherT["sunColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = color(w.mSunColor.getSunriseValue());
result["day"] = color(w.mSunColor.getDayValue());
result["sunset"] = color(w.mSunColor.getSunsetValue());
result["night"] = color(w.mSunColor.getNightValue());
return result;
});
weatherT["landFogDepth"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = w.mLandFogDepth.getSunriseValue();
result["day"] = w.mLandFogDepth.getDayValue();
result["sunset"] = w.mLandFogDepth.getSunsetValue();
result["night"] = w.mLandFogDepth.getNightValue();
return result;
});
weatherT["particleEffect"]
= sol::readonly_property([](const MWWorld::Weather& w) -> sol::optional<std::string> {
if (w.mParticleEffect.empty())
return sol::nullopt;
return w.mParticleEffect;
});
weatherT["distantLandFogFactor"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogFactor; });
weatherT["distantLandFogOffset"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogOffset; });
weatherT["scriptId"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mScriptId; });
weatherT["recordId"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mId.serializeText(); });
api["getCurrent"] = []() { return MWBase::Environment::get().getWorld()->getCurrentWeather(); };
api["getNext"]
= []() -> const MWWorld::Weather* { return MWBase::Environment::get().getWorld()->getNextWeather(); };
api["getTransition"] = []() { return MWBase::Environment::get().getWorld()->getWeatherTransition(); };
api["changeWeather"] = [](std::string_view regionId, const MWWorld::Weather& weather) {
ESM::RefId region = ESM::RefId::deserializeText(regionId);
MWBase::Environment::get().getESMStore()->get<ESM::Region>().find(region);
MWBase::Environment::get().getWorld()->changeWeather(region, weather.mId);
};
sol::usertype<WeatherStore> storeT = lua.new_usertype<WeatherStore>("WeatherWorldStore");
storeT[sol::meta_function::to_string]
= [](const WeatherStore& store) { return "{" + std::to_string(store.size()) + " Weather records}"; };
storeT[sol::meta_function::length] = [](const WeatherStore& store) { return store.size(); };
storeT[sol::meta_function::index] = sol::overload(
[](const WeatherStore& store, size_t index) -> const MWWorld::Weather* {
return store.get(LuaUtil::fromLuaIndex(index));
},
[](const WeatherStore& store, std::string_view id) -> const MWWorld::Weather* {
return store.get(ESM::RefId::deserializeText(id));
});
storeT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
// Provide access to the store.
api["records"] = WeatherStore{};
api["getCurrentSunLightDirection"] = []() {
osg::Vec4f sunPos = MWBase::Environment::get().getWorld()->getSunLightPosition();
// normalize to get the direction towards the sun
sunPos.normalize();
// and invert it to get the direction of the sun light
return -sunPos;
};
api["getCurrentSunVisibility"] = []() { return MWBase::Environment::get().getWorld()->getSunVisibility(); };
api["getCurrentSunPercentage"] = []() { return MWBase::Environment::get().getWorld()->getSunPercentage(); };
api["getCurrentWindSpeed"] = []() { return MWBase::Environment::get().getWorld()->getWindSpeed(); };
api["getCurrentStormDirection"] = []() { return MWBase::Environment::get().getWorld()->getStormDirection(); };
return LuaUtil::makeReadOnly(api);
}
}

View file

@ -0,0 +1,14 @@
#ifndef MWLUA_WEATHERBINDINGS_H
#define MWLUA_WEATHERBINDINGS_H
#include <sol/forward.hpp>
namespace MWLua
{
struct Context;
sol::table initCoreWeatherBindings(const Context&);
}
#endif // MWLUA_WEATHERBINDINGS_H

View file

@ -73,6 +73,21 @@ namespace
namespace MWMechanics
{
struct ActiveSpells::UpdateContext
{
bool mUpdatedEnemy = false;
bool mUpdatedHitOverlay = false;
bool mUpdateSpellWindow = false;
bool mPlayNonLooping = false;
bool mEraseRemoved = false;
bool mUpdate;
UpdateContext(bool update)
: mUpdate(update)
{
}
};
ActiveSpells::IterationGuard::IterationGuard(ActiveSpells& spells)
: mActiveSpells(spells)
{
@ -256,8 +271,9 @@ namespace MWMechanics
++spellIt;
}
UpdateContext context(duration > 0.f);
for (const auto& spell : mQueue)
addToSpells(ptr, spell);
addToSpells(ptr, spell, context);
mQueue.clear();
// Vanilla only does this on cell change I think
@ -267,20 +283,17 @@ namespace MWMechanics
if (spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power
&& !isSpellActive(spell->mId))
{
mSpells.emplace_back(ActiveSpellParams{ spell, ptr, true });
mSpells.back().setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
initParams(ptr, ActiveSpellParams{ spell, ptr, true }, context);
}
}
bool updateSpellWindow = false;
bool playNonLooping = false;
if (ptr.getClass().hasInventoryStore(ptr)
&& !(creatureStats.isDead() && !creatureStats.isDeathAnimationFinished()))
{
auto& store = ptr.getClass().getInventoryStore(ptr);
if (store.getInvListener() != nullptr)
{
playNonLooping = !store.isFirstEquip();
context.mPlayNonLooping = !store.isFirstEquip();
const auto world = MWBase::Environment::get().getWorld();
for (int slotIndex = 0; slotIndex < MWWorld::InventoryStore::Slots; slotIndex++)
{
@ -306,82 +319,108 @@ namespace MWMechanics
// invisibility manually
purgeEffect(ptr, ESM::MagicEffect::Invisibility);
applyPurges(ptr);
ActiveSpellParams& params = mSpells.emplace_back(ActiveSpellParams{ *slot, enchantment, ptr });
params.setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
updateSpellWindow = true;
ActiveSpellParams* params = initParams(ptr, ActiveSpellParams{ *slot, enchantment, ptr }, context);
if (params)
context.mUpdateSpellWindow = true;
}
}
}
const MWWorld::Ptr player = MWMechanics::getPlayer();
bool updatedHitOverlay = false;
bool updatedEnemy = false;
// Update effects
context.mEraseRemoved = true;
for (auto spellIt = mSpells.begin(); spellIt != mSpells.end();)
{
const auto caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(
spellIt->mCasterActorId); // Maybe make this search outside active grid?
bool removedSpell = false;
std::optional<ActiveSpellParams> reflected;
for (auto it = spellIt->mEffects.begin(); it != spellIt->mEffects.end();)
{
auto result = applyMagicEffect(ptr, caster, *spellIt, *it, duration, playNonLooping);
if (result.mType == MagicApplicationResult::Type::REFLECTED)
{
if (!reflected)
{
if (Settings::game().mClassicReflectedAbsorbSpellsBehavior)
reflected = { *spellIt, caster };
else
reflected = { *spellIt, ptr };
}
auto& reflectedEffect = reflected->mEffects.emplace_back(*it);
reflectedEffect.mFlags
= ESM::ActiveEffect::Flag_Ignore_Reflect | ESM::ActiveEffect::Flag_Ignore_SpellAbsorption;
it = spellIt->mEffects.erase(it);
}
else if (result.mType == MagicApplicationResult::Type::REMOVED)
it = spellIt->mEffects.erase(it);
else
{
++it;
if (!updatedEnemy && result.mShowHealth && caster == player && ptr != player)
{
MWBase::Environment::get().getWindowManager()->setEnemy(ptr);
updatedEnemy = true;
}
if (!updatedHitOverlay && result.mShowHit && ptr == player)
{
MWBase::Environment::get().getWindowManager()->activateHitOverlay(false);
updatedHitOverlay = true;
}
}
removedSpell = applyPurges(ptr, &spellIt, &it);
if (removedSpell)
break;
}
if (reflected)
{
const ESM::Static* reflectStatic = MWBase::Environment::get().getESMStore()->get<ESM::Static>().find(
ESM::RefId::stringRefId("VFX_Reflect"));
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if (animation && !reflectStatic->mModel.empty())
{
const VFS::Path::Normalized reflectStaticModel
= Misc::ResourceHelpers::correctMeshPath(VFS::Path::Normalized(reflectStatic->mModel));
animation->addEffect(
reflectStaticModel, ESM::MagicEffect::indexToName(ESM::MagicEffect::Reflect), false);
}
caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell(*reflected);
}
if (removedSpell)
continue;
updateActiveSpell(ptr, duration, spellIt, context);
}
if (Settings::game().mClassicCalmSpellsBehavior)
{
ESM::MagicEffect::Effects effect
= ptr.getClass().isNpc() ? ESM::MagicEffect::CalmHumanoid : ESM::MagicEffect::CalmCreature;
if (creatureStats.getMagicEffects().getOrDefault(effect).getMagnitude() > 0.f)
creatureStats.getAiSequence().stopCombat();
}
if (ptr == player && context.mUpdateSpellWindow)
{
// Something happened with the spell list -- possibly while the game is paused,
// so we want to make the spell window get the memo.
// We don't normally want to do this, so this targets constant enchantments.
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
}
}
bool ActiveSpells::updateActiveSpell(
const MWWorld::Ptr& ptr, float duration, Collection::iterator& spellIt, UpdateContext& context)
{
const auto caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(
spellIt->mCasterActorId); // Maybe make this search outside active grid?
bool removedSpell = false;
std::optional<ActiveSpellParams> reflected;
for (auto it = spellIt->mEffects.begin(); it != spellIt->mEffects.end();)
{
auto result = applyMagicEffect(ptr, caster, *spellIt, *it, duration, context.mPlayNonLooping);
if (result.mType == MagicApplicationResult::Type::REFLECTED)
{
if (!reflected)
{
if (Settings::game().mClassicReflectedAbsorbSpellsBehavior)
reflected = { *spellIt, caster };
else
reflected = { *spellIt, ptr };
}
auto& reflectedEffect = reflected->mEffects.emplace_back(*it);
reflectedEffect.mFlags
= ESM::ActiveEffect::Flag_Ignore_Reflect | ESM::ActiveEffect::Flag_Ignore_SpellAbsorption;
it = spellIt->mEffects.erase(it);
}
else if (result.mType == MagicApplicationResult::Type::REMOVED)
it = spellIt->mEffects.erase(it);
else
{
const MWWorld::Ptr player = MWMechanics::getPlayer();
++it;
if (!context.mUpdatedEnemy && result.mShowHealth && caster == player && ptr != player)
{
MWBase::Environment::get().getWindowManager()->setEnemy(ptr);
context.mUpdatedEnemy = true;
}
if (!context.mUpdatedHitOverlay && result.mShowHit && ptr == player)
{
MWBase::Environment::get().getWindowManager()->activateHitOverlay(false);
context.mUpdatedHitOverlay = true;
}
}
removedSpell = applyPurges(ptr, &spellIt, &it);
if (removedSpell)
break;
}
if (reflected)
{
const ESM::Static* reflectStatic = MWBase::Environment::get().getESMStore()->get<ESM::Static>().find(
ESM::RefId::stringRefId("VFX_Reflect"));
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if (animation && !reflectStatic->mModel.empty())
{
const VFS::Path::Normalized reflectStaticModel
= Misc::ResourceHelpers::correctMeshPath(VFS::Path::Normalized(reflectStatic->mModel));
animation->addEffect(
reflectStaticModel, ESM::MagicEffect::indexToName(ESM::MagicEffect::Reflect), false);
}
caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell(*reflected);
}
if (removedSpell)
return true;
if (context.mEraseRemoved)
{
bool remove = false;
if (spellIt->hasFlag(ESM::ActiveSpells::Flag_SpellStore))
{
try
{
auto& spells = ptr.getClass().getCreatureStats(ptr).getSpells();
remove = !spells.hasSpell(spellIt->mSourceSpellId);
}
catch (const std::runtime_error& e)
@ -413,30 +452,27 @@ namespace MWMechanics
for (const auto& effect : params.mEffects)
onMagicEffectRemoved(ptr, params, effect);
applyPurges(ptr, &spellIt);
updateSpellWindow = true;
continue;
context.mUpdateSpellWindow = true;
return true;
}
++spellIt;
}
if (Settings::game().mClassicCalmSpellsBehavior)
{
ESM::MagicEffect::Effects effect
= ptr.getClass().isNpc() ? ESM::MagicEffect::CalmHumanoid : ESM::MagicEffect::CalmCreature;
if (creatureStats.getMagicEffects().getOrDefault(effect).getMagnitude() > 0.f)
creatureStats.getAiSequence().stopCombat();
}
if (ptr == player && updateSpellWindow)
{
// Something happened with the spell list -- possibly while the game is paused,
// so we want to make the spell window get the memo.
// We don't normally want to do this, so this targets constant enchantments.
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
}
++spellIt;
return false;
}
void ActiveSpells::addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell)
ActiveSpells::ActiveSpellParams* ActiveSpells::initParams(
const MWWorld::Ptr& ptr, const ActiveSpellParams& params, UpdateContext& context)
{
mSpells.emplace_back(params).setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
auto it = mSpells.end();
--it;
// We instantly apply the effect with a duration of 0 so continuous effects can be purged before truly applying
if (context.mUpdate && updateActiveSpell(ptr, 0.f, it, context))
return nullptr;
return &*it;
}
void ActiveSpells::addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell, UpdateContext& context)
{
if (!spell.hasFlag(ESM::ActiveSpells::Flag_Stackable))
{
@ -454,8 +490,7 @@ namespace MWMechanics
onMagicEffectRemoved(ptr, params, effect);
}
}
mSpells.emplace_back(spell);
mSpells.back().setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
initParams(ptr, spell, context);
}
ActiveSpells::ActiveSpells()
@ -608,6 +643,8 @@ namespace MWMechanics
{
purge(
[=](const ActiveSpellParams&, const ESM::ActiveEffect& effect) {
if (!(effect.mFlags & ESM::ActiveEffect::Flag_Applied))
return false;
if (effectArg.empty())
return effect.mEffectId == effectId;
return effect.mEffectId == effectId && effect.getSkillOrAttribute() == effectArg;

View file

@ -116,17 +116,23 @@ namespace MWMechanics
IterationGuard(ActiveSpells& spells);
~IterationGuard();
};
struct UpdateContext;
std::list<ActiveSpellParams> mSpells;
std::vector<ActiveSpellParams> mQueue;
std::queue<Predicate> mPurges;
bool mIterating;
void addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell);
void addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell, UpdateContext& context);
bool applyPurges(const MWWorld::Ptr& ptr, std::list<ActiveSpellParams>::iterator* currentSpell = nullptr,
std::vector<ActiveEffect>::iterator* currentEffect = nullptr);
bool updateActiveSpell(
const MWWorld::Ptr& ptr, float duration, Collection::iterator& spellIt, UpdateContext& context);
ActiveSpellParams* initParams(const MWWorld::Ptr& ptr, const ActiveSpellParams& params, UpdateContext& context);
public:
ActiveSpells();

View file

@ -1326,19 +1326,37 @@ namespace MWMechanics
const MWWorld::Ptr player = getPlayer();
const MWBase::World* const world = MWBase::Environment::get().getWorld();
struct CacheEntry
{
MWWorld::Ptr mPtr;
float mMaxSpeed;
osg::Vec3f mHalfExtents;
Movement& mMovement;
};
std::vector<CacheEntry> cache;
cache.reserve(mActors.size());
for (const Actor& actor : mActors)
{
if (actor.isInvalid())
continue;
const MWWorld::Ptr& ptr = actor.getPtr();
const MWWorld::Class& cls = ptr.getClass();
cache.push_back({ ptr, cls.getMaxSpeed(ptr), world->getHalfExtents(ptr), cls.getMovementSettings(ptr) });
}
for (const CacheEntry& cached : cache)
{
const MWWorld::Ptr& ptr = cached.mPtr;
if (ptr == player)
continue; // Don't interfere with player controls.
const float maxSpeed = ptr.getClass().getMaxSpeed(ptr);
const float maxSpeed = cached.mMaxSpeed;
if (maxSpeed == 0.0)
continue; // Can't move, so there is no sense to predict collisions.
Movement& movement = ptr.getClass().getMovementSettings(ptr);
Movement& movement = cached.mMovement;
const osg::Vec2f origMovement(movement.mPosition[0], movement.mPosition[1]);
const bool isMoving = origMovement.length2() > 0.01;
if (movement.mPosition[1] < 0)
@ -1379,7 +1397,7 @@ namespace MWMechanics
const osg::Vec2f baseSpeed = origMovement * maxSpeed;
const osg::Vec3f basePos = ptr.getRefData().getPosition().asVec3();
const float baseRotZ = ptr.getRefData().getPosition().rot[2];
const osg::Vec3f halfExtents = world->getHalfExtents(ptr);
const osg::Vec3f& halfExtents = cached.mHalfExtents;
const float maxDistToCheck = isMoving ? maxDistForPartialAvoiding : maxDistForStrictAvoiding;
float timeToCheck = maxTimeToCheck;
@ -1392,15 +1410,13 @@ namespace MWMechanics
float angleToApproachingActor = 0;
// Iterate through all other actors and predict collisions.
for (const Actor& otherActor : mActors)
for (const CacheEntry& otherCached : cache)
{
if (otherActor.isInvalid())
continue;
const MWWorld::Ptr& otherPtr = otherActor.getPtr();
const MWWorld::Ptr& otherPtr = otherCached.mPtr;
if (otherPtr == ptr || otherPtr == currentTarget)
continue;
const osg::Vec3f otherHalfExtents = world->getHalfExtents(otherPtr);
const osg::Vec3f& otherHalfExtents = otherCached.mHalfExtents;
const osg::Vec3f deltaPos = otherPtr.getRefData().getPosition().asVec3() - basePos;
const osg::Vec2f relPos = Misc::rotateVec2f(osg::Vec2f(deltaPos.x(), deltaPos.y()), baseRotZ);
const float dist = deltaPos.length();
@ -1413,8 +1429,7 @@ namespace MWMechanics
if (deltaPos.z() > halfExtents.z() * 2 || deltaPos.z() < -otherHalfExtents.z() * 2)
continue;
const osg::Vec3f speed = otherPtr.getClass().getMovementSettings(otherPtr).asVec3()
* otherPtr.getClass().getMaxSpeed(otherPtr);
const osg::Vec3f speed = otherCached.mMovement.asVec3() * otherCached.mMaxSpeed;
const float rotZ = otherPtr.getRefData().getPosition().rot[2];
const osg::Vec2f relSpeed
= Misc::rotateVec2f(osg::Vec2f(speed.x(), speed.y()), baseRotZ - rotZ) - baseSpeed;

View file

@ -178,11 +178,16 @@ namespace MWMechanics
currentCell = actor.getCell();
}
const MWWorld::Class& actorClass = actor.getClass();
MWMechanics::CreatureStats& stats = actorClass.getCreatureStats(actor);
if (stats.isParalyzed() || stats.getKnockedDown())
return false;
bool forceFlee = false;
if (!canFight(actor, target))
{
storage.stopAttack();
actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false);
stats.setAttackingOrSpell(false);
storage.mActionCooldown = 0.f;
// Continue combat if target is player or player follower/escorter and an attack has been attempted
const auto& playerFollowersAndEscorters
@ -191,18 +196,14 @@ namespace MWMechanics
= (std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), target)
!= playerFollowersAndEscorters.end());
if ((target == MWMechanics::getPlayer() || targetSidesWithPlayer)
&& ((actor.getClass().getCreatureStats(actor).getHitAttemptActorId()
== target.getClass().getCreatureStats(target).getActorId())
|| (target.getClass().getCreatureStats(target).getHitAttemptActorId()
== actor.getClass().getCreatureStats(actor).getActorId())))
&& ((stats.getHitAttemptActorId() == target.getClass().getCreatureStats(target).getActorId())
|| (target.getClass().getCreatureStats(target).getHitAttemptActorId() == stats.getActorId())))
forceFlee = true;
else // Otherwise end combat
return true;
}
const MWWorld::Class& actorClass = actor.getClass();
actorClass.getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
stats.setMovementFlag(CreatureStats::Flag_Run, true);
float& actionCooldown = storage.mActionCooldown;
std::unique_ptr<Action>& currentAction = storage.mCurrentAction;
@ -330,7 +331,7 @@ namespace MWMechanics
{
storage.mUseCustomDestination = false;
storage.stopAttack();
actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false);
stats.setAttackingOrSpell(false);
currentAction = std::make_unique<ActionFlee>();
actionCooldown = currentAction->getActionCooldown();
storage.startFleeing();

View file

@ -2310,17 +2310,13 @@ namespace MWMechanics
}
else
{
// Do not play turning animation for player if rotation speed is very slow.
// Actual threshold should take framerate in account.
float rotationThreshold = (isPlayer ? 0.015f : 0.001f) * 60 * duration;
// It seems only bipedal actors use turning animations.
// Also do not use turning animations in the first-person view and when sneaking.
if (!sneak && !isFirstPersonPlayer && isBiped)
{
if (effectiveRotation > rotationThreshold)
if (effectiveRotation > 0.f)
movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight;
else if (effectiveRotation < -rotationThreshold)
else if (effectiveRotation < 0.f)
movestate = inwater ? CharState_SwimTurnLeft : CharState_TurnLeft;
}
}
@ -2346,34 +2342,19 @@ namespace MWMechanics
vec.y() *= std::sqrt(1.0f - swimUpwardCoef * swimUpwardCoef);
}
// Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering
if (isPlayer)
if (isBiped)
{
float threshold = mCurrentMovement.find("swim") == std::string::npos ? 0.4f : 0.8f;
float complete;
bool animPlaying = mAnimation->getInfo(mCurrentMovement, &complete);
if (movestate == CharState_None && jumpstate == JumpState_None && isTurning())
{
if (animPlaying && complete < threshold)
movestate = mMovementState;
}
}
else
{
if (isBiped)
{
if (mTurnAnimationThreshold > 0)
mTurnAnimationThreshold -= duration;
if (mTurnAnimationThreshold > 0)
mTurnAnimationThreshold -= duration;
if (movestate == CharState_TurnRight || movestate == CharState_TurnLeft
|| movestate == CharState_SwimTurnRight || movestate == CharState_SwimTurnLeft)
{
mTurnAnimationThreshold = 0.05f;
}
else if (movestate == CharState_None && isTurning() && mTurnAnimationThreshold > 0)
{
movestate = mMovementState;
}
if (movestate == CharState_TurnRight || movestate == CharState_TurnLeft
|| movestate == CharState_SwimTurnRight || movestate == CharState_SwimTurnLeft)
{
mTurnAnimationThreshold = 0.05f;
}
else if (movestate == CharState_None && isTurning() && mTurnAnimationThreshold > 0)
{
movestate = mMovementState;
}
}
@ -2402,11 +2383,10 @@ namespace MWMechanics
if (isTurning())
{
// Adjust animation speed from 1.0 to 1.5 multiplier
if (duration > 0)
{
float turnSpeed = std::min(1.5f, std::abs(rot.z()) / duration / static_cast<float>(osg::PI));
mAnimation->adjustSpeedMult(mCurrentMovement, std::max(turnSpeed, 1.0f));
mAnimation->adjustSpeedMult(mCurrentMovement, turnSpeed);
}
}
else if (mMovementState != CharState_None && mAdjustMovementAnimSpeed)

View file

@ -215,10 +215,6 @@ namespace MWMechanics
bool hasDuration = !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration);
effect.mDuration = hasDuration ? static_cast<float>(enam.mData.mDuration) : 1.f;
bool appliedOnce = magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce;
if (!appliedOnce)
effect.mDuration = std::max(1.f, effect.mDuration);
effect.mTimeLeft = effect.mDuration;
// add to list of active effects, to apply in next frame

View file

@ -1011,11 +1011,13 @@ namespace MWMechanics
else
{
// Morrowind.exe doesn't apply magic effects while the menu is open, we do because we like to see stats
// updated instantly. We don't want to teleport instantly though
// updated instantly. We don't want to teleport instantly though. Nor do we want to force players to drink
// invisibility potions in the "right" order
if (!dt
&& (effect.mEffectId == ESM::MagicEffect::Recall
|| effect.mEffectId == ESM::MagicEffect::DivineIntervention
|| effect.mEffectId == ESM::MagicEffect::AlmsiviIntervention))
|| effect.mEffectId == ESM::MagicEffect::AlmsiviIntervention
|| effect.mEffectId == ESM::MagicEffect::Invisibility))
return { MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth };
auto& stats = target.getClass().getCreatureStats(target);
auto& magnitudes = stats.getMagicEffects();

View file

@ -943,8 +943,8 @@ namespace MWRender
stateUpdater->setIsUnderwater(isUnderwater);
stateUpdater->setFogColor(fogColor);
stateUpdater->setGameHour(world->getTimeStamp().getHour());
stateUpdater->setWeatherId(world->getCurrentWeather());
stateUpdater->setNextWeatherId(world->getNextWeather());
stateUpdater->setWeatherId(world->getCurrentWeatherScriptId());
stateUpdater->setNextWeatherId(world->getNextWeatherScriptId());
stateUpdater->setWeatherTransition(world->getWeatherTransition());
stateUpdater->setWindSpeed(world->getWindSpeed());
stateUpdater->setSkyColor(mSky->getSkyColor());

View file

@ -139,6 +139,7 @@ namespace MWRender
int skyGetSecundaPhase() const;
void skySetMoonColour(bool red);
const osg::Vec4f& getSunLightPosition() const { return mSunLight->getPosition(); }
void setSunDirection(const osg::Vec3f& direction);
void setSunColour(const osg::Vec4f& diffuse, const osg::Vec4f& specular, float sunVis);
void setNight(bool isNight) { mNight = isNight; }

View file

@ -71,7 +71,7 @@ namespace MWScript
public:
void execute(Interpreter::Runtime& runtime) override
{
runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeather());
runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeatherScriptId());
}
};

View file

@ -1,5 +1,6 @@
#include "weather.hpp"
#include <components/esm/stringrefid.hpp>
#include <components/settings/values.hpp>
#include <components/misc/rng.hpp>
@ -141,9 +142,12 @@ namespace MWWorld
return direction;
}
Weather::Weather(const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset,
const std::string& particleEffect)
: mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture"))
Weather::Weather(ESM::RefId id, int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed,
float dlFactor, float dlOffset, const std::string& particleEffect)
: mId(id)
, mScriptId(scriptId)
, mName(name)
, mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture"))
, mSkyColor(Fallback::Map::getColour("Weather_" + name + "_Sky_Sunrise_Color"),
Fallback::Map::getColour("Weather_" + name + "_Sky_Day_Color"),
Fallback::Map::getColour("Weather_" + name + "_Sky_Sunset_Color"),
@ -676,6 +680,41 @@ namespace MWWorld
stopSounds();
}
const Weather* WeatherManager::getWeather(size_t index) const
{
if (index < mWeatherSettings.size())
return &mWeatherSettings[index];
return nullptr;
}
const Weather* WeatherManager::getWeather(const ESM::RefId& id) const
{
auto it = std::find_if(
mWeatherSettings.begin(), mWeatherSettings.end(), [id](const auto& weather) { return weather.mId == id; });
if (it != mWeatherSettings.end())
return &*it;
return nullptr;
}
void WeatherManager::changeWeather(const ESM::RefId& regionID, const ESM::RefId& weatherID)
{
auto wIt = std::find_if(mWeatherSettings.begin(), mWeatherSettings.end(),
[weatherID](const auto& weather) { return weather.mId == weatherID; });
if (wIt != mWeatherSettings.end())
{
auto rIt = mRegions.find(regionID);
if (rIt != mRegions.end())
{
rIt->second.setWeather(std::distance(mWeatherSettings.begin(), wIt));
regionalWeatherChanged(rIt->first, rIt->second);
}
}
}
void WeatherManager::changeWeather(const ESM::RefId& regionID, const unsigned int weatherID)
{
// In Morrowind, this seems to have the following behavior, when applied to the current region:
@ -1053,8 +1092,9 @@ namespace MWWorld
const std::string& name, float dlFactor, float dlOffset, const std::string& particleEffect)
{
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->mValue.getFloat();
Weather weather(name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect);
ESM::StringRefId id(name);
Weather weather(
id, mWeatherSettings.size(), name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect);
mWeatherSettings.push_back(weather);
}

View file

@ -109,6 +109,11 @@ namespace MWWorld
T getValue(const float gameHour, const TimeOfDaySettings& timeSettings, const std::string& prefix) const;
const T& getSunriseValue() const { return mSunriseValue; }
const T& getDayValue() const { return mDayValue; }
const T& getSunsetValue() const { return mSunsetValue; }
const T& getNightValue() const { return mNightValue; }
private:
T mSunriseValue, mDayValue, mSunsetValue, mNightValue;
};
@ -119,9 +124,12 @@ namespace MWWorld
public:
static osg::Vec3f defaultDirection();
Weather(const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset,
const std::string& particleEffect);
Weather(const ESM::RefId id, const int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed,
float dlFactor, float dlOffset, const std::string& particleEffect);
ESM::RefId mId;
int mScriptId;
std::string mName;
std::string mCloudTexture;
// Sky (atmosphere) color
@ -289,11 +297,12 @@ namespace MWWorld
~WeatherManager();
/**
* Change the weather in the specified region
* Change the weather in the specified region by id of the weather
* @param region that should be changed
* @param ID of the weather setting to shift to
*/
void changeWeather(const ESM::RefId& regionID, const unsigned int weatherID);
void changeWeather(const ESM::RefId& regionID, const ESM::RefId& weatherID);
void modRegion(const ESM::RefId& regionID, const std::vector<uint8_t>& chances);
void playerTeleported(const ESM::RefId& playerRegion, bool isExterior);
@ -316,8 +325,23 @@ namespace MWWorld
void advanceTime(double hours, bool incremental);
const std::vector<Weather>& getAllWeather() { return mWeatherSettings; }
const Weather& getWeather() { return mWeatherSettings[mCurrentWeather]; }
const Weather* getWeather(size_t index) const;
const Weather* getWeather(const ESM::RefId& id) const;
int getWeatherID() const { return mCurrentWeather; }
const Weather* getNextWeather()
{
if (mNextWeather > -1)
return &mWeatherSettings[mNextWeather];
return nullptr;
}
int getNextWeatherID() const { return mNextWeather; }
float getTransitionFactor() const { return mTransitionFactor; }

View file

@ -1868,14 +1868,43 @@ namespace MWWorld
return ESM::Cell::sDefaultWorldspaceId;
}
int World::getCurrentWeather() const
const std::vector<MWWorld::Weather>& World::getAllWeather() const
{
return mWeatherManager->getWeatherID();
return mWeatherManager->getAllWeather();
}
int World::getNextWeather() const
int World::getCurrentWeatherScriptId() const
{
return mWeatherManager->getNextWeatherID();
return mWeatherManager->getWeather().mScriptId;
}
const MWWorld::Weather& World::getCurrentWeather() const
{
return mWeatherManager->getWeather();
}
const MWWorld::Weather* World::getWeather(size_t index) const
{
return mWeatherManager->getWeather(index);
}
const MWWorld::Weather* World::getWeather(const ESM::RefId& id) const
{
return mWeatherManager->getWeather(id);
}
int World::getNextWeatherScriptId() const
{
auto next = mWeatherManager->getNextWeather();
if (next == nullptr)
return -1;
return next->mScriptId;
}
const MWWorld::Weather* World::getNextWeather() const
{
return mWeatherManager->getNextWeather();
}
float World::getWeatherTransition() const
@ -1893,6 +1922,11 @@ namespace MWWorld
mWeatherManager->changeWeather(region, id);
}
void World::changeWeather(const ESM::RefId& region, const ESM::RefId& id)
{
mWeatherManager->changeWeather(region, id);
}
void World::modRegion(const ESM::RefId& regionid, const std::vector<uint8_t>& chances)
{
mWeatherManager->modRegion(regionid, chances);
@ -3133,6 +3167,11 @@ namespace MWWorld
}
}
const osg::Vec4f& World::getSunLightPosition() const
{
return mRendering->getSunLightPosition();
}
float World::getSunVisibility() const
{
return mWeatherManager->getSunVisibility();

View file

@ -317,9 +317,16 @@ namespace MWWorld
void changeWeather(const ESM::RefId& region, const unsigned int id) override;
int getCurrentWeather() const override;
void changeWeather(const ESM::RefId& region, const ESM::RefId& id) override;
int getNextWeather() const override;
const std::vector<MWWorld::Weather>& getAllWeather() const override;
int getCurrentWeatherScriptId() const override;
const MWWorld::Weather& getCurrentWeather() const override;
const MWWorld::Weather* getWeather(size_t index) const override;
const MWWorld::Weather* getWeather(const ESM::RefId& id) const override;
int getNextWeatherScriptId() const override;
const MWWorld::Weather* getNextWeather() const override;
float getWeatherTransition() const override;
@ -573,6 +580,7 @@ namespace MWWorld
// Allow NPCs to use torches?
bool useTorches() const override;
const osg::Vec4f& getSunLightPosition() const override;
float getSunVisibility() const override;
float getSunPercentage() const override;

View file

@ -7,6 +7,7 @@
#include <components/esm3/loadnpc.hpp>
#include <components/esm3/readerscache.hpp>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace MWWorld
@ -36,7 +37,7 @@ namespace MWWorld
LiveCellRef<ESM::NPC> liveCellRef(cellRef, &npc);
liveCellRef.mData.setDeletedByContentFile(true);
Ptr ptr(&liveCellRef);
EXPECT_EQ(ptr.toString(), "deleted object0xd00002a (NPC, \"player\")");
EXPECT_THAT(ptr.toString(), StrCaseEq("deleted object0xd00002a (NPC, \"player\")"));
}
TEST(MWWorldPtrTest, toStringShouldReturnHumanReadableTextRepresentationOfPtr)
@ -53,7 +54,7 @@ namespace MWWorld
cellRef.mRefNum = ESM::RefNum{ .mIndex = 0x2a, .mContentFile = 0xd };
LiveCellRef<ESM::NPC> liveCellRef(cellRef, &npc);
Ptr ptr(&liveCellRef);
EXPECT_EQ(ptr.toString(), "object0xd00002a (NPC, \"player\")");
EXPECT_THAT(ptr.toString(), StrCaseEq("object0xd00002a (NPC, \"player\")"));
}
TEST(MWWorldPtrTest, underlyingLiveCellRefShouldBeDeregisteredOnDestruction)

View file

@ -18,37 +18,33 @@ namespace Files
namespace bpo = boost::program_options;
namespace
{
#if defined(_WIN32) || defined(__WINDOWS__)
static const char* const applicationName = "OpenMW";
constexpr auto applicationName = "OpenMW";
#else
static const char* const applicationName = "openmw";
constexpr auto applicationName = "openmw";
#endif
static constexpr auto localToken = u8"?local?";
static constexpr auto userConfigToken = u8"?userconfig?";
static constexpr auto userDataToken = u8"?userdata?";
static constexpr auto globalToken = u8"?global?";
using GetPath = const std::filesystem::path& (Files::FixedPath<>::*)() const;
constexpr std::array<std::pair<std::u8string_view, GetPath>, 4> sTokenMappings = {
std::make_pair(u8"?local?", &FixedPath<>::getLocalPath),
std::make_pair(u8"?userconfig?", &FixedPath<>::getUserConfigPath),
std::make_pair(u8"?userdata?", &FixedPath<>::getUserDataPath),
std::make_pair(u8"?global?", &FixedPath<>::getGlobalDataPath),
};
}
ConfigurationManager::ConfigurationManager(bool silent)
: mFixedPath(applicationName)
, mSilent(silent)
{
setupTokensMapping();
// Initialize with fixed paths, will be overridden in `readConfiguration`.
mUserDataPath = mFixedPath.getUserDataPath();
mScreenshotPath = mFixedPath.getUserDataPath() / "screenshots";
}
ConfigurationManager::~ConfigurationManager() {}
void ConfigurationManager::setupTokensMapping()
{
mTokensMapping.insert(std::make_pair(localToken, &FixedPath<>::getLocalPath));
mTokensMapping.insert(std::make_pair(userConfigToken, &FixedPath<>::getUserConfigPath));
mTokensMapping.insert(std::make_pair(userDataToken, &FixedPath<>::getUserDataPath));
mTokensMapping.insert(std::make_pair(globalToken, &FixedPath<>::getGlobalDataPath));
}
ConfigurationManager::~ConfigurationManager() = default;
static bool hasReplaceConfig(const bpo::variables_map& variables)
{
@ -74,7 +70,7 @@ namespace Files
std::optional<bpo::variables_map> config = loadConfig(mFixedPath.getLocalPath(), description);
if (config)
mActiveConfigPaths.push_back(mFixedPath.getLocalPath());
else
else if (!mFixedPath.getGlobalConfigPath().empty())
{
mActiveConfigPaths.push_back(mFixedPath.getGlobalConfigPath());
config = loadConfig(mFixedPath.getGlobalConfigPath(), description);
@ -305,15 +301,18 @@ namespace Files
const auto pos = str.find('?', 1);
if (pos != std::u8string::npos && pos != 0)
{
auto tokenIt = mTokensMapping.find(str.substr(0, pos + 1));
if (tokenIt != mTokensMapping.end())
std::u8string_view view(str);
auto token = view.substr(0, pos + 1);
auto found = std::find_if(
sTokenMappings.begin(), sTokenMappings.end(), [&](const auto& item) { return item.first == token; });
if (found != sTokenMappings.end())
{
auto tempPath(((mFixedPath).*(tokenIt->second))());
if (pos < str.length() - 1)
auto tempPath(((mFixedPath).*(found->second))());
if (!tempPath.empty() && pos < view.length() - 1)
{
// There is something after the token, so we should
// append it to the path
tempPath /= str.substr(pos + 1, str.length() - pos);
tempPath /= view.substr(pos + 1, view.length() - pos);
}
path = std::move(tempPath);

View file

@ -62,17 +62,12 @@ namespace Files
private:
typedef Files::FixedPath<> FixedPathType;
typedef const std::filesystem::path& (FixedPathType::*path_type_f)() const;
typedef std::map<std::u8string, path_type_f> TokensMappingContainer;
std::optional<boost::program_options::variables_map> loadConfig(
const std::filesystem::path& path, const boost::program_options::options_description& description) const;
void addExtraConfigDirs(
std::stack<std::filesystem::path>& dirs, const boost::program_options::variables_map& variables) const;
void setupTokensMapping();
std::vector<std::filesystem::path> mActiveConfigPaths;
FixedPathType mFixedPath;
@ -80,8 +75,6 @@ namespace Files
std::filesystem::path mUserDataPath;
std::filesystem::path mScreenshotPath;
TokensMappingContainer mTokensMapping;
bool mSilent;
};

View file

@ -8,21 +8,11 @@
namespace Files
{
inline QString getLocalConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{
return Files::pathToQString(cfgMgr.getLocalPath() / openmwCfgFile);
}
inline QString getUserConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{
return Files::pathToQString(cfgMgr.getUserConfigPath() / openmwCfgFile);
}
inline QString getGlobalConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{
return Files::pathToQString(cfgMgr.getGlobalPath() / openmwCfgFile);
}
inline QStringList getActiveConfigPathsQString(const Files::ConfigurationManager& cfgMgr)
{
const auto& activePaths = cfgMgr.getActiveConfigPaths();

View file

@ -54,19 +54,7 @@ namespace Files
{
// The concept of a global config path is absurd on Windows.
// Always use local config instead.
// The virtual base class requires that we provide this, though.
std::filesystem::path globalPath = std::filesystem::current_path();
PWSTR cString;
HRESULT result = SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, nullptr, &cString);
if (SUCCEEDED(result))
globalPath = std::filesystem::path(cString);
else
Log(Debug::Error) << "Error " << result << " when getting Program Files path";
CoTaskMemFree(cString);
return globalPath / mName;
return {};
}
std::filesystem::path WindowsPath::getLocalPath() const

View file

@ -34,7 +34,7 @@ namespace Files
std::filesystem::path getUserDataPath() const;
/**
* \brief Returns "X:\Program Files\"
* \brief Returns an empty path
*
* \return std::filesystem::path
*/

View file

@ -1,5 +1,8 @@
The code in this directory is copied from https://github.com/ThePhD/sol2.git (64096348465b980e2f1d0e5ba9cbeea8782e8f27)
The code in this directory is copied from https://github.com/ThePhD/sol2.git (c1f95a773c6f8f4fde8ca3efe872e7286afe4444) and has been patched to include
Additional changes include cherry-picking upstream commit d805d027e0a0a7222e936926139f06e23828ce9f to fix compilation under Clang 19.
https://github.com/ThePhD/sol2/pull/1674 (71d85143ad69164f5f52c3bdab91fb503c676eb4)
https://github.com/ThePhD/sol2/pull/1676 (a6872ef46b08704b9069ebf83161f4637459ce63)
https://github.com/ThePhD/sol2/pull/1716 (5b6881ed94c795298eae72b6848308e9a37e42c5)
https://github.com/ThePhD/sol2/pull/1722 (ab874eb0e8ef8aea4c10074a89efa25f62a29d9a)
License: MIT

47
extern/sol3/sol/abort.hpp vendored Normal file
View file

@ -0,0 +1,47 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_ABORT_HPP
#define SOL_ABORT_HPP
#include <sol/version.hpp>
#include <sol/base_traits.hpp>
#include <cstdlib>
// clang-format off
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#define SOL_DEBUG_ABORT() \
if (true) { ::std::abort(); } \
static_assert(true, "")
#else
#define SOL_DEBUG_ABORT() ::std::abort()
#endif
#else
#define SOL_DEBUG_ABORT() static_assert(true, "")
#endif
// clang-format on
#endif // SOL_ABORT_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -1,99 +1,99 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
#ifndef SOL_ASSERT_HPP
#define SOL_ASSERT_HPP
#include <sol/forward.hpp>
#if SOL_IS_ON(SOL2_CI_I_)
struct pre_main {
pre_main() {
#ifdef _MSC_VER
_set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif
}
} inline sol2_ci_dont_lock_ci_please = {};
#endif // Prevent lockup when doing Continuous Integration
// clang-format off
#if SOL_IS_ON(SOL_USER_C_ASSERT_I_)
#define sol_c_assert(...) SOL_C_ASSERT(__VA_ARGS__)
#else
#if SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#include <exception>
#include <iostream>
#include <cstdlib>
#define sol_c_assert(...) \
do { \
if (!(__VA_ARGS__)) { \
std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \
std::terminate(); \
} \
} while (false)
#else
#define sol_c_assert(...) \
do { \
if (false) { \
(void)(__VA_ARGS__); \
} \
} while (false)
#endif
#endif
#if SOL_IS_ON(SOL_USER_M_ASSERT_I_)
#define sol_m_assert(message, ...) SOL_M_ASSERT(message, __VA_ARGS__)
#else
#if SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#include <exception>
#include <iostream>
#include <cstdlib>
#define sol_m_assert(message, ...) \
do { \
if (!(__VA_ARGS__)) { \
std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \
std::terminate(); \
} \
} while (false)
#else
#define sol_m_assert(message, ...) \
do { \
if (false) { \
(void)(__VA_ARGS__); \
(void)sizeof(message); \
} \
} while (false)
#endif
#endif
// clang-format on
#endif // SOL_ASSERT_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
#ifndef SOL_ASSERT_HPP
#define SOL_ASSERT_HPP
#include <sol/forward.hpp>
#if SOL_IS_ON(SOL2_CI)
struct pre_main {
pre_main() {
#ifdef _MSC_VER
_set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif
}
} inline sol2_ci_dont_lock_ci_please = {};
#endif // Prevent lockup when doing Continuous Integration
// clang-format off
#if SOL_IS_ON(SOL_USER_ASSERT)
#define SOL_ASSERT(...) SOL_C_ASSERT(__VA_ARGS__)
#else
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#include <exception>
#include <iostream>
#include <cstdlib>
#define SOL_ASSERT(...) \
do { \
if (!(__VA_ARGS__)) { \
std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \
std::terminate(); \
} \
} while (false)
#else
#define SOL_ASSERT(...) \
do { \
if (false) { \
(void)(__VA_ARGS__); \
} \
} while (false)
#endif
#endif
#if SOL_IS_ON(SOL_USER_ASSERT_MSG)
#define SOL_ASSERT_MSG(message, ...) SOL_ASSERT_MSG(message, __VA_ARGS__)
#else
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#include <exception>
#include <iostream>
#include <cstdlib>
#define SOL_ASSERT_MSG(message, ...) \
do { \
if (!(__VA_ARGS__)) { \
std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \
std::terminate(); \
} \
} while (false)
#else
#define SOL_ASSERT_MSG(message, ...) \
do { \
if (false) { \
(void)(__VA_ARGS__); \
(void)sizeof(message); \
} \
} while (false)
#endif
#endif
// clang-format on
#endif // SOL_ASSERT_HPP

View file

@ -1,123 +1,156 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_BASE_TRAITS_HPP
#define SOL_BASE_TRAITS_HPP
#include <type_traits>
namespace sol {
namespace detail {
struct unchecked_t { };
const unchecked_t unchecked = unchecked_t {};
} // namespace detail
namespace meta {
using sfinae_yes_t = std::true_type;
using sfinae_no_t = std::false_type;
template <typename...>
using void_t = void;
template <typename T>
using unqualified = std::remove_cv<std::remove_reference_t<T>>;
template <typename T>
using unqualified_t = typename unqualified<T>::type;
namespace meta_detail {
template <typename T>
struct unqualified_non_alias : unqualified<T> { };
template <template <class...> class Test, class, class... Args>
struct is_detected : std::false_type { };
template <template <class...> class Test, class... Args>
struct is_detected<Test, void_t<Test<Args...>>, Args...> : std::true_type { };
} // namespace meta_detail
template <template <class...> class Trait, class... Args>
using is_detected = typename meta_detail::is_detected<Trait, void, Args...>::type;
template <template <class...> class Trait, class... Args>
constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
template <std::size_t I>
using index_value = std::integral_constant<std::size_t, I>;
template <bool>
struct conditional {
template <typename T, typename U>
using type = T;
};
template <>
struct conditional<false> {
template <typename T, typename U>
using type = U;
};
template <bool B, typename T, typename U>
using conditional_t = typename conditional<B>::template type<T, U>;
namespace meta_detail {
template <typename T, template <typename...> class Templ>
struct is_specialization_of : std::false_type { };
template <typename... T, template <typename...> class Templ>
struct is_specialization_of<Templ<T...>, Templ> : std::true_type { };
} // namespace meta_detail
template <typename T, template <typename...> class Templ>
using is_specialization_of = meta_detail::is_specialization_of<std::remove_cv_t<T>, Templ>;
template <typename T, template <typename...> class Templ>
inline constexpr bool is_specialization_of_v = is_specialization_of<std::remove_cv_t<T>, Templ>::value;
template <typename T>
struct identity {
typedef T type;
};
template <typename T>
using identity_t = typename identity<T>::type;
template <typename T>
using is_builtin_type = std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value>;
namespace meta_detail {
template <typename T, typename = void>
struct has_internal_marker_impl : std::false_type { };
template <typename T>
struct has_internal_marker_impl<T, void_t<typename T::SOL_INTERNAL_UNSPECIALIZED_MARKER_>> : std::true_type { };
template <typename T>
using has_internal_marker = has_internal_marker_impl<T>;
template <typename T>
constexpr inline bool has_internal_marker_v = has_internal_marker<T>::value;
} // namespace meta_detail
} // namespace meta
} // namespace sol
#endif // SOL_BASE_TRAITS_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_BASE_TRAITS_HPP
#define SOL_BASE_TRAITS_HPP
#include <type_traits>
namespace sol {
namespace detail {
struct unchecked_t { };
const unchecked_t unchecked = unchecked_t {};
} // namespace detail
namespace meta {
using sfinae_yes_t = std::true_type;
using sfinae_no_t = std::false_type;
template <typename...>
using void_t = void;
template <typename T>
using unqualified = std::remove_cv<std::remove_reference_t<T>>;
template <typename T>
using unqualified_t = typename unqualified<T>::type;
namespace meta_detail {
template <typename T>
struct unqualified_non_alias : unqualified<T> { };
template <template <class...> class Test, class, class... Args>
struct is_detected : std::false_type { };
template <template <class...> class Test, class... Args>
struct is_detected<Test, void_t<Test<Args...>>, Args...> : std::true_type { };
} // namespace meta_detail
template <template <class...> class Trait, class... Args>
using is_detected = typename meta_detail::is_detected<Trait, void, Args...>::type;
template <template <class...> class Trait, class... Args>
constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
template <typename _Default, typename _Void, template <typename...> typename _Op, typename... _Args>
class detector {
public:
using value_t = ::std::false_type;
using type = _Default;
};
template <typename _Default, template <typename...> typename _Op, typename... _Args>
class detector<_Default, void_t<_Op<_Args...>>, _Op, _Args...> {
public:
using value_t = ::std::true_type;
using type = _Op<_Args...>;
};
class nonesuch {
public:
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
nonesuch& operator=(nonesuch const&) = delete;
};
template <template <typename...> typename _Op, typename... _Args>
using detected_t = typename detector<nonesuch, void, _Op, _Args...>::type;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
using detected_or = detector<_Default, void, _Op, _Args...>;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
using detected_or_t = typename detector<_Default, void, _Op, _Args...>::type;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
constexpr inline bool detected_or_v = detector<_Default, void, _Op, _Args...>::value;
template <std::size_t I>
using index_value = std::integral_constant<std::size_t, I>;
template <bool>
struct conditional {
template <typename T, typename U>
using type = T;
};
template <>
struct conditional<false> {
template <typename T, typename U>
using type = U;
};
template <bool B, typename T, typename U>
using conditional_t = typename conditional<B>::template type<T, U>;
namespace meta_detail {
template <typename T, template <typename...> class Templ>
struct is_specialization_of : std::false_type { };
template <typename... T, template <typename...> class Templ>
struct is_specialization_of<Templ<T...>, Templ> : std::true_type { };
} // namespace meta_detail
template <typename T, template <typename...> class Templ>
using is_specialization_of = meta_detail::is_specialization_of<std::remove_cv_t<T>, Templ>;
template <typename T, template <typename...> class Templ>
inline constexpr bool is_specialization_of_v = is_specialization_of<std::remove_cv_t<T>, Templ>::value;
template <typename T>
struct identity {
typedef T type;
};
template <typename T>
using identity_t = typename identity<T>::type;
template <typename T>
using is_builtin_type = std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value>;
namespace meta_detail {
template <typename T, typename = void>
struct has_internal_marker_impl : std::false_type { };
template <typename T>
struct has_internal_marker_impl<T, void_t<typename T::SOL_INTERNAL_UNSPECIALIZED_MARKER_>> : std::true_type { };
template <typename T>
using has_internal_marker = has_internal_marker_impl<T>;
template <typename T>
constexpr inline bool has_internal_marker_v = has_internal_marker<T>::value;
} // namespace meta_detail
} // namespace meta
} // namespace sol
#endif // SOL_BASE_TRAITS_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -31,7 +31,7 @@
namespace sol { namespace meta {
namespace meta_detail {
template <typename F>
using detect_deducible_signature = decltype(&F::operator(), void());
using detect_deducible_signature = decltype(&F::operator());
} // namespace meta_detail
template <typename F>
@ -196,7 +196,7 @@ namespace sol { namespace meta {
typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&;
};
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <typename R, typename... Args>
struct fx_traits<R(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
@ -311,7 +311,7 @@ namespace sol { namespace meta {
#endif // noexcept is part of a function's type
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && SOL_IS_ON(SOL_PLATFORM_X86_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX) && SOL_IS_ON(SOL_PLATFORM_X86)
template <typename R, typename... Args>
struct fx_traits<R __stdcall(Args...), false> : public basic_traits<false, false, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args...);
@ -369,7 +369,7 @@ namespace sol { namespace meta {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&;
};
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <typename R, typename... Args>
struct fx_traits<R __stdcall(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {

View file

@ -1,121 +1,121 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_BYTECODE_HPP
#define SOL_BYTECODE_HPP
#include <sol/compatibility.hpp>
#include <sol/string_view.hpp>
#include <vector>
#include <cstdint>
#include <cstddef>
namespace sol {
template <typename Allocator = std::allocator<std::byte>>
class basic_bytecode : private std::vector<std::byte, Allocator> {
private:
using base_t = std::vector<std::byte, Allocator>;
public:
using typename base_t::allocator_type;
using typename base_t::const_iterator;
using typename base_t::const_pointer;
using typename base_t::const_reference;
using typename base_t::const_reverse_iterator;
using typename base_t::difference_type;
using typename base_t::iterator;
using typename base_t::pointer;
using typename base_t::reference;
using typename base_t::reverse_iterator;
using typename base_t::size_type;
using typename base_t::value_type;
using base_t::base_t;
using base_t::operator=;
using base_t::data;
using base_t::empty;
using base_t::max_size;
using base_t::size;
using base_t::at;
using base_t::operator[];
using base_t::back;
using base_t::front;
using base_t::begin;
using base_t::cbegin;
using base_t::cend;
using base_t::end;
using base_t::crbegin;
using base_t::crend;
using base_t::rbegin;
using base_t::rend;
using base_t::get_allocator;
using base_t::swap;
using base_t::clear;
using base_t::emplace;
using base_t::emplace_back;
using base_t::erase;
using base_t::insert;
using base_t::pop_back;
using base_t::push_back;
using base_t::reserve;
using base_t::resize;
using base_t::shrink_to_fit;
string_view as_string_view() const {
return string_view(reinterpret_cast<const char*>(this->data()), this->size());
}
};
template <typename Container>
inline int basic_insert_dump_writer(lua_State*, const void* memory, size_t memory_size, void* userdata_pointer) {
using storage_t = Container;
const std::byte* p_code = static_cast<const std::byte*>(memory);
storage_t& bc = *static_cast<storage_t*>(userdata_pointer);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
bc.insert(bc.cend(), p_code, p_code + memory_size);
#else
try {
bc.insert(bc.cend(), p_code, p_code + memory_size);
}
catch (...) {
return -1;
}
#endif
return 0;
}
using bytecode = basic_bytecode<>;
constexpr inline auto bytecode_dump_writer = &basic_insert_dump_writer<bytecode>;
} // namespace sol
#endif // SOL_BYTECODE_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_BYTECODE_HPP
#define SOL_BYTECODE_HPP
#include <sol/compatibility.hpp>
#include <sol/string_view.hpp>
#include <vector>
#include <cstdint>
#include <cstddef>
namespace sol {
template <typename Allocator = std::allocator<std::byte>>
class basic_bytecode : private std::vector<std::byte, Allocator> {
private:
using base_t = std::vector<std::byte, Allocator>;
public:
using typename base_t::allocator_type;
using typename base_t::const_iterator;
using typename base_t::const_pointer;
using typename base_t::const_reference;
using typename base_t::const_reverse_iterator;
using typename base_t::difference_type;
using typename base_t::iterator;
using typename base_t::pointer;
using typename base_t::reference;
using typename base_t::reverse_iterator;
using typename base_t::size_type;
using typename base_t::value_type;
using base_t::base_t;
using base_t::operator=;
using base_t::data;
using base_t::empty;
using base_t::max_size;
using base_t::size;
using base_t::at;
using base_t::operator[];
using base_t::back;
using base_t::front;
using base_t::begin;
using base_t::cbegin;
using base_t::cend;
using base_t::end;
using base_t::crbegin;
using base_t::crend;
using base_t::rbegin;
using base_t::rend;
using base_t::get_allocator;
using base_t::swap;
using base_t::clear;
using base_t::emplace;
using base_t::emplace_back;
using base_t::erase;
using base_t::insert;
using base_t::pop_back;
using base_t::push_back;
using base_t::reserve;
using base_t::resize;
using base_t::shrink_to_fit;
string_view as_string_view() const {
return string_view(reinterpret_cast<const char*>(this->data()), this->size());
}
};
template <typename Container>
inline int basic_insert_dump_writer(lua_State*, const void* memory, size_t memory_size, void* userdata_pointer) {
using storage_t = Container;
const std::byte* p_code = static_cast<const std::byte*>(memory);
storage_t& bc = *static_cast<storage_t*>(userdata_pointer);
#if SOL_IS_OFF(SOL_EXCEPTIONS)
bc.insert(bc.cend(), p_code, p_code + memory_size);
#else
try {
bc.insert(bc.cend(), p_code, p_code + memory_size);
}
catch (...) {
return -1;
}
#endif
return 0;
}
using bytecode = basic_bytecode<>;
constexpr inline auto bytecode_dump_writer = &basic_insert_dump_writer<bytecode>;
} // namespace sol
#endif // SOL_BYTECODE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -54,7 +54,7 @@ namespace sol {
lua_createtable(L, static_cast<int>(sizeof...(In)), 0);
stack_reference deps(L, -1);
auto per_dep = [&L, &deps](int i) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
lua_pushvalue(L, i);
@ -79,7 +79,7 @@ namespace sol {
}
lua_createtable(L, static_cast<int>(sdeps.size()), 0);
stack_reference deps(L, -1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, static_cast<int>(sdeps.size()), detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
for (std::size_t i = 0; i < sdeps.size(); ++i) {
@ -429,7 +429,7 @@ namespace sol {
}
};
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, clean_stack, C> {
static int call(lua_State* L, detail::lua_CFunction_noexcept f) {
@ -478,12 +478,13 @@ namespace sol {
using object_type = typename wrap::object_type;
if constexpr (sizeof...(Args) < 1) {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
static_assert(std::is_base_of_v<object_type, Ta>,
static_assert(std::is_same_v<object_type, Ta> || std::is_base_of_v<object_type, Ta>,
"It seems like you might have accidentally bound a class type with a member function method that does not correspond to the "
"class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" "
"but then bind member methods from a complete unrelated class. Check things over!");
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
auto maybeo = stack::check_get<Ta*>(L, 1);
#if SOL_IS_ON(SOL_SAFE_USERTYPE)
stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) {
return luaL_error(L,
"sol: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are "
@ -511,12 +512,13 @@ namespace sol {
if constexpr (is_index) {
if constexpr (sizeof...(Args) < 1) {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
static_assert(std::is_base_of_v<object_type, Ta>,
static_assert(std::is_same_v<object_type, Ta> || std::is_base_of_v<object_type, Ta>,
"It seems like you might have accidentally bound a class type with a member function method that does not correspond "
"to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one "
"class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
auto maybeo = stack::check_get<Ta*>(L, 1);
#if SOL_IS_ON(SOL_SAFE_USERTYPE)
stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) {
return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
@ -573,8 +575,9 @@ namespace sol {
}
else {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
auto maybeo = stack::check_get<Ta*>(L, 1);
#if SOL_IS_ON(SOL_SAFE_USERTYPE)
stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) {
return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)");
@ -811,8 +814,9 @@ namespace sol {
using args_list = meta::pop_front_type_t<typename traits_type::free_args_list>;
using Ta = T;
using Oa = std::remove_pointer_t<object_type>;
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
auto maybeo = stack::check_get<Ta*>(L, 1);
#if SOL_IS_ON(SOL_SAFE_USERTYPE)
stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) {
return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -32,20 +32,20 @@
#include <sol/version.hpp>
#include <sol/compatibility/lua_version.hpp>
#if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER_I_)
#if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER)
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
#ifndef COMPAT53_LUA_CPP
#define COMPAT53_LUA_CPP 1
#endif // Build Lua Compat layer as C++
// clang-format off
#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#ifndef COMPAT53_LUA_CPP
#define COMPAT53_LUA_CPP 1
#endif // Build Lua Compat layer as C++
#endif
#ifndef COMPAT53_INCLUDE_SOURCE
#define COMPAT53_INCLUDE_SOURCE 1
#endif // Build Compat Layer Inline
#include <sol/compatibility/compat-5.3.h>
#include <sol/compatibility/compat-5.4.h>
#ifndef COMPAT53_INCLUDE_SOURCE
#define COMPAT53_INCLUDE_SOURCE 1
#endif // Build Compat Layer Inline
#include <sol/compatibility/compat-5.3.h>
#include <sol/compatibility/compat-5.4.h>
#endif
// clang-format on
#endif // SOL_COMPATIBILITY_HPP

File diff suppressed because it is too large Load diff

View file

@ -1,424 +1,430 @@
#ifndef KEPLER_PROJECT_COMPAT53_H_
#define KEPLER_PROJECT_COMPAT53_H_
#include <stddef.h>
#include <limits.h>
#include <string.h>
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
extern "C" {
#endif
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
}
#endif
#ifndef COMPAT53_PREFIX
/* we chose this name because many other lua bindings / libs have
* their own compatibility layer, and that use the compat53 declaration
* frequently, causing all kinds of linker / compiler issues
*/
# define COMPAT53_PREFIX kp_compat53
#endif // COMPAT53_PREFIX
#ifndef COMPAT53_API
# if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE
# if defined(__GNUC__) || defined(__clang__)
# define COMPAT53_API __attribute__((__unused__)) static inline
# else
# define COMPAT53_API static inline
# endif /* Clang/GCC */
# else /* COMPAT53_INCLUDE_SOURCE */
/* we are not including source, so everything is extern */
# define COMPAT53_API extern
# endif /* COMPAT53_INCLUDE_SOURCE */
#endif /* COMPAT53_PREFIX */
#define COMPAT53_CONCAT_HELPER(a, b) a##b
#define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b)
/* declarations for Lua 5.1 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
/* XXX not implemented:
* lua_arith (new operators)
* lua_upvalueid
* lua_upvaluejoin
* lua_version
* lua_yieldk
*/
#ifndef LUA_OK
# define LUA_OK 0
#endif
#ifndef LUA_OPADD
# define LUA_OPADD 0
#endif
#ifndef LUA_OPSUB
# define LUA_OPSUB 1
#endif
#ifndef LUA_OPMUL
# define LUA_OPMUL 2
#endif
#ifndef LUA_OPDIV
# define LUA_OPDIV 3
#endif
#ifndef LUA_OPMOD
# define LUA_OPMOD 4
#endif
#ifndef LUA_OPPOW
# define LUA_OPPOW 5
#endif
#ifndef LUA_OPUNM
# define LUA_OPUNM 6
#endif
#ifndef LUA_OPEQ
# define LUA_OPEQ 0
#endif
#ifndef LUA_OPLT
# define LUA_OPLT 1
#endif
#ifndef LUA_OPLE
# define LUA_OPLE 2
#endif
/* LuaJIT/Lua 5.1 does not have the updated
* error codes for thread status/function returns (but some patched versions do)
* define it only if it's not found
*/
#if !defined(LUA_ERRGCMM)
/* Use + 2 because in some versions of Lua (Lua 5.1)
* LUA_ERRFILE is defined as (LUA_ERRERR+1)
* so we need to avoid it (LuaJIT might have something at this
* integer value too)
*/
# define LUA_ERRGCMM (LUA_ERRERR + 2)
#endif /* LUA_ERRGCMM define */
#if !defined(MOONJIT_VERSION)
typedef size_t lua_Unsigned;
#endif
typedef struct luaL_Buffer_53 {
luaL_Buffer b; /* make incorrect code crash! */
char *ptr;
size_t nelems;
size_t capacity;
lua_State *L2;
} luaL_Buffer_53;
#define luaL_Buffer luaL_Buffer_53
/* In PUC-Rio 5.1, userdata is a simple FILE*
* In LuaJIT, it's a struct where the first member is a FILE*
* We can't support the `closef` member
*/
typedef struct luaL_Stream {
FILE *f;
} luaL_Stream;
#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
COMPAT53_API int lua_absindex(lua_State *L, int i);
#define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith)
COMPAT53_API void lua_arith(lua_State *L, int op);
#define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare)
COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op);
#define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy)
COMPAT53_API void lua_copy(lua_State *L, int from, int to);
#define lua_getuservalue(L, i) \
(lua_getfenv((L), (i)), lua_type((L), -1))
#define lua_setuservalue(L, i) \
(luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i)))
#define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
COMPAT53_API void lua_len(lua_State *L, int i);
#define lua_pushstring(L, s) \
(lua_pushstring((L), (s)), lua_tostring((L), -1))
#define lua_pushlstring(L, s, len) \
((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1))
#ifndef luaL_newlibtable
# define luaL_newlibtable(L, l) \
(lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
#endif
#ifndef luaL_newlib
# define luaL_newlib(L, l) \
(luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l)))
#endif
#ifndef lua_pushglobaltable
# define lua_pushglobaltable(L) \
lua_pushvalue((L), LUA_GLOBALSINDEX)
#endif
#define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp)
COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p);
#define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp)
COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p);
#define lua_rawlen(L, i) lua_objlen((L), (i))
#define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
#define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx)
COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
#define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
COMPAT53_API void luaL_checkversion(lua_State *L);
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
#define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode);
#define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx)
COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
#define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53)
COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg);
#define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable)
COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char *name);
#define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len)
COMPAT53_API lua_Integer luaL_len(lua_State *L, int i);
#define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs)
COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
#define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable)
COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname);
#define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata)
COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname);
#define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback)
COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
#define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult)
COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
#define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult)
COMPAT53_API int luaL_execresult(lua_State *L, int stat);
#define lua_callk(L, na, nr, ctx, cont) \
((void)(ctx), (void)(cont), lua_call((L), (na), (nr)))
#define lua_pcallk(L, na, nr, err, ctx, cont) \
((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err)))
#define lua_resume(L, from, nargs) \
((void)(from), lua_resume((L), (nargs)))
#define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B);
#define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s);
#define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l);
#define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B);
#define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
COMPAT53_API void luaL_pushresult(luaL_Buffer_53 *B);
#undef luaL_buffinitsize
#define luaL_buffinitsize(L, B, s) \
(luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
#undef luaL_prepbuffer
#define luaL_prepbuffer(B) \
luaL_prepbuffsize((B), LUAL_BUFFERSIZE)
#undef luaL_addchar
#define luaL_addchar(B, c) \
((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \
((B)->ptr[(B)->nelems++] = (c)))
#undef luaL_addsize
#define luaL_addsize(B, s) \
((B)->nelems += (s))
#undef luaL_addstring
#define luaL_addstring(B, s) \
luaL_addlstring((B), (s), strlen((s)))
#undef luaL_pushresultsize
#define luaL_pushresultsize(B, s) \
(luaL_addsize((B), (s)), luaL_pushresult((B)))
#if defined(LUA_COMPAT_APIINTCASTS)
#define lua_pushunsigned(L, n) \
lua_pushinteger((L), (lua_Integer)(n))
#define lua_tounsignedx(L, i, is) \
((lua_Unsigned)lua_tointegerx((L), (i), (is)))
#define lua_tounsigned(L, i) \
lua_tounsignedx((L), (i), NULL)
#define luaL_checkunsigned(L, a) \
((lua_Unsigned)luaL_checkinteger((L), (a)))
#define luaL_optunsigned(L, a, d) \
((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d)))
#endif
#endif /* Lua 5.1 only */
/* declarations for Lua 5.1 and 5.2 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
typedef int lua_KContext;
typedef int(*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
#define lua_dump(L, w, d, s) \
((void)(s), lua_dump((L), (w), (d)))
#define lua_getfield(L, i, k) \
(lua_getfield((L), (i), (k)), lua_type((L), -1))
#define lua_gettable(L, i) \
(lua_gettable((L), (i)), lua_type((L), -1))
#define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti)
COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i);
#define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger)
COMPAT53_API int lua_isinteger(lua_State *L, int index);
#define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53)
COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
#define lua_numbertointeger(n, p) \
((*(p) = (lua_Integer)(n)), 1)
#define lua_rawget(L, i) \
(lua_rawget((L), (i)), lua_type((L), -1))
#define lua_rawgeti(L, i, n) \
(lua_rawgeti((L), (i), (n)), lua_type((L), -1))
#define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate)
COMPAT53_API void lua_rotate(lua_State *L, int idx, int n);
#define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti)
COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i);
#define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber)
COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s);
#define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring)
COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
#define luaL_getmetafield(L, o, e) \
(luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL)
#define luaL_newmetatable(L, tn) \
(luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0)
#define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
COMPAT53_API void luaL_requiref(lua_State *L, const char *modname,
lua_CFunction openf, int glb);
#endif /* Lua 5.1 and Lua 5.2 */
/* declarations for Lua 5.2 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
/* XXX not implemented:
* lua_isyieldable
* lua_getextraspace
* lua_arith (new operators)
* lua_pushfstring (new formats)
*/
#define lua_getglobal(L, n) \
(lua_getglobal((L), (n)), lua_type((L), -1))
#define lua_getuservalue(L, i) \
(lua_getuservalue((L), (i)), lua_type((L), -1))
#define lua_pushlstring(L, s, len) \
(((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len)))
#define lua_rawgetp(L, i, p) \
(lua_rawgetp((L), (i), (p)), lua_type((L), -1))
#define LUA_KFUNCTION(_name) \
static int (_name)(lua_State *L, int status, lua_KContext ctx); \
static int (_name ## _52)(lua_State *L) { \
lua_KContext ctx; \
int status = lua_getctx(L, &ctx); \
return (_name)(L, status, ctx); \
} \
static int (_name)(lua_State *L, int status, lua_KContext ctx)
#define lua_pcallk(L, na, nr, err, ctx, cont) \
lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52)
#define lua_callk(L, na, nr, ctx, cont) \
lua_callk((L), (na), (nr), (ctx), cont ## _52)
#define lua_yieldk(L, nr, ctx, cont) \
lua_yieldk((L), (nr), (ctx), cont ## _52)
#ifdef lua_call
# undef lua_call
# define lua_call(L, na, nr) \
(lua_callk)((L), (na), (nr), 0, NULL)
#endif
#ifdef lua_pcall
# undef lua_pcall
# define lua_pcall(L, na, nr, err) \
(lua_pcallk)((L), (na), (nr), (err), 0, NULL)
#endif
#ifdef lua_yield
# undef lua_yield
# define lua_yield(L, nr) \
(lua_yieldk)((L), (nr), 0, NULL)
#endif
#endif /* Lua 5.2 only */
/* other Lua versions */
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
# error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)"
#endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */
/* helper macro for defining continuation functions (for every version
* *except* Lua 5.2) */
#ifndef LUA_KFUNCTION
#define LUA_KFUNCTION(_name) \
static int (_name)(lua_State *L, int status, lua_KContext ctx)
#endif
#if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE == 1
# include "compat-5.3.c.h"
#endif
#endif /* KEPLER_PROJECT_COMPAT53_H_ */
#ifndef KEPLER_PROJECT_COMPAT53_H_
#define KEPLER_PROJECT_COMPAT53_H_
#include <stddef.h>
#include <limits.h>
#include <string.h>
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
extern "C" {
#endif
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
}
#endif
#ifndef COMPAT53_PREFIX
/* we chose this name because many other lua bindings / libs have
* their own compatibility layer, and that use the compat53 declaration
* frequently, causing all kinds of linker / compiler issues
*/
# define COMPAT53_PREFIX kp_compat53
#endif // COMPAT53_PREFIX
#ifndef COMPAT53_API
# if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE
# if defined(__GNUC__) || defined(__clang__)
# define COMPAT53_API __attribute__((__unused__)) static inline
# else
# define COMPAT53_API static inline
# endif /* Clang/GCC */
# else /* COMPAT53_INCLUDE_SOURCE */
/* we are not including source, so everything is extern */
# define COMPAT53_API extern
# endif /* COMPAT53_INCLUDE_SOURCE */
#endif /* COMPAT53_PREFIX */
#define COMPAT53_CONCAT_HELPER(a, b) a##b
#define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b)
/* declarations for Lua 5.1 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
/* XXX not implemented:
* lua_arith (new operators)
* lua_upvalueid
* lua_upvaluejoin
* lua_version
* lua_yieldk
*/
#ifndef LUA_OK
# define LUA_OK 0
#endif
#ifndef LUA_OPADD
# define LUA_OPADD 0
#endif
#ifndef LUA_OPSUB
# define LUA_OPSUB 1
#endif
#ifndef LUA_OPMUL
# define LUA_OPMUL 2
#endif
#ifndef LUA_OPDIV
# define LUA_OPDIV 3
#endif
#ifndef LUA_OPMOD
# define LUA_OPMOD 4
#endif
#ifndef LUA_OPPOW
# define LUA_OPPOW 5
#endif
#ifndef LUA_OPUNM
# define LUA_OPUNM 6
#endif
#ifndef LUA_OPEQ
# define LUA_OPEQ 0
#endif
#ifndef LUA_OPLT
# define LUA_OPLT 1
#endif
#ifndef LUA_OPLE
# define LUA_OPLE 2
#endif
/* LuaJIT/Lua 5.1 does not have the updated
* error codes for thread status/function returns (but some patched versions do)
* define it only if it's not found
*/
#if !defined(LUA_ERRGCMM)
/* Use + 2 because in some versions of Lua (Lua 5.1)
* LUA_ERRFILE is defined as (LUA_ERRERR+1)
* so we need to avoid it (LuaJIT might have something at this
* integer value too)
*/
# define LUA_ERRGCMM (LUA_ERRERR + 2)
#endif /* LUA_ERRGCMM define */
#if !defined(MOONJIT_VERSION)
typedef size_t lua_Unsigned;
#endif
typedef struct luaL_Buffer_53 {
luaL_Buffer b; /* make incorrect code crash! */
char *ptr;
size_t nelems;
size_t capacity;
lua_State *L2;
} luaL_Buffer_53;
#define luaL_Buffer luaL_Buffer_53
/* In PUC-Rio 5.1, userdata is a simple FILE*
* In LuaJIT, it's a struct where the first member is a FILE*
* We can't support the `closef` member
*/
typedef struct luaL_Stream {
FILE *f;
} luaL_Stream;
#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
COMPAT53_API int lua_absindex(lua_State *L, int i);
#define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith)
COMPAT53_API void lua_arith(lua_State *L, int op);
#define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare)
COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op);
#define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy)
COMPAT53_API void lua_copy(lua_State *L, int from, int to);
#define lua_getuservalue(L, i) \
(lua_getfenv((L), (i)), lua_type((L), -1))
#define lua_setuservalue(L, i) \
(luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i)))
#define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
COMPAT53_API void lua_len(lua_State *L, int i);
#define lua_pushstring(L, s) \
(lua_pushstring((L), (s)), lua_tostring((L), -1))
#define lua_pushlstring(L, s, len) \
((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1))
#ifndef luaL_newlibtable
# define luaL_newlibtable(L, l) \
(lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
#endif
#ifndef luaL_newlib
# define luaL_newlib(L, l) \
(luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l)))
#endif
#ifndef lua_pushglobaltable
# define lua_pushglobaltable(L) \
lua_pushvalue((L), LUA_GLOBALSINDEX)
#endif
#define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp)
COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p);
#define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp)
COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p);
#define lua_rawlen(L, i) lua_objlen((L), (i))
#define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
#define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx)
COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
#define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
COMPAT53_API void luaL_checkversion(lua_State *L);
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
#define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode);
#define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx)
COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
#define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53)
COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg);
#define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable)
COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char *name);
#define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len)
COMPAT53_API lua_Integer luaL_len(lua_State *L, int i);
#define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs)
COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
#define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable)
COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname);
#define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata)
COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname);
#define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback)
COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
#define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult)
COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
#define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult)
COMPAT53_API int luaL_execresult(lua_State *L, int stat);
#define lua_callk(L, na, nr, ctx, cont) \
((void)(ctx), (void)(cont), lua_call((L), (na), (nr)))
#define lua_pcallk(L, na, nr, err, ctx, cont) \
((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err)))
#define lua_resume(L, from, nargs) \
((void)(from), lua_resume((L), (nargs)))
#define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B);
#define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s);
#define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l);
#define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B);
#define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
COMPAT53_API void luaL_pushresult(luaL_Buffer_53 *B);
#undef luaL_buffinitsize
#define luaL_buffinitsize(L, B, s) \
(luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
#undef luaL_prepbuffer
#define luaL_prepbuffer(B) \
luaL_prepbuffsize((B), LUAL_BUFFERSIZE)
#undef luaL_addchar
#define luaL_addchar(B, c) \
((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \
((B)->ptr[(B)->nelems++] = (c)))
#undef luaL_addsize
#define luaL_addsize(B, s) \
((B)->nelems += (s))
#undef luaL_addstring
#define luaL_addstring(B, s) \
luaL_addlstring((B), (s), strlen((s)))
#undef luaL_pushresultsize
#define luaL_pushresultsize(B, s) \
(luaL_addsize((B), (s)), luaL_pushresult((B)))
#if defined(LUA_COMPAT_APIINTCASTS)
#define lua_pushunsigned(L, n) \
lua_pushinteger((L), (lua_Integer)(n))
#define lua_tounsignedx(L, i, is) \
((lua_Unsigned)lua_tointegerx((L), (i), (is)))
#define lua_tounsigned(L, i) \
lua_tounsignedx((L), (i), NULL)
#define luaL_checkunsigned(L, a) \
((lua_Unsigned)luaL_checkinteger((L), (a)))
#define luaL_optunsigned(L, a, d) \
((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d)))
#endif
#endif /* Lua 5.1 only */
/* declarations for Lua 5.1 and 5.2 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
typedef int lua_KContext;
typedef int(*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
#define lua_dump(L, w, d, s) \
((void)(s), lua_dump((L), (w), (d)))
#define lua_getfield(L, i, k) \
(lua_getfield((L), (i), (k)), lua_type((L), -1))
#define lua_gettable(L, i) \
(lua_gettable((L), (i)), lua_type((L), -1))
#define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti)
COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i);
#define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger)
COMPAT53_API int lua_isinteger(lua_State *L, int index);
#define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53)
COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
#define lua_numbertointeger(n, p) \
((*(p) = (lua_Integer)(n)), 1)
#define lua_rawget(L, i) \
(lua_rawget((L), (i)), lua_type((L), -1))
#define lua_rawgeti(L, i, n) \
(lua_rawgeti((L), (i), (n)), lua_type((L), -1))
#define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate)
COMPAT53_API void lua_rotate(lua_State *L, int idx, int n);
#define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti)
COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i);
#define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber)
COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s);
#define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring)
COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
#define luaL_getmetafield(L, o, e) \
(luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL)
#define luaL_newmetatable(L, tn) \
(luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0)
#define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
COMPAT53_API void luaL_requiref(lua_State *L, const char *modname,
lua_CFunction openf, int glb);
#endif /* Lua 5.1 and Lua 5.2 */
/* declarations for Lua 5.2 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
/* XXX not implemented:
* lua_isyieldable
* lua_getextraspace
* lua_arith (new operators)
* lua_pushfstring (new formats)
*/
#define lua_getglobal(L, n) \
(lua_getglobal((L), (n)), lua_type((L), -1))
#define lua_getuservalue(L, i) \
(lua_getuservalue((L), (i)), lua_type((L), -1))
#define lua_pushlstring(L, s, len) \
(((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len)))
#define lua_rawgetp(L, i, p) \
(lua_rawgetp((L), (i), (p)), lua_type((L), -1))
#define LUA_KFUNCTION(_name) \
static int (_name)(lua_State *L, int status, lua_KContext ctx); \
static int (_name ## _52)(lua_State *L) { \
lua_KContext ctx; \
int status = lua_getctx(L, &ctx); \
return (_name)(L, status, ctx); \
} \
static int (_name)(lua_State *L, int status, lua_KContext ctx)
#define lua_pcallk(L, na, nr, err, ctx, cont) \
lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52)
#define lua_callk(L, na, nr, ctx, cont) \
lua_callk((L), (na), (nr), (ctx), cont ## _52)
#define lua_yieldk(L, nr, ctx, cont) \
lua_yieldk((L), (nr), (ctx), cont ## _52)
#ifdef lua_call
# undef lua_call
# define lua_call(L, na, nr) \
(lua_callk)((L), (na), (nr), 0, NULL)
#endif
#ifdef lua_pcall
# undef lua_pcall
# define lua_pcall(L, na, nr, err) \
(lua_pcallk)((L), (na), (nr), (err), 0, NULL)
#endif
#ifdef lua_yield
# undef lua_yield
# define lua_yield(L, nr) \
(lua_yieldk)((L), (nr), 0, NULL)
#endif
#endif /* Lua 5.2 only */
/* other Lua versions */
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
# error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)"
#endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */
/* helper macro for defining continuation functions (for every version
* *except* Lua 5.2) */
#ifndef LUA_KFUNCTION
#define LUA_KFUNCTION(_name) \
static int (_name)(lua_State *L, int status, lua_KContext ctx)
#endif
#if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE == 1
# include "compat-5.3.c.h"
#endif
#endif /* KEPLER_PROJECT_COMPAT53_H_ */

View file

@ -1,25 +1,31 @@
#ifndef NOT_KEPLER_PROJECT_COMPAT54_H_
#define NOT_KEPLER_PROJECT_COMPAT54_H_
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
extern "C" {
#endif
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
}
#endif
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504
#if !defined(LUA_ERRGCMM)
/* So Lua 5.4 actually removes this, which breaks sol2...
man, this API is quite unstable...!
*/
# define LUA_ERRGCMM (LUA_ERRERR + 2)
#endif /* LUA_ERRGCMM define */
#endif // Lua 5.4 only
#ifndef NOT_KEPLER_PROJECT_COMPAT54_H_
#define NOT_KEPLER_PROJECT_COMPAT54_H_
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
extern "C" {
#endif
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
}
#endif
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504
#if !defined(LUA_ERRGCMM)
/* So Lua 5.4 actually removes this, which breaks sol2...
man, this API is quite unstable...!
*/
# define LUA_ERRGCMM (LUA_ERRERR + 2)
#endif /* LUA_ERRGCMM define */
#endif // Lua 5.4 only
#endif // NOT_KEPLER_PROJECT_COMPAT54_H_

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -21,24 +21,40 @@
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_COMPATIBILITY_VERSION_HPP
#define SOL_COMPATIBILITY_VERSION_HPP
#ifndef SOL_COMPATIBILITY_LUA_VERSION_HPP
#define SOL_COMPATIBILITY_LUA_VERSION_HPP
#include <sol/version.hpp>
// clang-format off
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_)
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#elif SOL_IS_ON(SOL_USE_LUA_HPP_I_)
#include <lua.hpp>
#else
extern "C" {
#if SOL_IS_ON(SOL_USING_CXX_LUA)
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif
#elif SOL_IS_ON(SOL_USE_LUA_HPP)
#if __has_include(<lua/lua.hpp>)
#include <lua/lua.hpp>
#else
#include <lua.hpp>
#endif
#else
extern "C" {
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif
}
#endif // C++ Mangling for Lua vs. Not
@ -50,13 +66,15 @@
#endif
#elif defined(LUAJIT_VERSION)
#define SOL_USE_LUAJIT_I_ SOL_ON
#elif SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define SOL_USE_LUAJIT_I_ SOL_ON
#else
#define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF
#endif // luajit
#if SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
#if SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#include <luajit.h>
#elif SOL_IS_ON(SOL_USE_LUAJIT_I_)
#elif SOL_IS_ON(SOL_USE_LUAJIT)
extern "C" {
#include <luajit.h>
}
@ -64,7 +82,7 @@
#if defined(SOL_LUAJIT_VERSION)
#define SOL_LUAJIT_VERSION_I_ SOL_LUAJIT_VERSION
#elif SOL_IS_ON(SOL_USE_LUAJIT_I_)
#elif SOL_IS_ON(SOL_USE_LUAJIT)
#define SOL_LUAJIT_VERSION_I_ LUAJIT_VERSION_NUM
#else
#define SOL_LUAJIT_VERSION_I_ 0
@ -118,21 +136,25 @@
#else
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
#endif
#elif SOL_LUAJIT_VERSION_I_ >= 20100
// LuaJIT 2.1.0-beta3 and better have exception support locked in for all platforms (mostly)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#elif SOL_LUAJIT_VERSION_I_ >= 20000
// LuaJIT 2.0.x have exception support only on x64 builds
#if SOL_IS_ON(SOL_PLATFORM_X64_I_)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#else
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
#endif
#else
// otherwise, there is no exception safety for
// shoving exceptions through Lua and errors should
// always be serialized
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
#if SOL_IS_ON(SOL_USE_LUAJIT)
#if SOL_USE(SOL_LUAJIT_VERSION) >= 20100
// LuaJIT 2.1.0-beta3 and better have exception support locked in for all platforms (mostly)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#elif SOL_USE(SOL_LUAJIT_VERSION) >= 20000
// LuaJIT 2.0.x have exception support only on x64 builds
#if SOL_IS_ON(SOL_PLATFORM_X64)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#else
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
#endif
#endif
#else
// otherwise, there is no exception safety for
// shoving exceptions through Lua and errors should
// always be serialized
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
#endif
#endif
// Some configurations work with exceptions,
@ -144,13 +166,14 @@
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_OFF
#endif
#else
#if SOL_IS_ON(SOL_USE_LUAJIT_I_)
#if SOL_IS_ON(SOL_USE_LUAJIT) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUA_I_)
#elif SOL_IS_ON(SOL_USING_CXX_LUA)
// C++ builds of Lua will throw an exception to implement its `yield` behavior;
// it is irresponsible to "catch all" on this setting.
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#else
// Otherwise, by default, everyhting should be caught.
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON
#endif
#endif
@ -162,7 +185,7 @@
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_OFF
#endif
#else
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_) && SOL_IS_ON(SOL_USE_LUAJIT_I_)
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS) && SOL_IS_ON(SOL_USE_LUAJIT)
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
#else
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_DEFAULT_OFF
@ -176,7 +199,7 @@
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_OFF
#endif
#else
#if SOL_IS_OFF(SOL_USE_LUAJIT_I_) && (SOL_LUA_VERSION > 501)
#if SOL_IS_OFF(SOL_USE_LUAJIT) && (SOL_LUA_VERSION > 501)
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
#else
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_DEFAULT_OFF
@ -192,7 +215,11 @@
#else
// Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags)
// Lua 5.2, or other versions of Lua with the compat flag, or Lua that is not 5.2 with the specific define (5.4.1 either removed it entirely or broke it)
#if (SOL_LUA_VERSION_I_ == 502) || (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0)) || (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
#if (SOL_LUA_VERSION_I_ == 502)
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif defined(LUA_COMPAT_BITLIB)
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif (SOL_LUA_VERSION_I_ < 504 && defined(LUA_COMPAT_5_2))
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#else
#define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF
@ -215,4 +242,4 @@
// clang-format on
#endif // SOL_COMPATIBILITY_VERSION_HPP
#endif // SOL_COMPATIBILITY_LUA_VERSION_HPP

50
extern/sol3/sol/config.hpp vendored Normal file
View file

@ -0,0 +1,50 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_CONFIG_HPP
#define SOL_CONFIG_HPP
/* Base, empty configuration file!
To override, place a file in your include paths of the form:
. (your include path here)
| sol (directory, or equivalent)
| config.hpp (your config.hpp file)
So that when sol2 includes the file
#include <sol/config.hpp>
it gives you the configuration values you desire. Configuration values can be
seen in the safety.rst of the doc/src, or at
https://sol2.readthedocs.io/en/latest/safety.html ! You can also pass them through
the build system, or the command line options of your compiler.
*/
#endif // SOL_CONFIG_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -94,7 +94,7 @@ namespace sol {
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_coroutine(T&& r) noexcept
: base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -157,7 +157,7 @@ namespace sol {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_coroutine>(lua_state(), -1, handler);
@ -180,7 +180,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_coroutine>(L, index, handler);
#endif // Safety
@ -189,7 +189,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_coroutine>(L, index, handler);
#endif // Safety
@ -198,7 +198,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_coroutine>(lua_state(), -1, handler);

View file

@ -1,52 +1,63 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DEBUG_HPP
#define SOL_DEBUG_HPP
#include <sol/stack.hpp>
#include <iostream>
namespace sol { namespace detail { namespace debug {
inline std::string dump_types(lua_State* L) {
std::string visual;
std::size_t size = lua_gettop(L) + 1;
for (std::size_t i = 1; i < size; ++i) {
if (i != 1) {
visual += " | ";
}
visual += type_name(L, stack::get<type>(L, static_cast<int>(i)));
}
return visual;
}
inline void print_stack(lua_State* L) {
std::cout << dump_types(L) << std::endl;
}
inline void print_section(const std::string& message, lua_State* L) {
std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
}
}}} // namespace sol::detail::debug
#endif // SOL_DEBUG_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DEBUG_HPP
#define SOL_DEBUG_HPP
#include <sol/stack.hpp>
#include <iostream>
namespace sol { namespace detail { namespace debug {
inline std::string dump_types(lua_State* L) {
std::string visual;
std::size_t size = lua_gettop(L) + 1;
for (std::size_t i = 1; i < size; ++i) {
if (i != 1) {
visual += " | ";
}
visual += type_name(L, stack::get<type>(L, static_cast<int>(i)));
}
return visual;
}
inline void print_stack(lua_State* L) {
std::cout << dump_types(L) << std::endl;
}
inline void print_section(const std::string& message, lua_State* L) {
std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
}
inline void print_lua_information(lua_State* L) {
std::cout << "Lua Version: " << SOL_USE(SOL_LUA_VERSION) << std::endl;
std::cout << "Lua (C++): " << SOL_IS_ON(SOL_USING_CXX_LUA) << std::endl;
std::cout << "Trampoline Propagate Exceptions?: " << SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS) << std::endl;
std::cout << "Catch-all Exceptions?: " << SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL) << std::endl;
std::cout << "LuaJIT: " << SOL_IS_ON(SOL_USE_LUAJIT) << std::endl;
std::cout << "LuaJIT Version: " << SOL_USE(SOL_LUAJIT_VERSION) << std::endl;
std::cout << "LuaJIT (C++): " << SOL_IS_ON(SOL_USING_CXX_LUAJIT) << std::endl;
std::cout << "LuaJIT Exception Trampoline: " << SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE) << std::endl;
}
}}} // namespace sol::detail::debug
#endif // SOL_DEBUG_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -28,7 +28,7 @@
#include <string>
#include <array>
#include <cctype>
#if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED_I_)
#if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED)
extern "C" {
#include <ctype.h>
}
@ -47,7 +47,7 @@ namespace sol { namespace detail {
"`anonymous namespace'" } };
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
inline std::string ctti_get_type_name_from_sig(std::string name) {
// cardinal sins from MINGW
using namespace std;
@ -85,7 +85,7 @@ namespace sol { namespace detail {
inline std::string ctti_get_type_name() {
return ctti_get_type_name_from_sig(__PRETTY_FUNCTION__);
}
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#elif SOL_IS_ON(SOL_COMPILER_VCXX)
inline std::string ctti_get_type_name_from_sig(std::string name) {
std::size_t start = name.find("get_type_name");
if (start == std::string::npos)

View file

@ -1,44 +1,44 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DEPRECATE_HPP
#define SOL_DEPRECATE_HPP
#ifndef SOL_DEPRECATED
#ifdef _MSC_VER
#define SOL_DEPRECATED __declspec(deprecated)
#elif __GNUC__
#define SOL_DEPRECATED __attribute__((deprecated))
#else
#define SOL_DEPRECATED [[deprecated]]
#endif // compilers
#endif // SOL_DEPRECATED
namespace sol { namespace detail {
template <typename T>
struct SOL_DEPRECATED deprecate_type {
using type = T;
};
}} // namespace sol::detail
#endif // SOL_DEPRECATE_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DEPRECATE_HPP
#define SOL_DEPRECATE_HPP
#ifndef SOL_DEPRECATED
#ifdef _MSC_VER
#define SOL_DEPRECATED __declspec(deprecated)
#elif __GNUC__
#define SOL_DEPRECATED __attribute__((deprecated))
#else
#define SOL_DEPRECATED [[deprecated]]
#endif // compilers
#endif // SOL_DEPRECATED
namespace sol { namespace detail {
template <typename T>
struct SOL_DEPRECATED deprecate_type {
using type = T;
};
}} // namespace sol::detail
#endif // SOL_DEPRECATE_HPP

View file

@ -1,232 +1,232 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
#ifndef SOL_DETAIL_BUILD_VERSION_HPP
#define SOL_DETAIL_BUILD_VERSION_HPP
#include <sol/version.hpp>
// clang-format off
#if defined(SOL_DLL)
#if (SOL_DLL != 0)
#define SOL_DLL_I_ SOL_ON
#else
#define SOL_DLL_I_ SOL_OFF
#endif
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) && (defined(DLL_) || defined(_DLL))
#define SOL_DLL_I_ SOL_DEFAULT_ON
#else
#define SOL_DLL_I_ SOL_DEFAULT_OFF
#endif // DLL definition
#if defined(SOL_HEADER_ONLY)
#if (SOL_HEADER_ONLY != 0)
#define SOL_HEADER_ONLY_I_ SOL_ON
#else
#define SOL_HEADER_ONLY_I_ SOL_OFF
#endif
#else
#define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF
#endif // Header only library
#if defined(SOL_BUILD)
#if (SOL_BUILD != 0)
#define SOL_BUILD_I_ SOL_ON
#else
#define SOL_BUILD_I_ SOL_OFF
#endif
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#define SOL_BUILD_I_ SOL_DEFAULT_OFF
#else
#define SOL_BUILD_I_ SOL_DEFAULT_ON
#endif
#if defined(SOL_UNITY_BUILD)
#if (SOL_UNITY_BUILD != 0)
#define SOL_UNITY_BUILD_I_ SOL_ON
#else
#define SOL_UNITY_BUILD_I_ SOL_OFF
#endif
#else
#define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF
#endif // Header only library
#if defined(SOL_C_FUNCTION_LINKAGE)
#define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE
#else
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_)
// C++
#define SOL_C_FUNCTION_LINKAGE_I_ extern "C"
#else
// normal
#define SOL_C_FUNCTION_LINKAGE_I_
#endif // C++ or not
#endif // Linkage specification for C functions
#if defined(SOL_API_LINKAGE)
#define SOL_API_LINKAGE_I_ SOL_API_LINKAGE
#else
#if SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) || SOL_IS_ON(SOL_PLATFORM_WINDOWS_I_) || SOL_IS_ON(SOL_PLATFORM_CYGWIN_I_)
// MSVC Compiler; or, Windows, or Cygwin platforms
#if SOL_IS_ON(SOL_BUILD_I_)
// Building the library
#if SOL_IS_ON(SOL_COMPILER_GCC_I_)
// Using GCC
#define SOL_API_LINKAGE_I_ __attribute__((dllexport))
#else
// Using Clang, MSVC, etc...
#define SOL_API_LINKAGE_I_ __declspec(dllexport)
#endif
#else
#if SOL_IS_ON(SOL_COMPILER_GCC_I_)
#define SOL_API_LINKAGE_I_ __attribute__((dllimport))
#else
#define SOL_API_LINKAGE_I_ __declspec(dllimport)
#endif
#endif
#else
// extern if building normally on non-MSVC
#define SOL_API_LINKAGE_I_ extern
#endif
#elif SOL_IS_ON(SOL_UNITY_BUILD_I_)
// Built-in library, like how stb typical works
#if SOL_IS_ON(SOL_HEADER_ONLY_I_)
// Header only, so functions are defined "inline"
#define SOL_API_LINKAGE_I_ inline
#else
// Not header only, so seperately compiled files
#define SOL_API_LINKAGE_I_ extern
#endif
#else
// Normal static library
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_)
#define SOL_API_LINKAGE_I_
#else
#define SOL_API_LINKAGE_I_ extern
#endif
#endif // DLL or not
#endif // Build definitions
#if defined(SOL_PUBLIC_FUNC_DECL)
#define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL
#else
#define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_
#endif
#if defined(SOL_INTERNAL_FUNC_DECL_)
#define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_
#else
#define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_
#endif
#if defined(SOL_PUBLIC_FUNC_DEF)
#define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF
#else
#define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_
#endif
#if defined(SOL_INTERNAL_FUNC_DEF)
#define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF
#else
#define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_
#endif
#if defined(SOL_FUNC_DECL)
#define SOL_FUNC_DECL_I_ SOL_FUNC_DECL
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#define SOL_FUNC_DECL_I_
#elif SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_BUILD_I_)
#define SOL_FUNC_DECL_I_ extern __declspec(dllexport)
#else
#define SOL_FUNC_DECL_I_ extern __declspec(dllimport)
#endif
#elif SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default")))
#else
#define SOL_FUNC_DECL_I_ extern
#endif
#endif
#if defined(SOL_FUNC_DEFN)
#define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#define SOL_FUNC_DEFN_I_ inline
#elif SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_BUILD_I_)
#define SOL_FUNC_DEFN_I_ __declspec(dllexport)
#else
#define SOL_FUNC_DEFN_I_ __declspec(dllimport)
#endif
#elif SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#define SOL_FUNC_DEFN_I_ __attribute__((visibility("default")))
#else
#define SOL_FUNC_DEFN_I_
#endif
#endif
#if defined(SOL_HIDDEN_FUNC_DECL)
#define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#define SOL_HIDDEN_FUNC_DECL_I_
#elif SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_BUILD_I_)
#define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport)
#else
#define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport)
#endif
#elif SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default")))
#else
#define SOL_HIDDEN_FUNC_DECL_I_ extern
#endif
#endif
#if defined(SOL_HIDDEN_FUNC_DEFN)
#define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#define SOL_HIDDEN_FUNC_DEFN_I_ inline
#elif SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_BUILD_I_)
#define SOL_HIDDEN_FUNC_DEFN_I_
#else
#define SOL_HIDDEN_FUNC_DEFN_I_
#endif
#elif SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden")))
#else
#define SOL_HIDDEN_FUNC_DEFN_I_
#endif
#endif
// clang-format on
#endif // SOL_DETAIL_BUILD_VERSION_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
#ifndef SOL_DETAIL_BUILD_VERSION_HPP
#define SOL_DETAIL_BUILD_VERSION_HPP
#include <sol/version.hpp>
// clang-format off
#if defined(SOL_DLL)
#if (SOL_DLL != 0)
#define SOL_DLL_I_ SOL_ON
#else
#define SOL_DLL_I_ SOL_OFF
#endif
#elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(DLL_) || defined(_DLL))
#define SOL_DLL_I_ SOL_DEFAULT_ON
#else
#define SOL_DLL_I_ SOL_DEFAULT_OFF
#endif // DLL definition
#if defined(SOL_HEADER_ONLY)
#if (SOL_HEADER_ONLY != 0)
#define SOL_HEADER_ONLY_I_ SOL_ON
#else
#define SOL_HEADER_ONLY_I_ SOL_OFF
#endif
#else
#define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF
#endif // Header only library
#if defined(SOL_BUILD)
#if (SOL_BUILD != 0)
#define SOL_BUILD_I_ SOL_ON
#else
#define SOL_BUILD_I_ SOL_OFF
#endif
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_BUILD_I_ SOL_DEFAULT_OFF
#else
#define SOL_BUILD_I_ SOL_DEFAULT_ON
#endif
#if defined(SOL_UNITY_BUILD)
#if (SOL_UNITY_BUILD != 0)
#define SOL_UNITY_BUILD_I_ SOL_ON
#else
#define SOL_UNITY_BUILD_I_ SOL_OFF
#endif
#else
#define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF
#endif // Header only library
#if defined(SOL_C_FUNCTION_LINKAGE)
#define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE
#else
#if SOL_IS_ON(SOL_BUILD_CXX_MODE)
// C++
#define SOL_C_FUNCTION_LINKAGE_I_ extern "C"
#else
// normal
#define SOL_C_FUNCTION_LINKAGE_I_
#endif // C++ or not
#endif // Linkage specification for C functions
#if defined(SOL_API_LINKAGE)
#define SOL_API_LINKAGE_I_ SOL_API_LINKAGE
#else
#if SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX) || SOL_IS_ON(SOL_PLATFORM_WINDOWS) || SOL_IS_ON(SOL_PLATFORM_CYGWIN)
// MSVC Compiler; or, Windows, or Cygwin platforms
#if SOL_IS_ON(SOL_BUILD)
// Building the library
#if SOL_IS_ON(SOL_COMPILER_GCC)
// Using GCC
#define SOL_API_LINKAGE_I_ __attribute__((dllexport))
#else
// Using Clang, MSVC, etc...
#define SOL_API_LINKAGE_I_ __declspec(dllexport)
#endif
#else
#if SOL_IS_ON(SOL_COMPILER_GCC)
#define SOL_API_LINKAGE_I_ __attribute__((dllimport))
#else
#define SOL_API_LINKAGE_I_ __declspec(dllimport)
#endif
#endif
#else
// extern if building normally on non-MSVC
#define SOL_API_LINKAGE_I_ extern
#endif
#elif SOL_IS_ON(SOL_UNITY_BUILD)
// Built-in library, like how stb typical works
#if SOL_IS_ON(SOL_HEADER_ONLY)
// Header only, so functions are defined "inline"
#define SOL_API_LINKAGE_I_ inline
#else
// Not header only, so seperately compiled files
#define SOL_API_LINKAGE_I_ extern
#endif
#else
// Normal static library
#if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#define SOL_API_LINKAGE_I_
#else
#define SOL_API_LINKAGE_I_ extern
#endif
#endif // DLL or not
#endif // Build definitions
#if defined(SOL_PUBLIC_FUNC_DECL)
#define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL
#else
#define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_
#endif
#if defined(SOL_INTERNAL_FUNC_DECL_)
#define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_
#else
#define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_
#endif
#if defined(SOL_PUBLIC_FUNC_DEF)
#define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF
#else
#define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_
#endif
#if defined(SOL_INTERNAL_FUNC_DEF)
#define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF
#else
#define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_
#endif
#if defined(SOL_FUNC_DECL)
#define SOL_FUNC_DECL_I_ SOL_FUNC_DECL
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_FUNC_DECL_I_
#elif SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#if SOL_IS_ON(SOL_BUILD)
#define SOL_FUNC_DECL_I_ extern __declspec(dllexport)
#else
#define SOL_FUNC_DECL_I_ extern __declspec(dllimport)
#endif
#elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default")))
#else
#define SOL_FUNC_DECL_I_ extern
#endif
#endif
#if defined(SOL_FUNC_DEFN)
#define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_FUNC_DEFN_I_ inline
#elif SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#if SOL_IS_ON(SOL_BUILD)
#define SOL_FUNC_DEFN_I_ __declspec(dllexport)
#else
#define SOL_FUNC_DEFN_I_ __declspec(dllimport)
#endif
#elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define SOL_FUNC_DEFN_I_ __attribute__((visibility("default")))
#else
#define SOL_FUNC_DEFN_I_
#endif
#endif
#if defined(SOL_HIDDEN_FUNC_DECL)
#define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_HIDDEN_FUNC_DECL_I_
#elif SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#if SOL_IS_ON(SOL_BUILD)
#define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport)
#else
#define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport)
#endif
#elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default")))
#else
#define SOL_HIDDEN_FUNC_DECL_I_ extern
#endif
#endif
#if defined(SOL_HIDDEN_FUNC_DEFN)
#define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_HIDDEN_FUNC_DEFN_I_ inline
#elif SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#if SOL_IS_ON(SOL_BUILD)
#define SOL_HIDDEN_FUNC_DEFN_I_
#else
#define SOL_HIDDEN_FUNC_DEFN_I_
#endif
#elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden")))
#else
#define SOL_HIDDEN_FUNC_DEFN_I_
#endif
#endif
// clang-format on
#endif // SOL_DETAIL_BUILD_VERSION_HPP

View file

@ -1,77 +1,77 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DUMP_HANDLER_HPP
#define SOL_DUMP_HANDLER_HPP
#include <sol/compatibility.hpp>
#include <cstdint>
#include <exception>
namespace sol {
class dump_error : public error {
private:
int m_ec;
public:
dump_error(int error_code_) : error("dump returned non-zero error of " + std::to_string(error_code_)), m_ec(error_code_) {
}
int error_code() const {
return m_ec;
}
};
inline int dump_pass_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
(void)L_;
(void)writer_function;
(void)userdata_pointer_;
(void)strip;
return result_code;
}
inline int dump_panic_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
(void)L_;
(void)writer_function;
(void)userdata_pointer_;
(void)strip;
return luaL_error(L_, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
inline int dump_throw_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
return dump_panic_on_error(L_, result_code, writer_function, userdata_pointer_, strip);
#else
(void)L_;
(void)writer_function;
(void)userdata_pointer_;
(void)strip;
throw dump_error(result_code);
#endif // no exceptions stuff
}
} // namespace sol
#endif // SOL_DUMP_HANDLER_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DUMP_HANDLER_HPP
#define SOL_DUMP_HANDLER_HPP
#include <sol/compatibility.hpp>
#include <cstdint>
#include <exception>
namespace sol {
class dump_error : public error {
private:
int m_ec;
public:
dump_error(int error_code_) : error("dump returned non-zero error of " + std::to_string(error_code_)), m_ec(error_code_) {
}
int error_code() const {
return m_ec;
}
};
inline int dump_pass_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
(void)L_;
(void)writer_function;
(void)userdata_pointer_;
(void)strip;
return result_code;
}
inline int dump_panic_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
(void)L_;
(void)writer_function;
(void)userdata_pointer_;
(void)strip;
return luaL_error(L_, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
inline int dump_throw_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
#if SOL_IS_OFF(SOL_EXCEPTIONS)
return dump_panic_on_error(L_, result_code, writer_function, userdata_pointer_, strip);
#else
(void)L_;
(void)writer_function;
(void)userdata_pointer_;
(void)strip;
throw dump_error(result_code);
#endif // no exceptions stuff
}
} // namespace sol
#endif // SOL_DUMP_HANDLER_HPP

View file

@ -1,160 +1,161 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_EBCO_HPP
#define SOL_EBCO_HPP
#include <type_traits>
#include <utility>
namespace sol { namespace detail {
template <typename T, std::size_t tag = 0, typename = void>
struct ebco {
T m_value;
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : m_value(v) {};
ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : m_value(std::move(v)) {};
ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) {
m_value = v;
return *this;
}
ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) {
m_value = std::move(v);
return *this;
};
template <typename Arg, typename... Args,
typename = std::enable_if_t<
!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>)
: m_value(std::forward<Arg>(arg), std::forward<Args>(args)...) {
}
T& value() & noexcept {
return m_value;
}
T const& value() const& noexcept {
return m_value;
}
T&& value() && noexcept {
return std::move(m_value);
}
};
template <typename T, std::size_t tag>
struct ebco<T, tag, std::enable_if_t<!std::is_reference_v<T> && std::is_class_v<T> && !std::is_final_v<T>>> : T {
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : T(v) {};
ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : T(std::move(v)) {};
template <typename Arg, typename... Args,
typename = std::enable_if_t<
!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>) : T(std::forward<Arg>(arg), std::forward<Args>(args)...) {
}
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) {
static_cast<T&>(*this) = v;
return *this;
}
ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) {
static_cast<T&>(*this) = std::move(v);
return *this;
};
T& value() & noexcept {
return static_cast<T&>(*this);
}
T const& value() const& noexcept {
return static_cast<T const&>(*this);
}
T&& value() && noexcept {
return std::move(static_cast<T&>(*this));
}
};
template <typename T, std::size_t tag>
struct ebco<T&, tag> {
private:
T* m_ref;
public:
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco(T& v) noexcept : m_ref(std::addressof(v)) {};
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
ebco& operator=(T& v) noexcept {
m_ref = std::addressof(v);
return *this;
}
T& value() const noexcept {
return *(const_cast<ebco<T&, tag>&>(*this).m_ref);
}
};
template <typename T, std::size_t tag>
struct ebco<T&&, tag> {
T&& ref;
ebco() = default;
ebco(const ebco&) = delete;
ebco(ebco&&) = default;
ebco(T&& v) noexcept : ref(v) {};
ebco& operator=(const ebco&) = delete;
ebco& operator=(ebco&&) = delete;
T& value() & noexcept {
return ref;
}
const T& value() const& noexcept {
return ref;
}
T&& value() && noexcept {
return std::move(ref);
}
};
}} // namespace sol::detail
#endif // SOL_EBCO_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_EBCO_HPP
#define SOL_EBCO_HPP
#include <type_traits>
#include <utility>
#include <memory>
namespace sol { namespace detail {
template <typename T, std::size_t tag = 0, typename = void>
struct ebco {
T m_value;
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : m_value(v) {};
ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : m_value(std::move(v)) {};
ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) {
m_value = v;
return *this;
}
ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) {
m_value = std::move(v);
return *this;
};
template <typename Arg, typename... Args,
typename = std::enable_if_t<
!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>)
: m_value(std::forward<Arg>(arg), std::forward<Args>(args)...) {
}
T& value() & noexcept {
return m_value;
}
T const& value() const& noexcept {
return m_value;
}
T&& value() && noexcept {
return std::move(m_value);
}
};
template <typename T, std::size_t tag>
struct ebco<T, tag, std::enable_if_t<!std::is_reference_v<T> && std::is_class_v<T> && !std::is_final_v<T>>> : T {
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : T(v) {};
ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : T(std::move(v)) {};
template <typename Arg, typename... Args,
typename = std::enable_if_t<
!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>) : T(std::forward<Arg>(arg), std::forward<Args>(args)...) {
}
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) {
static_cast<T&>(*this) = v;
return *this;
}
ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) {
static_cast<T&>(*this) = std::move(v);
return *this;
};
T& value() & noexcept {
return static_cast<T&>(*this);
}
T const& value() const& noexcept {
return static_cast<T const&>(*this);
}
T&& value() && noexcept {
return std::move(static_cast<T&>(*this));
}
};
template <typename T, std::size_t tag>
struct ebco<T&, tag> {
private:
T* m_ref;
public:
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco(T& v) noexcept : m_ref(std::addressof(v)) {};
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
ebco& operator=(T& v) noexcept {
m_ref = std::addressof(v);
return *this;
}
T& value() const noexcept {
return *(const_cast<ebco<T&, tag>&>(*this).m_ref);
}
};
template <typename T, std::size_t tag>
struct ebco<T&&, tag> {
T&& ref;
ebco() = default;
ebco(const ebco&) = delete;
ebco(ebco&&) = default;
ebco(T&& v) noexcept : ref(v) {};
ebco& operator=(const ebco&) = delete;
ebco& operator=(ebco&&) = delete;
T& value() & noexcept {
return ref;
}
const T& value() const& noexcept {
return ref;
}
T&& value() && noexcept {
return std::move(ref);
}
};
}} // namespace sol::detail
#endif // SOL_EBCO_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -58,29 +58,29 @@ namespace sol {
basic_environment(env_key_t, const stack_reference& extraction_target)
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<env_key_t>(this->lua_state(), -1, handler);
#endif // Safety
lua_pop(this->lua_state(), 2);
lua_pop(this->lua_state(), 1);
}
template <bool b>
basic_environment(env_key_t, const basic_reference<b>& extraction_target)
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<env_key_t>(this->lua_state(), -1, handler);
#endif // Safety
lua_pop(this->lua_state(), 2);
lua_pop(this->lua_state(), 1);
}
basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_environment>(L, index, handler);
#endif // Safety
}
basic_environment(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_environment>(L, -1, handler);
@ -90,7 +90,7 @@ namespace sol {
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_environment(T&& r) noexcept : base_t(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_environment<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -103,7 +103,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_environment(lua_State* L, T&& r) noexcept : base_t(detail::no_safety, L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_environment<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -136,11 +136,13 @@ namespace sol {
const char* success = lua_setupvalue(L, target_index, 1);
if (success == nullptr) {
// left things alone on the stack, pop them off
lua_pop(L, 1);
lua_pop(L, 2);
return false;
}
lua_pop(L, 1);
return true;
}
lua_pop(L, 1);
return false;
}
else {
@ -152,6 +154,7 @@ namespace sol {
}
string_view upvalue_name(maybe_upvalue_name);
if (upvalue_name == "_ENV") {
lua_pop(L, 1);
this->push();
const char* success = lua_setupvalue(L, target_index, upvalue_index);
if (success == nullptr) {

View file

@ -1,39 +1,39 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
// clang-format off
#if !defined(SOL_PROLOGUE_I_)
#error "[sol2] Library Prologue is missing from this translation unit."
#else
#undef SOL_PROLOGUE_I_
#endif
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_)
#undef _FWD
#undef _MOVE
#endif
// clang-format on
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
// clang-format off
#if !defined(SOL_PROLOGUE_I_)
#error "[sol2] Library Prologue is missing from this translation unit."
#else
#undef SOL_PROLOGUE_I_
#endif
#if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#undef _FWD
#undef _MOVE
#endif
// clang-format on

View file

@ -1,89 +1,102 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_ERROR_HPP
#define SOL_ERROR_HPP
#include <sol/compatibility.hpp>
#include <stdexcept>
#include <string>
#include <array>
namespace sol {
namespace detail {
struct direct_error_tag { };
const auto direct_error = direct_error_tag {};
struct error_result {
int results;
const char* format_string;
std::array<const char*, 4> argument_strings;
error_result() : results(0), format_string(nullptr) {
}
error_result(int results_) : results(results_), format_string(nullptr) {
}
error_result(const char* format_string_, const char* first_message_) : results(0), format_string(format_string_), argument_strings() {
argument_strings[0] = first_message_;
}
};
inline int handle_errors(lua_State* L, const error_result& er) {
if (er.format_string == nullptr) {
return er.results;
}
return luaL_error(L, er.format_string, er.argument_strings[0], er.argument_strings[1], er.argument_strings[2], er.argument_strings[3]);
}
} // namespace detail
class error : public std::runtime_error {
private:
// Because VC++ is upsetting, most of the time!
std::string what_reason;
public:
error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {
}
error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) {
}
error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), what_reason(str) {
}
error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), what_reason(std::move(str)) {
}
error(const error& e) = default;
error(error&& e) = default;
error& operator=(const error& e) = default;
error& operator=(error&& e) = default;
virtual const char* what() const noexcept override {
return what_reason.c_str();
}
};
} // namespace sol
#endif // SOL_ERROR_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_ERROR_HPP
#define SOL_ERROR_HPP
#include <sol/compatibility.hpp>
#include <stdexcept>
#include <string>
#include <array>
namespace sol {
namespace detail {
struct direct_error_tag { };
const auto direct_error = direct_error_tag {};
struct error_result {
int results;
const char* format_string;
std::array<const char*, 4> argument_strings;
error_result() : results(0), format_string(nullptr) {
}
error_result(int results_) : results(results_), format_string(nullptr) {
}
error_result(const char* format_string_, const char* first_message_) : results(0), format_string(format_string_), argument_strings() {
argument_strings[0] = first_message_;
}
};
inline int handle_errors(lua_State* L, const error_result& er) {
if (er.format_string == nullptr) {
return er.results;
}
return luaL_error(L, er.format_string, er.argument_strings[0], er.argument_strings[1], er.argument_strings[2], er.argument_strings[3]);
}
class error_exception : public std::runtime_error {
public:
error_exception(const std::string& str) : error_exception(detail::direct_error, "lua: error: " + str) {
}
error_exception(std::string&& str) : error_exception(detail::direct_error, "lua: error: " + std::move(str)) {
}
error_exception(detail::direct_error_tag, const std::string& str) : std::runtime_error(str) {
}
error_exception(detail::direct_error_tag, std::string&& str) : std::runtime_error(str) {
}
error_exception(const error_exception& e) = default;
error_exception(error_exception&& e) = default;
error_exception& operator=(const error_exception& e) = default;
error_exception& operator=(error_exception&& e) = default;
};
} // namespace detail
class error : public std::runtime_error {
private:
// Because VC++ is upsetting, most of the time!
std::string what_reason;
public:
error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {
}
error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) {
}
error(detail::direct_error_tag, const std::string& str) : std::runtime_error(str) {
}
error(detail::direct_error_tag, std::string&& str) : std::runtime_error(str) {
}
error(const error& e) = default;
error(error&& e) = default;
error& operator=(const error& e) = default;
error& operator=(error&& e) = default;
};
} // namespace sol
#endif // SOL_ERROR_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -24,6 +24,7 @@
#ifndef SOL_ERROR_HANDLER_HPP
#define SOL_ERROR_HANDLER_HPP
#include <sol/config.hpp>
#include <sol/types.hpp>
#include <sol/demangle.hpp>
@ -62,7 +63,7 @@ namespace sol {
case type::poly:
return "anything";
case type::userdata: {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 2, "not enough space to push get the type name");
#endif // make sure stack doesn't overflow
if (lua_getmetatable(L, index) == 0) {
@ -84,7 +85,7 @@ namespace sol {
inline int push_type_panic_string(lua_State* L, int index, type expected, type actual, string_view message, string_view aux_message) noexcept {
const char* err = message.size() == 0
? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s")
? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s%s")
: "stack index %d, expected %s, received %s: %s %s";
const char* type_name = expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected));
{
@ -96,12 +97,16 @@ namespace sol {
inline int type_panic_string(lua_State* L, int index, type expected, type actual, string_view message = "") noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, "");
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) {
push_type_panic_string(L, index, expected, actual, message == nullptr ? "" : message, "");
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
struct type_panic_t {
@ -118,7 +123,9 @@ namespace sol {
struct constructor_handler {
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, "(type check failed in constructor)");
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
};
@ -126,7 +133,9 @@ namespace sol {
struct argument_handler {
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, "(bad argument to variable or function call)");
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
};
@ -142,7 +151,9 @@ namespace sol {
aux_message += ")')";
push_type_panic_string(L, index, expected, actual, message, aux_message);
}
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
};

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -30,7 +30,7 @@
#include <type_traits>
#include <string_view>
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
struct lua_State;
#else
extern "C" {
@ -117,7 +117,7 @@ namespace sol {
using main_protected_function = main_safe_function;
using stack_protected_function = stack_safe_function;
using stack_aligned_protected_function = stack_aligned_safe_function;
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_)
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
using function = protected_function;
using main_function = main_protected_function;
using stack_function = stack_protected_function;
@ -133,7 +133,7 @@ namespace sol {
struct unsafe_function_result;
struct protected_function_result;
using safe_function_result = protected_function_result;
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_)
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
using function_result = safe_function_result;
#else
using function_result = unsafe_function_result;
@ -234,7 +234,7 @@ namespace sol {
struct record;
}
#if SOL_IS_OFF(SOL_USE_BOOST_I_)
#if SOL_IS_OFF(SOL_USE_BOOST)
template <class T>
class optional;
@ -253,7 +253,7 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
static_assert(true, "")
#define SOL_DERIVED_CLASSES(T, ...) \
namespace sol { \
template <> \
@ -261,6 +261,6 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
static_assert(true, "")
#endif // SOL_FORWARD_HPP

44
extern/sol3/sol/forward_as.hpp vendored Normal file
View file

@ -0,0 +1,44 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_FORWARD_AS_HPP
#define SOL_FORWARD_AS_HPP
#include <sol/version.hpp>
#include <utility>
#include <type_traits>
namespace sol {
template <typename T, typename U>
constexpr decltype(auto) forward_as(U&& value) noexcept {
if constexpr (::std::is_lvalue_reference_v<T>) {
return value;
}
else {
return ::std::move(value);
}
}
}
#endif // SOL_FORWARD_AS_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -32,7 +32,7 @@
namespace sol {
namespace detail {
const bool default_safe_function_calls =
#if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS_I_)
#if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS)
true;
#else
false;

View file

@ -1,142 +1,142 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_FUNCTION_HPP
#define SOL_FUNCTION_HPP
#include <sol/stack.hpp>
#include <sol/unsafe_function.hpp>
#include <sol/protected_function.hpp>
#include <sol/bytecode.hpp>
#include <functional>
namespace sol {
template <typename... Ret, typename... Args>
decltype(auto) stack_proxy::call(Args&&... args) {
stack_function sf(this->lua_state(), this->stack_index());
return sf.template call<Ret...>(std::forward<Args>(args)...);
}
inline protected_function_result::protected_function_result(unsafe_function_result&& o) noexcept
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
o.abandon();
}
inline protected_function_result& protected_function_result::operator=(unsafe_function_result&& o) noexcept {
L = o.lua_state();
index = o.stack_index();
returncount = o.return_count();
popcount = o.return_count();
err = o.status();
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
o.abandon();
return *this;
}
inline unsafe_function_result::unsafe_function_result(protected_function_result&& o) noexcept
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()) {
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
o.abandon();
}
inline unsafe_function_result& unsafe_function_result::operator=(protected_function_result&& o) noexcept {
L = o.lua_state();
index = o.stack_index();
returncount = o.return_count();
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
o.abandon();
return *this;
}
namespace detail {
template <typename... R>
struct std_shim {
unsafe_function lua_func_;
std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
}
template <typename... Args>
meta::return_type_t<R...> operator()(Args&&... args) {
return lua_func_.call<R...>(std::forward<Args>(args)...);
}
};
template <>
struct std_shim<void> {
unsafe_function lua_func_;
std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
}
template <typename... Args>
void operator()(Args&&... args) {
lua_func_.call<void>(std::forward<Args>(args)...);
}
};
} // namespace detail
namespace stack {
template <typename Signature>
struct unqualified_getter<std::function<Signature>> {
typedef meta::bind_traits<Signature> fx_t;
typedef typename fx_t::args_list args_lists;
typedef meta::tuple_types<typename fx_t::return_type> return_types;
template <typename... R>
static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
detail::std_shim<R...> fx(unsafe_function(L, index));
return fx;
}
static std::function<Signature> get(lua_State* L, int index, record& tracking) {
tracking.use(1);
type t = type_of(L, index);
if (t == type::none || t == type::lua_nil) {
return nullptr;
}
return get_std_func(return_types(), L, index);
}
};
template <typename Allocator>
struct unqualified_getter<basic_bytecode<Allocator>> {
static basic_bytecode<Allocator> get(lua_State* L, int index, record& tracking) {
tracking.use(1);
stack_function sf(L, index);
return sf.dump(&dump_panic_on_error);
}
};
} // namespace stack
} // namespace sol
#endif // SOL_FUNCTION_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_FUNCTION_HPP
#define SOL_FUNCTION_HPP
#include <sol/stack.hpp>
#include <sol/unsafe_function.hpp>
#include <sol/protected_function.hpp>
#include <sol/bytecode.hpp>
#include <functional>
namespace sol {
template <typename... Ret, typename... Args>
decltype(auto) stack_proxy::call(Args&&... args) {
stack_function sf(this->lua_state(), this->stack_index());
return sf.template call<Ret...>(std::forward<Args>(args)...);
}
inline protected_function_result::protected_function_result(unsafe_function_result&& o) noexcept
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
o.abandon();
}
inline protected_function_result& protected_function_result::operator=(unsafe_function_result&& o) noexcept {
L = o.lua_state();
index = o.stack_index();
returncount = o.return_count();
popcount = o.return_count();
err = o.status();
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
o.abandon();
return *this;
}
inline unsafe_function_result::unsafe_function_result(protected_function_result&& o) noexcept
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()) {
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
o.abandon();
}
inline unsafe_function_result& unsafe_function_result::operator=(protected_function_result&& o) noexcept {
L = o.lua_state();
index = o.stack_index();
returncount = o.return_count();
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
o.abandon();
return *this;
}
namespace detail {
template <typename... R>
struct std_shim {
unsafe_function lua_func_;
std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
}
template <typename... Args>
meta::return_type_t<R...> operator()(Args&&... args) {
return lua_func_.call<R...>(std::forward<Args>(args)...);
}
};
template <>
struct std_shim<void> {
unsafe_function lua_func_;
std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
}
template <typename... Args>
void operator()(Args&&... args) {
lua_func_.call<void>(std::forward<Args>(args)...);
}
};
} // namespace detail
namespace stack {
template <typename Signature>
struct unqualified_getter<std::function<Signature>> {
typedef meta::bind_traits<Signature> fx_t;
typedef typename fx_t::args_list args_lists;
typedef meta::tuple_types<typename fx_t::return_type> return_types;
template <typename... R>
static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
detail::std_shim<R...> fx(unsafe_function(L, index));
return fx;
}
static std::function<Signature> get(lua_State* L, int index, record& tracking) {
tracking.use(1);
type t = type_of(L, index);
if (t == type::none || t == type::lua_nil) {
return nullptr;
}
return get_std_func(return_types(), L, index);
}
};
template <typename Allocator>
struct unqualified_getter<basic_bytecode<Allocator>> {
static basic_bytecode<Allocator> get(lua_State* L, int index, record& tracking) {
tracking.use(1);
stack_function sf(L, index);
return sf.dump(&dump_panic_on_error);
}
};
} // namespace stack
} // namespace sol
#endif // SOL_FUNCTION_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -217,7 +217,7 @@ namespace sol {
int upvalues = 0;
upvalues += stack::push(L, nullptr);
upvalues += stack::push(L, std::forward<Fx>(fx));
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<true>;
lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues);
@ -237,7 +237,7 @@ namespace sol {
int upvalues = 0;
upvalues += stack::push(L, nullptr);
upvalues += stack::push(L, std::forward<Fx>(fx));
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<is_yielding>;
lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues);
@ -398,7 +398,7 @@ namespace sol {
struct unqualified_pusher<Signature,
std::enable_if_t<meta::all<std::is_function<std::remove_pointer_t<Signature>>, meta::neg<std::is_same<Signature, lua_CFunction>>,
meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
,
meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>,
meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>>
@ -711,7 +711,7 @@ namespace sol {
namespace stack_detail {
template <typename Function, typename Handler>
bool check_function_pointer(lua_State* L, int index, Handler&& handler, record& tracking) noexcept {
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
tracking.use(1);
bool success = lua_iscfunction(L, index) == 1;
if (success) {
@ -737,7 +737,7 @@ namespace sol {
template <typename Function>
Function* get_function_pointer(lua_State* L, int index, record& tracking) noexcept {
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
tracking.use(1);
auto udata = stack::stack_detail::get_as_upvalues_using_function<Function*>(L, index);
Function* fx = udata.first;
@ -747,7 +747,7 @@ namespace sol {
(void)index;
(void)tracking;
static_assert(meta::meta_detail::always_true<Function>::value,
#if SOL_IS_DEFAULT_OFF(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_DEFAULT_OFF(SOL_GET_FUNCTION_POINTER_UNSAFE)
"You are attempting to retrieve a function pointer type. "
"This is inherently unsafe in sol2. In order to do this, you must turn on the "
"SOL_GET_FUNCTION_POINTER_UNSAFE configuration macro, as detailed in the documentation. "

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -62,4 +62,4 @@ namespace sol { namespace function_detail {
};
}} // namespace sol::function_detail
#endif // SOL_FUNCTION_TYPES_OVERLOAD_HPP
#endif // SOL_FUNCTION_TYPES_OVERLOAD_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -74,7 +74,7 @@ namespace sol { namespace function_detail {
}
static int call(lua_State* L, member_function& self)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -90,7 +90,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -35,7 +35,7 @@ namespace sol { namespace function_detail {
using traits_type = meta::bind_traits<function_type>;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -70,7 +70,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -88,7 +88,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -110,7 +110,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -126,7 +126,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -153,7 +153,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -175,7 +175,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -191,7 +191,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -216,7 +216,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -238,7 +238,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -254,7 +254,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -268,7 +268,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -290,7 +290,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -320,7 +320,13 @@ namespace sol { namespace function_detail {
}
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_CLANG)
// apparent regression in clang 18 - llvm/llvm-project#91362
#else
noexcept(std::is_nothrow_copy_assignable_v<T>)
#endif
{
int nr;
if constexpr (no_trampoline) {
nr = real_call(L);
@ -360,7 +366,13 @@ namespace sol { namespace function_detail {
}
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_CLANG)
// apparent regression in clang 18 - llvm/llvm-project#91362
#else
noexcept(std::is_nothrow_copy_assignable_v<T>)
#endif
{
int nr;
if constexpr (no_trampoline) {
nr = real_call(L);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -121,7 +121,7 @@ namespace sol {
typedef meta::unqualified_t<F> Fu;
typedef std::integral_constant<bool,
std::is_same<Fu, lua_CFunction>::value
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
|| std::is_same<Fu, detail::lua_CFunction_noexcept>::value
#endif
>

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -1,195 +1,195 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_INHERITANCE_HPP
#define SOL_INHERITANCE_HPP
#include <sol/types.hpp>
#include <sol/usertype_traits.hpp>
#include <sol/unique_usertype_traits.hpp>
namespace sol {
template <typename... Args>
struct base_list { };
template <typename... Args>
using bases = base_list<Args...>;
typedef bases<> base_classes_tag;
const auto base_classes = base_classes_tag();
template <typename... Args>
struct is_to_stringable<base_list<Args...>> : std::false_type { };
namespace detail {
inline decltype(auto) base_class_check_key() {
static const auto& key = "class_check";
return key;
}
inline decltype(auto) base_class_cast_key() {
static const auto& key = "class_cast";
return key;
}
inline decltype(auto) base_class_index_propogation_key() {
static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
return key;
}
inline decltype(auto) base_class_new_index_propogation_key() {
static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
return key;
}
template <typename T>
struct inheritance {
typedef typename base<T>::type bases_t;
static bool type_check_bases(types<>, const string_view&) {
return false;
}
template <typename Base, typename... Args>
static bool type_check_bases(types<Base, Args...>, const string_view& ti) {
return ti == usertype_traits<Base>::qualified_name() || type_check_bases(types<Args...>(), ti);
}
static bool type_check(const string_view& ti) {
return ti == usertype_traits<T>::qualified_name() || type_check_bases(bases_t(), ti);
}
template <typename... Bases>
static bool type_check_with(const string_view& ti) {
return ti == usertype_traits<T>::qualified_name() || type_check_bases(types<Bases...>(), ti);
}
static void* type_cast_bases(types<>, T*, const string_view&) {
return nullptr;
}
template <typename Base, typename... Args>
static void* type_cast_bases(types<Base, Args...>, T* data, const string_view& ti) {
// Make sure to convert to T first, and then dynamic cast to the proper type
return ti != usertype_traits<Base>::qualified_name() ? type_cast_bases(types<Args...>(), data, ti)
: static_cast<void*>(static_cast<Base*>(data));
}
static void* type_cast(void* voiddata, const string_view& ti) {
T* data = static_cast<T*>(voiddata);
return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(bases_t(), data, ti) : data);
}
template <typename... Bases>
static void* type_cast_with(void* voiddata, const string_view& ti) {
T* data = static_cast<T*>(voiddata);
return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(types<Bases...>(), data, ti) : data);
}
template <typename U>
static bool type_unique_cast_bases(types<>, void*, void*, const string_view&) {
return 0;
}
template <typename U, typename Base, typename... Args>
static int type_unique_cast_bases(types<Base, Args...>, void* source_data, void* target_data, const string_view& ti) {
using uu_traits = unique_usertype_traits<U>;
using base_ptr = typename uu_traits::template rebind_actual_type<Base>;
string_view base_ti = usertype_traits<Base>::qualified_name();
if (base_ti == ti) {
if (target_data != nullptr) {
U* source = static_cast<U*>(source_data);
base_ptr* target = static_cast<base_ptr*>(target_data);
// perform proper derived -> base conversion
*target = *source;
}
return 2;
}
return type_unique_cast_bases<U>(types<Args...>(), source_data, target_data, ti);
}
template <typename U>
static int type_unique_cast(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
if constexpr (is_actual_type_rebindable_for_v<U>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<U>;
using maybe_bases_or_empty = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, bases_t>;
string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
if (rebind_ti != this_rebind_ti) {
// this is not even of the same unique type
return 0;
}
string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) {
// direct match, return 1
return 1;
}
return type_unique_cast_bases<U>(maybe_bases_or_empty(), source_data, target_data, ti);
}
else {
(void)rebind_ti;
string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) {
// direct match, return 1
return 1;
}
return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
}
}
template <typename U, typename... Bases>
static int type_unique_cast_with(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
using uc_bases_t = types<Bases...>;
if constexpr (is_actual_type_rebindable_for_v<U>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<U>;
using cond_bases_t = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, uc_bases_t>;
string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
if (rebind_ti != this_rebind_ti) {
// this is not even of the same unique type
return 0;
}
string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) {
// direct match, return 1
return 1;
}
return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
}
else {
(void)rebind_ti;
string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) {
// direct match, return 1
return 1;
}
return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
}
}
};
using inheritance_check_function = decltype(&inheritance<void>::type_check);
using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
using inheritance_unique_cast_function = decltype(&inheritance<void>::type_unique_cast<void>);
} // namespace detail
} // namespace sol
#endif // SOL_INHERITANCE_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_INHERITANCE_HPP
#define SOL_INHERITANCE_HPP
#include <sol/types.hpp>
#include <sol/usertype_traits.hpp>
#include <sol/unique_usertype_traits.hpp>
namespace sol {
template <typename... Args>
struct base_list { };
template <typename... Args>
using bases = base_list<Args...>;
typedef bases<> base_classes_tag;
const auto base_classes = base_classes_tag();
template <typename... Args>
struct is_to_stringable<base_list<Args...>> : std::false_type { };
namespace detail {
inline decltype(auto) base_class_check_key() {
static const auto& key = "class_check";
return key;
}
inline decltype(auto) base_class_cast_key() {
static const auto& key = "class_cast";
return key;
}
inline decltype(auto) base_class_index_propogation_key() {
static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
return key;
}
inline decltype(auto) base_class_new_index_propogation_key() {
static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
return key;
}
template <typename T>
struct inheritance {
typedef typename base<T>::type bases_t;
static bool type_check_bases(types<>, const string_view&) {
return false;
}
template <typename Base, typename... Args>
static bool type_check_bases(types<Base, Args...>, const string_view& ti) {
return ti == usertype_traits<Base>::qualified_name() || type_check_bases(types<Args...>(), ti);
}
static bool type_check(const string_view& ti) {
return ti == usertype_traits<T>::qualified_name() || type_check_bases(bases_t(), ti);
}
template <typename... Bases>
static bool type_check_with(const string_view& ti) {
return ti == usertype_traits<T>::qualified_name() || type_check_bases(types<Bases...>(), ti);
}
static void* type_cast_bases(types<>, T*, const string_view&) {
return nullptr;
}
template <typename Base, typename... Args>
static void* type_cast_bases(types<Base, Args...>, T* data, const string_view& ti) {
// Make sure to convert to T first, and then dynamic cast to the proper type
return ti != usertype_traits<Base>::qualified_name() ? type_cast_bases(types<Args...>(), data, ti)
: static_cast<void*>(static_cast<Base*>(data));
}
static void* type_cast(void* voiddata, const string_view& ti) {
T* data = static_cast<T*>(voiddata);
return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(bases_t(), data, ti) : data);
}
template <typename... Bases>
static void* type_cast_with(void* voiddata, const string_view& ti) {
T* data = static_cast<T*>(voiddata);
return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(types<Bases...>(), data, ti) : data);
}
template <typename U>
static bool type_unique_cast_bases(types<>, void*, void*, const string_view&) {
return 0;
}
template <typename U, typename Base, typename... Args>
static int type_unique_cast_bases(types<Base, Args...>, void* source_data, void* target_data, const string_view& ti) {
using uu_traits = unique_usertype_traits<U>;
using base_ptr = typename uu_traits::template rebind_actual_type<Base>;
string_view base_ti = usertype_traits<Base>::qualified_name();
if (base_ti == ti) {
if (target_data != nullptr) {
U* source = static_cast<U*>(source_data);
base_ptr* target = static_cast<base_ptr*>(target_data);
// perform proper derived -> base conversion
*target = *source;
}
return 2;
}
return type_unique_cast_bases<U>(types<Args...>(), source_data, target_data, ti);
}
template <typename U>
static int type_unique_cast(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
if constexpr (is_actual_type_rebindable_for_v<U>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<U>;
using maybe_bases_or_empty = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, bases_t>;
string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
if (rebind_ti != this_rebind_ti) {
// this is not even of the same unique type
return 0;
}
string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) {
// direct match, return 1
return 1;
}
return type_unique_cast_bases<U>(maybe_bases_or_empty(), source_data, target_data, ti);
}
else {
(void)rebind_ti;
string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) {
// direct match, return 1
return 1;
}
return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
}
}
template <typename U, typename... Bases>
static int type_unique_cast_with(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
using uc_bases_t = types<Bases...>;
if constexpr (is_actual_type_rebindable_for_v<U>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<U>;
using cond_bases_t = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, uc_bases_t>;
string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
if (rebind_ti != this_rebind_ti) {
// this is not even of the same unique type
return 0;
}
string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) {
// direct match, return 1
return 1;
}
return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
}
else {
(void)rebind_ti;
string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) {
// direct match, return 1
return 1;
}
return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
}
}
};
using inheritance_check_function = decltype(&inheritance<void>::type_check);
using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
using inheritance_unique_cast_function = decltype(&inheritance<void>::type_unique_cast<void>);
} // namespace detail
} // namespace sol
#endif // SOL_INHERITANCE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -39,7 +39,7 @@ namespace sol {
load_status err;
public:
load_result() noexcept = default;
load_result() noexcept : load_result(nullptr) {}
load_result(lua_State* Ls, int stackindex = -1, int retnum = 0, int popnum = 0, load_status lerr = load_status::ok) noexcept
: L(Ls), index(stackindex), returncount(retnum), popcount(popnum), err(lerr) {
}
@ -95,7 +95,7 @@ namespace sol {
if (valid()) {
return UT(nullopt);
}
return error(detail::direct_error, stack::get<std::string>(L, index));
return stack::stack_detail::get_error(L, index);
}
else {
if (!valid()) {
@ -106,15 +106,15 @@ namespace sol {
}
else {
if constexpr (std::is_same_v<T, error>) {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
#if SOL_IS_ON(SOL_SAFE_PROXIES)
if (valid()) {
type_panic_c_str(L, index, type_of(L, index), type::none, "expecting an error type (a string, from Lua)");
}
#endif // Check proxy type's safety
return error(detail::direct_error, stack::get<std::string>(L, index));
return stack::stack_detail::get_error(L, index);
}
else {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
#if SOL_IS_ON(SOL_SAFE_PROXIES)
if (!valid()) {
type_panic_c_str(L, index, type_of(L, index), type::none);
}
@ -142,7 +142,9 @@ namespace sol {
};
~load_result() {
stack::remove(L, index, popcount);
if (L != nullptr) {
stack::remove(L, index, popcount);
}
}
};
} // namespace sol

View file

@ -1,95 +1,95 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_LUA_TABLE_HPP
#define SOL_LUA_TABLE_HPP
#include <sol/table_core.hpp>
namespace sol {
template <typename ref_t>
struct basic_lua_table : basic_table_core<false, ref_t> {
private:
using base_t = basic_table_core<false, ref_t>;
friend class state;
friend class state_view;
public:
using base_t::lua_state;
basic_lua_table() noexcept = default;
basic_lua_table(const basic_lua_table&) = default;
basic_lua_table(basic_lua_table&&) = default;
basic_lua_table& operator=(const basic_lua_table&) = default;
basic_lua_table& operator=(basic_lua_table&&) = default;
basic_lua_table(const stack_reference& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
}
basic_lua_table(stack_reference&& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
}
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lua_table(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler);
#endif // Safety
}
basic_lua_table(lua_State* L, const new_table& nt) : base_t(L, nt) {
if (!is_stack_based<meta::unqualified_t<ref_t>>::value) {
lua_pop(L, 1);
}
}
basic_lua_table(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
constructor_handler handler {};
stack::check<basic_lua_table>(L, index, handler);
#endif // Safety
}
basic_lua_table(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler);
#endif // Safety
}
template <typename T,
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_lua_table>>, meta::neg<std::is_same<ref_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lua_table(T&& r) noexcept : basic_lua_table(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler);
}
#endif // Safety
}
basic_lua_table(lua_nil_t r) noexcept : basic_lua_table(detail::no_safety, r) {
}
};
} // namespace sol
#endif // SOL_LUA_TABLE_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_LUA_TABLE_HPP
#define SOL_LUA_TABLE_HPP
#include <sol/table_core.hpp>
namespace sol {
template <typename ref_t>
struct basic_lua_table : basic_table_core<false, ref_t> {
private:
using base_t = basic_table_core<false, ref_t>;
friend class state;
friend class state_view;
public:
using base_t::lua_state;
basic_lua_table() noexcept = default;
basic_lua_table(const basic_lua_table&) = default;
basic_lua_table(basic_lua_table&&) = default;
basic_lua_table& operator=(const basic_lua_table&) = default;
basic_lua_table& operator=(basic_lua_table&&) = default;
basic_lua_table(const stack_reference& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
}
basic_lua_table(stack_reference&& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
}
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lua_table(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler);
#endif // Safety
}
basic_lua_table(lua_State* L, const new_table& nt) : base_t(L, nt) {
if (!is_stack_based<meta::unqualified_t<ref_t>>::value) {
lua_pop(L, 1);
}
}
basic_lua_table(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_lua_table>(L, index, handler);
#endif // Safety
}
basic_lua_table(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler);
#endif // Safety
}
template <typename T,
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_lua_table>>, meta::neg<std::is_same<ref_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lua_table(T&& r) noexcept : basic_lua_table(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler);
}
#endif // Safety
}
basic_lua_table(lua_nil_t r) noexcept : basic_lua_table(detail::no_safety, r) {
}
};
} // namespace sol
#endif // SOL_LUA_TABLE_HPP

View file

@ -1,162 +1,162 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_LUA_VALUE_HPP
#define SOL_LUA_VALUE_HPP
#include <sol/stack.hpp>
#include <sol/reference.hpp>
#include <sol/make_reference.hpp>
namespace sol {
struct lua_value {
public:
struct arr : detail::ebco<std::initializer_list<lua_value>> {
private:
using base_t = detail::ebco<std::initializer_list<lua_value>>;
public:
using base_t::base_t;
};
private:
template <typename T>
using is_reference_or_lua_value_init_list
= meta::any<meta::is_specialization_of<T, std::initializer_list>, std::is_same<T, reference>, std::is_same<T, arr>>;
template <typename T>
using is_lua_value_single_constructible = meta::any<std::is_same<T, lua_value>, is_reference_or_lua_value_init_list<T>>;
static lua_State*& thread_local_lua_state() {
#if SOL_IS_ON(SOL_USE_THREAD_LOCAL_I_)
static thread_local lua_State* L = nullptr;
#else
static lua_State* L = nullptr;
#endif
return L;
}
reference ref_value;
public:
static void set_lua_state(lua_State* L) {
thread_local_lua_state() = L;
}
template <typename T, meta::disable<is_reference_or_lua_value_init_list<meta::unqualified_t<T>>> = meta::enabler>
lua_value(lua_State* L_, T&& value) : lua_value(((set_lua_state(L_)), std::forward<T>(value))) {
}
template <typename T, meta::disable<is_lua_value_single_constructible<meta::unqualified_t<T>>> = meta::enabler>
lua_value(T&& value) : ref_value(make_reference(thread_local_lua_state(), std::forward<T>(value))) {
}
lua_value(lua_State* L_, std::initializer_list<std::pair<lua_value, lua_value>> il)
: lua_value([&L_, &il]() {
set_lua_state(L_);
return std::move(il);
}()) {
}
lua_value(std::initializer_list<std::pair<lua_value, lua_value>> il) : ref_value(make_reference(thread_local_lua_state(), std::move(il))) {
}
lua_value(lua_State* L_, arr il)
: lua_value([&L_, &il]() {
set_lua_state(L_);
return std::move(il);
}()) {
}
lua_value(arr il) : ref_value(make_reference(thread_local_lua_state(), std::move(il.value()))) {
}
lua_value(lua_State* L_, reference r)
: lua_value([&L_, &r]() {
set_lua_state(L_);
return std::move(r);
}()) {
}
lua_value(reference r) : ref_value(std::move(r)) {
}
lua_value(const lua_value&) noexcept = default;
lua_value(lua_value&&) = default;
lua_value& operator=(const lua_value&) = default;
lua_value& operator=(lua_value&&) = default;
const reference& value() const& {
return ref_value;
}
reference& value() & {
return ref_value;
}
reference&& value() && {
return std::move(ref_value);
}
template <typename T>
decltype(auto) as() const {
ref_value.push();
return stack::pop<T>(ref_value.lua_state());
}
template <typename T>
bool is() const {
int r = ref_value.registry_index();
if (r == LUA_REFNIL)
return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
if (r == LUA_NOREF)
return false;
auto pp = stack::push_pop(ref_value);
return stack::check<T>(ref_value.lua_state(), -1, &no_panic);
}
};
using array_value = typename lua_value::arr;
namespace stack {
template <>
struct unqualified_pusher<lua_value> {
static int push(lua_State* L, const lua_value& lv) {
return stack::push(L, lv.value());
}
static int push(lua_State* L, lua_value&& lv) {
return stack::push(L, std::move(lv).value());
}
};
template <>
struct unqualified_getter<lua_value> {
static lua_value get(lua_State* L, int index, record& tracking) {
return lua_value(L, stack::get<reference>(L, index, tracking));
}
};
} // namespace stack
} // namespace sol
#endif // SOL_LUA_VALUE_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_LUA_VALUE_HPP
#define SOL_LUA_VALUE_HPP
#include <sol/stack.hpp>
#include <sol/reference.hpp>
#include <sol/make_reference.hpp>
namespace sol {
struct lua_value {
public:
struct arr : detail::ebco<std::initializer_list<lua_value>> {
private:
using base_t = detail::ebco<std::initializer_list<lua_value>>;
public:
using base_t::base_t;
};
private:
template <typename T>
using is_reference_or_lua_value_init_list
= meta::any<meta::is_specialization_of<T, std::initializer_list>, std::is_same<T, reference>, std::is_same<T, arr>>;
template <typename T>
using is_lua_value_single_constructible = meta::any<std::is_same<T, lua_value>, is_reference_or_lua_value_init_list<T>>;
static lua_State*& thread_local_lua_state() {
#if SOL_IS_ON(SOL_USE_THREAD_LOCAL)
static thread_local lua_State* L = nullptr;
#else
static lua_State* L = nullptr;
#endif
return L;
}
reference ref_value;
public:
static void set_lua_state(lua_State* L) {
thread_local_lua_state() = L;
}
template <typename T, meta::disable<is_reference_or_lua_value_init_list<meta::unqualified_t<T>>> = meta::enabler>
lua_value(lua_State* L_, T&& value) : lua_value(((set_lua_state(L_)), std::forward<T>(value))) {
}
template <typename T, meta::disable<is_lua_value_single_constructible<meta::unqualified_t<T>>> = meta::enabler>
lua_value(T&& value) : ref_value(make_reference(thread_local_lua_state(), std::forward<T>(value))) {
}
lua_value(lua_State* L_, std::initializer_list<std::pair<lua_value, lua_value>> il)
: lua_value([&L_, &il]() {
set_lua_state(L_);
return std::move(il);
}()) {
}
lua_value(std::initializer_list<std::pair<lua_value, lua_value>> il) : ref_value(make_reference(thread_local_lua_state(), std::move(il))) {
}
lua_value(lua_State* L_, arr il)
: lua_value([&L_, &il]() {
set_lua_state(L_);
return std::move(il);
}()) {
}
lua_value(arr il) : ref_value(make_reference(thread_local_lua_state(), std::move(il.value()))) {
}
lua_value(lua_State* L_, reference r)
: lua_value([&L_, &r]() {
set_lua_state(L_);
return std::move(r);
}()) {
}
lua_value(reference r) : ref_value(std::move(r)) {
}
lua_value(const lua_value&) noexcept = default;
lua_value(lua_value&&) = default;
lua_value& operator=(const lua_value&) = default;
lua_value& operator=(lua_value&&) = default;
const reference& value() const& {
return ref_value;
}
reference& value() & {
return ref_value;
}
reference&& value() && {
return std::move(ref_value);
}
template <typename T>
decltype(auto) as() const {
ref_value.push();
return stack::pop<T>(ref_value.lua_state());
}
template <typename T>
bool is() const {
int r = ref_value.registry_index();
if (r == LUA_REFNIL)
return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
if (r == LUA_NOREF)
return false;
auto pp = stack::push_pop(ref_value);
return stack::check<T>(ref_value.lua_state(), -1, &no_panic);
}
};
using array_value = typename lua_value::arr;
namespace stack {
template <>
struct unqualified_pusher<lua_value> {
static int push(lua_State* L, const lua_value& lv) {
return stack::push(L, lv.value());
}
static int push(lua_State* L, lua_value&& lv) {
return stack::push(L, std::move(lv).value());
}
};
template <>
struct unqualified_getter<lua_value> {
static lua_value get(lua_State* L, int index, record& tracking) {
return lua_value(L, stack::get<reference>(L, index, tracking));
}
};
} // namespace stack
} // namespace sol
#endif // SOL_LUA_VALUE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -86,20 +86,20 @@ namespace sol {
}
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_metatable(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_metatable>(lua_state(), -1, handler);
#endif // Safety
}
basic_metatable(lua_State* L, int index = -1) : basic_metatable(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_metatable>(L, index, handler);
#endif // Safety
}
basic_metatable(lua_State* L, ref_index index) : basic_metatable(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_metatable>(lua_state(), -1, handler);
@ -109,7 +109,7 @@ namespace sol {
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_metatable(T&& r) noexcept : basic_metatable(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -27,7 +27,7 @@
#include <sol/forward.hpp>
#include <sol/in_place.hpp>
#include <sol/traits.hpp>
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
#include <boost/optional.hpp>
#else
#include <sol/optional_implementation.hpp>
@ -38,7 +38,7 @@
namespace sol {
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
template <typename T>
using optional = boost::optional<T>;
using nullopt_t = boost::none_t;
@ -59,14 +59,14 @@ namespace sol {
inline static constexpr std::nullopt_t value = std::nullopt;
};
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
template <typename T>
struct associated_nullopt<boost::optional<T>> {
inline static SOL_BOOST_NONE_CONSTEXPR_I_ boost::none_t value = boost::none;
};
#endif // Boost nullopt
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
template <typename T>
inline SOL_BOOST_NONE_CONSTEXPR_I_ auto associated_nullopt_v = associated_nullopt<T>::value;
#else
@ -76,7 +76,7 @@ namespace sol {
} // namespace detail
} // namespace sol
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
#undef SOL_BOOST_NONE_CONSTEXPR_I_
#endif

View file

@ -1,6 +1,6 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -1375,7 +1375,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T& value() & {
if (has_value())
return this->m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -1386,7 +1386,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const& {
if (has_value())
return this->m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -1396,7 +1396,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T&& value() && {
if (has_value())
return std::move(this->m_value);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -1408,7 +1408,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T&& value() const&& {
if (has_value())
return std::move(this->m_value);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -2186,12 +2186,9 @@ namespace sol {
/// one.
///
/// \group emplace
template <class... Args>
T& emplace(Args&&... args) noexcept {
static_assert(std::is_constructible<T, Args&&...>::value, "T must be constructible with Args");
T& emplace(T& arg) noexcept {
*this = nullopt;
new (static_cast<void*>(this)) optional(std::in_place, std::forward<Args>(args)...);
m_value = &arg;
return **this;
}
@ -2251,7 +2248,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T& value() {
if (has_value())
return *m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -2262,7 +2259,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const {
if (has_value())
return *m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -46,4 +46,4 @@ namespace sol {
}
} // namespace sol
#endif // SOL_OVERLOAD_HPP
#endif // SOL_OVERLOAD_HPP

View file

@ -1,262 +1,262 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_PACKAGED_COROUTINE_HPP
#define SOL_PACKAGED_COROUTINE_HPP
#include <sol/reference.hpp>
#include <sol/object.hpp>
#include <sol/stack.hpp>
#include <sol/function_result.hpp>
#include <sol/thread.hpp>
#include <sol/protected_handler.hpp>
#include <sol/coroutine.hpp>
namespace sol {
#if 0
class packaged_coroutine {
private:
lua_State* m_L;
sol::stateless_reference m_coroutine_reference;
sol::stateless_reference m_error_handler;
sol::thread m_thread_reference;
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
#if SOL_LUA_VERSION_I_ >= 504
int nresults;
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults));
#else
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount)));
#endif
}
template <std::size_t... I, typename... Ret>
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) {
luacall(n, sizeof...(Ret));
return stack::pop<std::tuple<Ret...>>(lua_state());
}
template <std::size_t I, typename Ret>
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) {
luacall(n, 1);
return stack::pop<Ret>(lua_state());
}
template <std::size_t I>
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) {
luacall(n, 0);
}
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
int firstreturn = 1;
luacall(n, LUA_MULTRET);
int poststacksize = lua_gettop(this->lua_state());
int returncount = poststacksize - (firstreturn - 1);
if (error()) {
if (m_error_handler.valid()) {
string_view err = stack::get<string_view>(this->lua_state(), poststacksize);
m_error_handler.push();
stack::push(this->lua_state(), err);
lua_call(lua_state(), 1, 1);
}
return protected_function_result(this->lua_state(), lua_absindex(this->lua_state(), -1), 1, returncount, status());
}
return protected_function_result(this->lua_state(), firstreturn, returncount, returncount, status());
}
public:
using base_t::lua_state;
basic_packaged_coroutine() = default;
template <typename T,
meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_packaged_coroutine>>,
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(T&& r) noexcept
: base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
}
#endif // Safety
}
basic_packaged_coroutine(const basic_packaged_coroutine& other) = default;
basic_packaged_coroutine& operator=(const basic_packaged_coroutine&) = default;
basic_packaged_coroutine(basic_packaged_coroutine&& other) noexcept
: base_t(std::move(other)), m_error_handler(this->lua_state(), std::move(other.m_error_handler)) {
}
basic_packaged_coroutine& operator=(basic_packaged_coroutine&& other) noexcept {
base_t::operator=(std::move(other));
// must change the state, since it could change on the coroutine type
m_error_handler.abandon();
m_error_handler = handler_t(this->lua_state(), std::move(other.m_error_handler));
return *this;
}
basic_packaged_coroutine(const basic_function<base_t>& b) noexcept
: basic_packaged_coroutine(b, detail::get_default_handler<reference, is_main_threaded_v<base_t>>(b.lua_state())) {
}
basic_packaged_coroutine(basic_function<base_t>&& b) noexcept
: basic_packaged_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded_v<base_t>>(b.lua_state())) {
}
basic_packaged_coroutine(const basic_function<base_t>& b, handler_t eh) noexcept : base_t(b), m_error_handler(std::move(eh)) {
}
basic_packaged_coroutine(basic_function<base_t>&& b, handler_t eh) noexcept : base_t(std::move(b)), m_error_handler(std::move(eh)) {
}
basic_packaged_coroutine(const stack_reference& r) noexcept
: basic_packaged_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
}
basic_packaged_coroutine(stack_reference&& r) noexcept
: basic_packaged_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
}
basic_packaged_coroutine(const stack_reference& r, handler_t eh) noexcept : basic_packaged_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
}
basic_packaged_coroutine(stack_reference&& r, handler_t eh) noexcept : basic_packaged_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
}
template <typename Super>
basic_packaged_coroutine(const proxy_base<Super>& p)
: basic_packaged_coroutine(p, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
}
template <typename Super>
basic_packaged_coroutine(proxy_base<Super>&& p)
: basic_packaged_coroutine(std::move(p), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
}
template <typename Proxy, typename HandlerReference,
meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<HandlerReference>>>> = meta::enabler>
basic_packaged_coroutine(Proxy&& p, HandlerReference&& eh) : basic_packaged_coroutine(detail::force_cast<base_t>(p), std::forward<HandlerReference>(eh)) {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(lua_State* L, T&& r) noexcept
: basic_packaged_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
#endif // Safety
}
basic_packaged_coroutine(lua_nil_t n) : base_t(n), m_error_handler(n) {
}
basic_packaged_coroutine(lua_State* L, int index = -1)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, int index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety
}
basic_packaged_coroutine(lua_State* L, absolute_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety
}
basic_packaged_coroutine(lua_State* L, raw_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety
}
basic_packaged_coroutine(lua_State* L, ref_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
#endif // Safety
}
call_status status() const noexcept {
return stats;
}
bool error() const noexcept {
call_status cs = status();
return cs != call_status::ok && cs != call_status::yielded;
}
bool runnable() const noexcept {
return base_t::valid() && (status() == call_status::yielded);
}
reference error_handler() const noexcept {
return reference(m_L, registry_index(m_error_handler.index));
}
set_error_handler(reference new_error_handler) noexcept {
this->m_error_handler = stateless_reference(this->m_L, std::move(new_error_handler));
}
explicit operator bool() const noexcept {
return runnable();
}
template <typename... Args>
protected_function_result operator()(Args&&... args) {
return call<>(std::forward<Args>(args)...);
}
template <typename... Ret, typename... Args>
decltype(auto) operator()(types<Ret...>, Args&&... args) {
return call<Ret...>(std::forward<Args>(args)...);
}
template <typename... Ret, typename... Args>
decltype(auto) call(Args&&... args) {
// some users screw up coroutine.create
// and try to use it with sol::coroutine without ever calling the first resume in Lua
// this makes the stack incompatible with other kinds of stacks: protect against this
// make sure coroutines don't screw us over
base_t::push();
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
}
};
#endif
} // namespace sol
#endif // SOL_PACKAGED_COROUTINE_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_PACKAGED_COROUTINE_HPP
#define SOL_PACKAGED_COROUTINE_HPP
#include <sol/reference.hpp>
#include <sol/object.hpp>
#include <sol/stack.hpp>
#include <sol/function_result.hpp>
#include <sol/thread.hpp>
#include <sol/protected_handler.hpp>
#include <sol/coroutine.hpp>
namespace sol {
#if 0
class packaged_coroutine {
private:
lua_State* m_L;
sol::stateless_reference m_coroutine_reference;
sol::stateless_reference m_error_handler;
sol::thread m_thread_reference;
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
#if SOL_LUA_VERSION_I_ >= 504
int nresults;
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults));
#else
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount)));
#endif
}
template <std::size_t... I, typename... Ret>
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) {
luacall(n, sizeof...(Ret));
return stack::pop<std::tuple<Ret...>>(lua_state());
}
template <std::size_t I, typename Ret>
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) {
luacall(n, 1);
return stack::pop<Ret>(lua_state());
}
template <std::size_t I>
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) {
luacall(n, 0);
}
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
int firstreturn = 1;
luacall(n, LUA_MULTRET);
int poststacksize = lua_gettop(this->lua_state());
int returncount = poststacksize - (firstreturn - 1);
if (error()) {
if (m_error_handler.valid()) {
string_view err = stack::get<string_view>(this->lua_state(), poststacksize);
m_error_handler.push();
stack::push(this->lua_state(), err);
lua_call(lua_state(), 1, 1);
}
return protected_function_result(this->lua_state(), lua_absindex(this->lua_state(), -1), 1, returncount, status());
}
return protected_function_result(this->lua_state(), firstreturn, returncount, returncount, status());
}
public:
using base_t::lua_state;
basic_packaged_coroutine() = default;
template <typename T,
meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_packaged_coroutine>>,
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(T&& r) noexcept
: base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
}
#endif // Safety
}
basic_packaged_coroutine(const basic_packaged_coroutine& other) = default;
basic_packaged_coroutine& operator=(const basic_packaged_coroutine&) = default;
basic_packaged_coroutine(basic_packaged_coroutine&& other) noexcept
: base_t(std::move(other)), m_error_handler(this->lua_state(), std::move(other.m_error_handler)) {
}
basic_packaged_coroutine& operator=(basic_packaged_coroutine&& other) noexcept {
base_t::operator=(std::move(other));
// must change the state, since it could change on the coroutine type
m_error_handler.abandon();
m_error_handler = handler_t(this->lua_state(), std::move(other.m_error_handler));
return *this;
}
basic_packaged_coroutine(const basic_function<base_t>& b) noexcept
: basic_packaged_coroutine(b, detail::get_default_handler<reference, is_main_threaded_v<base_t>>(b.lua_state())) {
}
basic_packaged_coroutine(basic_function<base_t>&& b) noexcept
: basic_packaged_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded_v<base_t>>(b.lua_state())) {
}
basic_packaged_coroutine(const basic_function<base_t>& b, handler_t eh) noexcept : base_t(b), m_error_handler(std::move(eh)) {
}
basic_packaged_coroutine(basic_function<base_t>&& b, handler_t eh) noexcept : base_t(std::move(b)), m_error_handler(std::move(eh)) {
}
basic_packaged_coroutine(const stack_reference& r) noexcept
: basic_packaged_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
}
basic_packaged_coroutine(stack_reference&& r) noexcept
: basic_packaged_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
}
basic_packaged_coroutine(const stack_reference& r, handler_t eh) noexcept : basic_packaged_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
}
basic_packaged_coroutine(stack_reference&& r, handler_t eh) noexcept : basic_packaged_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
}
template <typename Super>
basic_packaged_coroutine(const proxy_base<Super>& p)
: basic_packaged_coroutine(p, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
}
template <typename Super>
basic_packaged_coroutine(proxy_base<Super>&& p)
: basic_packaged_coroutine(std::move(p), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
}
template <typename Proxy, typename HandlerReference,
meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<HandlerReference>>>> = meta::enabler>
basic_packaged_coroutine(Proxy&& p, HandlerReference&& eh) : basic_packaged_coroutine(detail::force_cast<base_t>(p), std::forward<HandlerReference>(eh)) {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(lua_State* L, T&& r) noexcept
: basic_packaged_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
#endif // Safety
}
basic_packaged_coroutine(lua_nil_t n) : base_t(n), m_error_handler(n) {
}
basic_packaged_coroutine(lua_State* L, int index = -1)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, int index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety
}
basic_packaged_coroutine(lua_State* L, absolute_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety
}
basic_packaged_coroutine(lua_State* L, raw_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety
}
basic_packaged_coroutine(lua_State* L, ref_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
#endif // Safety
}
call_status status() const noexcept {
return stats;
}
bool error() const noexcept {
call_status cs = status();
return cs != call_status::ok && cs != call_status::yielded;
}
bool runnable() const noexcept {
return base_t::valid() && (status() == call_status::yielded);
}
reference error_handler() const noexcept {
return reference(m_L, registry_index(m_error_handler.index));
}
set_error_handler(reference new_error_handler) noexcept {
this->m_error_handler = stateless_reference(this->m_L, std::move(new_error_handler));
}
explicit operator bool() const noexcept {
return runnable();
}
template <typename... Args>
protected_function_result operator()(Args&&... args) {
return call<>(std::forward<Args>(args)...);
}
template <typename... Ret, typename... Args>
decltype(auto) operator()(types<Ret...>, Args&&... args) {
return call<Ret...>(std::forward<Args>(args)...);
}
template <typename... Ret, typename... Args>
decltype(auto) call(Args&&... args) {
// some users screw up coroutine.create
// and try to use it with sol::coroutine without ever calling the first resume in Lua
// this makes the stack incompatible with other kinds of stacks: protect against this
// make sure coroutines don't screw us over
base_t::push();
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
}
};
#endif
} // namespace sol
#endif // SOL_PACKAGED_COROUTINE_HPP

View file

@ -1,275 +1,275 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_PAIRS_ITERATOR_HPP
#define SOL_PAIRS_ITERATOR_HPP
#include <sol/version.hpp>
#include <sol/reference.hpp>
#include <sol/stack_reference.hpp>
#include <sol/table_iterator.hpp>
#include <sol/protected_function.hpp>
#include <sol/stack/detail/pairs.hpp>
namespace sol {
struct pairs_sentinel { };
class pairs_iterator {
private:
inline static constexpr int empty_key_index = -1;
public:
using key_type = object;
using mapped_type = object;
using value_type = std::pair<object, object>;
using iterator_category = std::input_iterator_tag;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using const_pointer = value_type const*;
using reference = value_type&;
using const_reference = const value_type&;
pairs_iterator() noexcept
: m_L(nullptr)
, m_next_function_ref(lua_nil)
, m_table_ref(lua_nil)
, m_cached_key_value_pair({ lua_nil, lua_nil })
, m_key_index(empty_key_index)
, m_iteration_index(0) {
}
pairs_iterator(const pairs_iterator&) = delete;
pairs_iterator& operator=(const pairs_iterator&) = delete;
pairs_iterator(pairs_iterator&& right) noexcept
: m_L(right.m_L)
, m_next_function_ref(std::move(right.m_next_function_ref))
, m_table_ref(std::move(right.m_table_ref))
, m_cached_key_value_pair(std::move(right.m_cached_key_value_pair))
, m_key_index(right.m_key_index)
, m_iteration_index(right.m_iteration_index) {
right.m_key_index = empty_key_index;
}
pairs_iterator& operator=(pairs_iterator&& right) noexcept {
m_L = right.m_L;
m_next_function_ref = std::move(right.m_next_function_ref);
m_table_ref = std::move(right.m_table_ref);
m_cached_key_value_pair = std::move(right.m_cached_key_value_pair);
m_key_index = right.m_key_index;
m_iteration_index = right.m_iteration_index;
right.m_key_index = empty_key_index;
return *this;
}
template <typename Source>
pairs_iterator(const Source& source_) noexcept : m_L(source_.lua_state()), m_key_index(empty_key_index), m_iteration_index(0) {
if (m_L == nullptr || !source_.valid()) {
m_key_index = empty_key_index;
return;
}
int source_index = -source_.push(m_L);
int abs_source_index = lua_absindex(m_L, source_index);
int metatable_exists = lua_getmetatable(m_L, abs_source_index);
lua_remove(m_L, abs_source_index);
if (metatable_exists == 1) {
// just has a metatable, but does it have __pairs ?
stack_reference metatable(m_L, raw_index(abs_source_index));
stack::get_field<is_global_table_v<Source>, true>(m_L, meta_function::pairs, metatable.stack_index());
optional<protected_function> maybe_pairs_function = stack::pop<optional<protected_function>>(m_L);
if (maybe_pairs_function.has_value()) {
protected_function& pairs_function = *maybe_pairs_function;
protected_function_result next_fn_and_table_and_first_key = pairs_function(source_);
if (next_fn_and_table_and_first_key.valid()) {
m_next_function_ref = next_fn_and_table_and_first_key.get<protected_function>(0);
m_table_ref = next_fn_and_table_and_first_key.get<sol::reference>(1);
m_key_index = next_fn_and_table_and_first_key.stack_index() - 1;
// remove next function and table
lua_remove(m_L, m_key_index);
lua_remove(m_L, m_key_index);
next_fn_and_table_and_first_key.abandon();
lua_remove(m_L, abs_source_index);
this->operator++();
m_iteration_index = 0;
return;
}
}
}
{
auto maybe_next = stack::stack_detail::find_lua_next_function(m_L);
if (maybe_next.has_value()) {
m_next_function_ref = std::move(*maybe_next);
m_table_ref = source_;
stack::push(m_L, lua_nil);
m_key_index = lua_gettop(m_L);
this->operator++();
m_iteration_index = 0;
return;
}
}
// okay, so none of the above worked and now we need to create
// a shim / polyfill instead
stack::push(m_L, &stack::stack_detail::c_lua_next);
m_next_function_ref = stack::pop<protected_function>(m_L);
m_table_ref = source_;
stack::push(m_L, lua_nil);
m_key_index = lua_gettop(m_L);
this->operator++();
m_iteration_index = 0;
}
pairs_iterator& operator++() {
if (m_key_index == empty_key_index) {
return *this;
}
{
sol::protected_function_result next_results = m_next_function_ref(m_table_ref, stack_reference(m_L, m_key_index));
if (!next_results.valid()) {
// TODO: abort, or throw an error?
m_clear();
m_key_index = empty_key_index;
return *this;
}
int next_results_count = next_results.return_count();
if (next_results_count < 2) {
// iteration is over!
next_results.abandon();
lua_settop(m_L, m_key_index - 1);
m_key_index = empty_key_index;
++m_iteration_index;
return *this;
}
else {
lua_remove(m_L, m_key_index);
m_key_index = next_results.stack_index() - 1;
m_cached_key_value_pair.first = stack::get<object>(m_L, m_key_index);
m_cached_key_value_pair.second = stack::get<object>(m_L, m_key_index + 1);
lua_settop(m_L, m_key_index);
next_results.abandon();
}
}
++m_iteration_index;
return *this;
}
std::ptrdiff_t index() const {
return static_cast<std::ptrdiff_t>(m_iteration_index);
}
const_reference operator*() const noexcept {
return m_cached_key_value_pair;
}
reference operator*() noexcept {
return m_cached_key_value_pair;
}
friend bool operator==(const pairs_iterator& left, const pairs_iterator& right) noexcept {
return left.m_table_ref == right.m_table_ref && left.m_iteration_index == right.m_iteration_index;
}
friend bool operator!=(const pairs_iterator& left, const pairs_iterator& right) noexcept {
return left.m_table_ref != right.m_table_ref || left.m_iteration_index != right.m_iteration_index;
}
friend bool operator==(const pairs_iterator& left, const pairs_sentinel&) noexcept {
return left.m_key_index == empty_key_index;
}
friend bool operator!=(const pairs_iterator& left, const pairs_sentinel&) noexcept {
return left.m_key_index != empty_key_index;
}
friend bool operator==(const pairs_sentinel&, const pairs_iterator& left) noexcept {
return left.m_key_index == empty_key_index;
}
friend bool operator!=(const pairs_sentinel&, const pairs_iterator& left) noexcept {
return left.m_key_index != empty_key_index;
}
~pairs_iterator() {
if (m_key_index != empty_key_index) {
m_clear();
}
}
private:
void m_clear() noexcept {
lua_remove(m_L, m_key_index);
}
lua_State* m_L;
protected_function m_next_function_ref;
sol::reference m_table_ref;
std::pair<object, object> m_cached_key_value_pair;
int m_key_index;
int m_iteration_index;
};
template <typename Source>
class basic_pairs_range {
private:
using source_t = std::add_lvalue_reference_t<Source>;
source_t m_source;
public:
using iterator = pairs_iterator;
using const_iterator = pairs_iterator;
basic_pairs_range(source_t source_) noexcept : m_source(source_) {
}
iterator begin() noexcept {
return iterator(m_source);
}
iterator begin() const noexcept {
return iterator(m_source);
}
const_iterator cbegin() const noexcept {
return const_iterator(m_source);
}
pairs_sentinel end() noexcept {
return {};
}
pairs_sentinel end() const noexcept {
return {};
}
pairs_sentinel cend() const noexcept {
return {};
}
};
} // namespace sol
#endif // SOL_PAIRS_ITERATOR_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_PAIRS_ITERATOR_HPP
#define SOL_PAIRS_ITERATOR_HPP
#include <sol/version.hpp>
#include <sol/reference.hpp>
#include <sol/stack_reference.hpp>
#include <sol/table_iterator.hpp>
#include <sol/protected_function.hpp>
#include <sol/stack/detail/pairs.hpp>
namespace sol {
struct pairs_sentinel { };
class pairs_iterator {
private:
inline static constexpr int empty_key_index = -1;
public:
using key_type = object;
using mapped_type = object;
using value_type = std::pair<object, object>;
using iterator_category = std::input_iterator_tag;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using const_pointer = value_type const*;
using reference = value_type&;
using const_reference = const value_type&;
pairs_iterator() noexcept
: m_L(nullptr)
, m_next_function_ref(lua_nil)
, m_table_ref(lua_nil)
, m_cached_key_value_pair({ lua_nil, lua_nil })
, m_key_index(empty_key_index)
, m_iteration_index(0) {
}
pairs_iterator(const pairs_iterator&) = delete;
pairs_iterator& operator=(const pairs_iterator&) = delete;
pairs_iterator(pairs_iterator&& right) noexcept
: m_L(right.m_L)
, m_next_function_ref(std::move(right.m_next_function_ref))
, m_table_ref(std::move(right.m_table_ref))
, m_cached_key_value_pair(std::move(right.m_cached_key_value_pair))
, m_key_index(right.m_key_index)
, m_iteration_index(right.m_iteration_index) {
right.m_key_index = empty_key_index;
}
pairs_iterator& operator=(pairs_iterator&& right) noexcept {
m_L = right.m_L;
m_next_function_ref = std::move(right.m_next_function_ref);
m_table_ref = std::move(right.m_table_ref);
m_cached_key_value_pair = std::move(right.m_cached_key_value_pair);
m_key_index = right.m_key_index;
m_iteration_index = right.m_iteration_index;
right.m_key_index = empty_key_index;
return *this;
}
template <typename Source>
pairs_iterator(const Source& source_) noexcept : m_L(source_.lua_state()), m_key_index(empty_key_index), m_iteration_index(0) {
if (m_L == nullptr || !source_.valid()) {
m_key_index = empty_key_index;
return;
}
int source_index = -source_.push(m_L);
int abs_source_index = lua_absindex(m_L, source_index);
int metatable_exists = lua_getmetatable(m_L, abs_source_index);
lua_remove(m_L, abs_source_index);
if (metatable_exists == 1) {
// just has a metatable, but does it have __pairs ?
stack_reference metatable(m_L, raw_index(abs_source_index));
stack::get_field<is_global_table_v<Source>, true>(m_L, meta_function::pairs, metatable.stack_index());
optional<protected_function> maybe_pairs_function = stack::pop<optional<protected_function>>(m_L);
if (maybe_pairs_function.has_value()) {
protected_function& pairs_function = *maybe_pairs_function;
protected_function_result next_fn_and_table_and_first_key = pairs_function(source_);
if (next_fn_and_table_and_first_key.valid()) {
m_next_function_ref = next_fn_and_table_and_first_key.get<protected_function>(0);
m_table_ref = next_fn_and_table_and_first_key.get<sol::reference>(1);
m_key_index = next_fn_and_table_and_first_key.stack_index() - 1;
// remove next function and table
lua_remove(m_L, m_key_index);
lua_remove(m_L, m_key_index);
next_fn_and_table_and_first_key.abandon();
lua_remove(m_L, abs_source_index);
this->operator++();
m_iteration_index = 0;
return;
}
}
}
{
auto maybe_next = stack::stack_detail::find_lua_next_function(m_L);
if (maybe_next.has_value()) {
m_next_function_ref = std::move(*maybe_next);
m_table_ref = source_;
stack::push(m_L, lua_nil);
m_key_index = lua_gettop(m_L);
this->operator++();
m_iteration_index = 0;
return;
}
}
// okay, so none of the above worked and now we need to create
// a shim / polyfill instead
stack::push(m_L, &stack::stack_detail::c_lua_next);
m_next_function_ref = stack::pop<protected_function>(m_L);
m_table_ref = source_;
stack::push(m_L, lua_nil);
m_key_index = lua_gettop(m_L);
this->operator++();
m_iteration_index = 0;
}
pairs_iterator& operator++() {
if (m_key_index == empty_key_index) {
return *this;
}
{
sol::protected_function_result next_results = m_next_function_ref(m_table_ref, stack_reference(m_L, m_key_index));
if (!next_results.valid()) {
// TODO: abort, or throw an error?
m_clear();
m_key_index = empty_key_index;
return *this;
}
int next_results_count = next_results.return_count();
if (next_results_count < 2) {
// iteration is over!
next_results.abandon();
lua_settop(m_L, m_key_index - 1);
m_key_index = empty_key_index;
++m_iteration_index;
return *this;
}
else {
lua_remove(m_L, m_key_index);
m_key_index = next_results.stack_index() - 1;
m_cached_key_value_pair.first = stack::get<object>(m_L, m_key_index);
m_cached_key_value_pair.second = stack::get<object>(m_L, m_key_index + 1);
lua_settop(m_L, m_key_index);
next_results.abandon();
}
}
++m_iteration_index;
return *this;
}
std::ptrdiff_t index() const {
return static_cast<std::ptrdiff_t>(m_iteration_index);
}
const_reference operator*() const noexcept {
return m_cached_key_value_pair;
}
reference operator*() noexcept {
return m_cached_key_value_pair;
}
friend bool operator==(const pairs_iterator& left, const pairs_iterator& right) noexcept {
return left.m_table_ref == right.m_table_ref && left.m_iteration_index == right.m_iteration_index;
}
friend bool operator!=(const pairs_iterator& left, const pairs_iterator& right) noexcept {
return left.m_table_ref != right.m_table_ref || left.m_iteration_index != right.m_iteration_index;
}
friend bool operator==(const pairs_iterator& left, const pairs_sentinel&) noexcept {
return left.m_key_index == empty_key_index;
}
friend bool operator!=(const pairs_iterator& left, const pairs_sentinel&) noexcept {
return left.m_key_index != empty_key_index;
}
friend bool operator==(const pairs_sentinel&, const pairs_iterator& left) noexcept {
return left.m_key_index == empty_key_index;
}
friend bool operator!=(const pairs_sentinel&, const pairs_iterator& left) noexcept {
return left.m_key_index != empty_key_index;
}
~pairs_iterator() {
if (m_key_index != empty_key_index) {
m_clear();
}
}
private:
void m_clear() noexcept {
lua_remove(m_L, m_key_index);
}
lua_State* m_L;
protected_function m_next_function_ref;
sol::reference m_table_ref;
std::pair<object, object> m_cached_key_value_pair;
int m_key_index;
int m_iteration_index;
};
template <typename Source>
class basic_pairs_range {
private:
using source_t = std::add_lvalue_reference_t<Source>;
source_t m_source;
public:
using iterator = pairs_iterator;
using const_iterator = pairs_iterator;
basic_pairs_range(source_t source_) noexcept : m_source(source_) {
}
iterator begin() noexcept {
return iterator(m_source);
}
iterator begin() const noexcept {
return iterator(m_source);
}
const_iterator cbegin() const noexcept {
return const_iterator(m_source);
}
pairs_sentinel end() noexcept {
return {};
}
pairs_sentinel end() const noexcept {
return {};
}
pairs_sentinel cend() const noexcept {
return {};
}
};
} // namespace sol
#endif // SOL_PAIRS_ITERATOR_HPP

View file

@ -1,102 +1,103 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_POINTER_LIKE_HPP
#define SOL_POINTER_LIKE_HPP
#include <sol/base_traits.hpp>
#include <utility>
#include <type_traits>
namespace sol {
namespace meta {
namespace meta_detail {
template <typename T>
using is_dereferenceable_test = decltype(*std::declval<T>());
template <typename T>
using is_explicitly_dereferenceable_test = decltype(std::declval<T>().operator*());
} // namespace meta_detail
template <typename T>
using is_pointer_like = std::integral_constant<bool,
!std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>;
template <typename T>
constexpr inline bool is_pointer_like_v = is_pointer_like<T>::value;
} // namespace meta
namespace detail {
template <typename T>
auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
return std::forward<T>(item);
}
template <typename T>
T& unwrap(std::reference_wrapper<T> arg) {
return arg.get();
}
template <typename T>
inline decltype(auto) deref(T&& item) {
using Tu = meta::unqualified_t<T>;
if constexpr (meta::is_pointer_like_v<Tu>) {
return *std::forward<T>(item);
}
else {
return std::forward<T>(item);
}
}
template <typename T>
inline decltype(auto) deref_move_only(T&& item) {
using Tu = meta::unqualified_t<T>;
if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) {
return *std::forward<T>(item);
}
else {
return std::forward<T>(item);
}
}
template <typename T>
inline T* ptr(T& val) {
return std::addressof(val);
}
template <typename T>
inline T* ptr(std::reference_wrapper<T> val) {
return std::addressof(val.get());
}
template <typename T>
inline T* ptr(T* val) {
return val;
}
} // namespace detail
} // namespace sol
#endif // SOL_POINTER_LIKE_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_POINTER_LIKE_HPP
#define SOL_POINTER_LIKE_HPP
#include <sol/base_traits.hpp>
#include <utility>
#include <type_traits>
#include <memory>
namespace sol {
namespace meta {
namespace meta_detail {
template <typename T>
using is_dereferenceable_test = decltype(*std::declval<T>());
template <typename T>
using is_explicitly_dereferenceable_test = decltype(std::declval<T>().operator*());
} // namespace meta_detail
template <typename T>
using is_pointer_like = std::integral_constant<bool,
!std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>;
template <typename T>
constexpr inline bool is_pointer_like_v = is_pointer_like<T>::value;
} // namespace meta
namespace detail {
template <typename T>
auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
return std::forward<T>(item);
}
template <typename T>
T& unwrap(std::reference_wrapper<T> arg) {
return arg.get();
}
template <typename T>
inline decltype(auto) deref(T&& item) {
using Tu = meta::unqualified_t<T>;
if constexpr (meta::is_pointer_like_v<Tu>) {
return *std::forward<T>(item);
}
else {
return std::forward<T>(item);
}
}
template <typename T>
inline decltype(auto) deref_move_only(T&& item) {
using Tu = meta::unqualified_t<T>;
if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) {
return *std::forward<T>(item);
}
else {
return std::forward<T>(item);
}
}
template <typename T>
inline T* ptr(T& val) {
return std::addressof(val);
}
template <typename T>
inline T* ptr(std::reference_wrapper<T> val) {
return std::addressof(val.get());
}
template <typename T>
inline T* ptr(T* val) {
return val;
}
} // namespace detail
} // namespace sol
#endif // SOL_POINTER_LIKE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -1,47 +1,47 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
// clang-format off
#if defined(SOL_PROLOGUE_I_)
#error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue."
#endif
#define SOL_PROLOGUE_I_ 1
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_)
#define _FWD(...) static_cast<decltype( __VA_ARGS__ )&&>( __VA_ARGS__ )
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ )
#else
#include <type_traits>
#define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) )
#endif
#endif
// clang-format on
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
// clang-format off
#if defined(SOL_PROLOGUE_I_)
#error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue."
#endif
#define SOL_PROLOGUE_I_ 1
#if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#define _FWD(...) static_cast<decltype( __VA_ARGS__ )&&>( __VA_ARGS__ )
#if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ )
#else
#include <type_traits>
#define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) )
#endif
#endif
// clang-format on

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -75,7 +75,7 @@ namespace sol {
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)), m_error_handler(get_default_handler(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -133,7 +133,7 @@ namespace sol {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(lua_State* L_, T&& r, handler_t eh) : base_t(L_, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler);
@ -146,7 +146,7 @@ namespace sol {
basic_protected_function(lua_State* L_, int index_ = -1) : basic_protected_function(L_, index_, get_default_handler(L_)) {
}
basic_protected_function(lua_State* L_, int index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety
@ -154,7 +154,7 @@ namespace sol {
basic_protected_function(lua_State* L_, absolute_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
}
basic_protected_function(lua_State* L_, absolute_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety
@ -162,7 +162,7 @@ namespace sol {
basic_protected_function(lua_State* L_, raw_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
}
basic_protected_function(lua_State* L_, raw_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety
@ -170,7 +170,7 @@ namespace sol {
basic_protected_function(lua_State* L_, ref_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
}
basic_protected_function(lua_State* L_, ref_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler);
@ -339,14 +339,14 @@ namespace sol {
int firstreturn = 1;
int returncount = 0;
call_status code = call_status::ok;
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
#if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
try {
#endif // No Exceptions
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler_v)));
code = luacall(n, LUA_MULTRET, h);
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler_v);
returncount = poststacksize - (firstreturn - 1);
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
#if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
}
// Handle C++ errors thrown from C++ functions bound inside of lua
catch (const char* error) {
@ -364,7 +364,7 @@ namespace sol {
firstreturn = lua_gettop(lua_state());
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
}
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL_I_)
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
// LuaJIT cannot have the catchall when the safe propagation is on
// but LuaJIT will swallow all C++ errors
// if we don't at least catch std::exception ones

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -54,9 +54,9 @@ namespace sol {
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
protected_function_result() noexcept = default;
protected_function_result() noexcept : protected_function_result(nullptr) {}
protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept
: L(Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
: L( Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
}
// We do not want anyone to copy these around willy-nilly
@ -99,6 +99,13 @@ namespace sol {
return status() == call_status::ok || status() == call_status::yielded;
}
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic push
#if !SOL_IS_ON(SOL_COMPILER_CLANG)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
template <typename T>
decltype(auto) get(int index_offset = 0) const {
using UT = meta::unqualified_t<T>;
@ -109,7 +116,7 @@ namespace sol {
if (valid()) {
return UT();
}
return UT(error(detail::direct_error, stack::get<std::string>(L, target)));
return UT(stack::stack_detail::get_error(L, target));
}
else {
if (!valid()) {
@ -120,16 +127,16 @@ namespace sol {
}
else {
if constexpr (std::is_same_v<T, error>) {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
#if SOL_IS_ON(SOL_SAFE_PROXIES)
if (valid()) {
type t = type_of(L, target);
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is an error)");
}
#endif // Check Argument Safety
return error(detail::direct_error, stack::get<std::string>(L, target));
return stack::stack_detail::get_error(L, target);
}
else {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
#if SOL_IS_ON(SOL_SAFE_PROXIES)
if (!valid()) {
type t = type_of(L, target);
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is not an error)");
@ -140,6 +147,10 @@ namespace sol {
}
}
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif
type get_type(int index_offset = 0) const noexcept {
return type_of(L, index + static_cast<int>(index_offset));
}
@ -216,7 +227,7 @@ namespace sol {
template <>
struct unqualified_pusher<protected_function_result> {
static int push(lua_State* L, const protected_function_result& pfr) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, static_cast<int>(pfr.pop_count()), detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
int p = 0;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -92,7 +92,7 @@ namespace sol { namespace detail {
return;
}
if (!ref.valid()) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
lua_pushnil(L);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -289,7 +289,7 @@ namespace sol {
}
stateless_reference(lua_State* L_, global_tag_t) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_pushglobaltable(L_);
@ -352,7 +352,7 @@ namespace sol {
}
stateless_reference(lua_State* L_, int index = -1) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_pushvalue(L_, index);
@ -383,7 +383,7 @@ namespace sol {
}
int push(lua_State* L_) const noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_rawgeti(L_, LUA_REGISTRYINDEX, ref);
@ -407,7 +407,7 @@ namespace sol {
void reset(lua_State* L_, int index_) noexcept {
reset(L_);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_pushvalue(L_, index_);
@ -616,7 +616,7 @@ namespace sol {
}
basic_reference(lua_State* L_, int index = -1) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
// use L_ to stick with that state's execution stack
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_pushvalue(L_, index);
@ -693,7 +693,7 @@ namespace sol {
}
int push(lua_State* L_) const noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
if (lua_state() == nullptr) {
@ -828,6 +828,8 @@ namespace sol {
stateless_reference_equals(lua_State* L_) noexcept : stateless_stack_reference_equals(L_) {
}
using stateless_stack_reference_equals::operator();
bool operator()(const lua_nil_t& lhs, const stateless_reference& rhs) const noexcept {
return rhs.equals(lua_state(), lhs);
}
@ -839,6 +841,14 @@ namespace sol {
bool operator()(const stateless_reference& lhs, const stateless_reference& rhs) const noexcept {
return lhs.equals(lua_state(), rhs);
}
bool operator()(const stateless_stack_reference& lhs, const stateless_reference& rhs) const noexcept {
return rhs.equals(lua_state(), lhs);
}
bool operator()(const stateless_reference& lhs, const stateless_stack_reference& rhs) const noexcept {
return lhs.equals(lua_state(), rhs);
}
};
struct reference_equals : public stack_reference_equals {
@ -878,6 +888,8 @@ namespace sol {
stateless_reference_hash(lua_State* L_) noexcept : stateless_stack_reference_hash(L_) {
}
using stateless_stack_reference_hash::operator();
result_type operator()(const stateless_reference& lhs) const noexcept {
std::hash<const void*> h;
return h(lhs.pointer(lua_state()));

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -24,23 +24,23 @@
#include <sol/version.hpp>
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_)
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
#ifdef check
#pragma push_macro("check")
#undef check
#endif
#endif // Unreal Engine 4 Bullshit
#if SOL_IS_ON(SOL_COMPILER_GCC_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wconversion"
#if __GNUC__ > 6
#pragma GCC diagnostic ignored "-Wnoexcept-type"
#endif
#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#elif SOL_IS_ON(SOL_COMPILER_CLANG)
// we'll just let this alone for now
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#elif SOL_IS_ON(SOL_COMPILER_VCXX)
#pragma warning(push)
#pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS
#endif // clang++ vs. g++ vs. VC++
@ -65,13 +65,15 @@
#include <sol/variadic_results.hpp>
#include <sol/lua_value.hpp>
#if SOL_IS_ON(SOL_COMPILER_GCC_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#elif SOL_IS_ON(SOL_COMPILER_CLANG)
// we'll just let this alone for now
#elif SOL_IS_ON(SOL_COMPILER_VCXX)
#pragma warning(pop)
#endif // g++
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_)
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
#undef check
#pragma pop_macro("check")
#endif // Unreal Engine 4 Bullshit

View file

@ -1,351 +1,384 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_STACK_HPP
#define SOL_STACK_HPP
#include <sol/trampoline.hpp>
#include <sol/stack_core.hpp>
#include <sol/stack_reference.hpp>
#include <sol/stack_check.hpp>
#include <sol/stack_get.hpp>
#include <sol/stack_check_get.hpp>
#include <sol/stack_push.hpp>
#include <sol/stack_pop.hpp>
#include <sol/stack_field.hpp>
#include <sol/stack_probe.hpp>
#include <cstring>
#include <array>
namespace sol {
namespace detail {
using typical_chunk_name_t = char[SOL_ID_SIZE_I_];
using typical_file_chunk_name_t = char[SOL_FILE_ID_SIZE_I_];
inline const std::string& default_chunk_name() {
static const std::string name = "";
return name;
}
template <std::size_t N>
const char* make_chunk_name(const string_view& code, const std::string& chunkname, char (&basechunkname)[N]) {
if (chunkname.empty()) {
auto it = code.cbegin();
auto e = code.cend();
std::size_t i = 0;
static const std::size_t n = N - 4;
for (i = 0; i < n && it != e; ++i, ++it) {
basechunkname[i] = *it;
}
if (it != e) {
for (std::size_t c = 0; c < 3; ++i, ++c) {
basechunkname[i] = '.';
}
}
basechunkname[i] = '\0';
return &basechunkname[0];
}
else {
return chunkname.c_str();
}
}
inline void clear_entries(stack_reference r) {
stack::push(r.lua_state(), lua_nil);
while (lua_next(r.lua_state(), -2)) {
absolute_index key(r.lua_state(), -2);
auto pn = stack::pop_n(r.lua_state(), 1);
stack::set_field<false, true>(r.lua_state(), key, lua_nil, r.stack_index());
}
}
inline void clear_entries(const reference& registry_reference) {
auto pp = stack::push_pop(registry_reference);
stack_reference ref(registry_reference.lua_state(), -1);
clear_entries(ref);
}
} // namespace detail
namespace stack {
namespace stack_detail {
template <typename T>
inline int push_as_upvalues(lua_State* L, T& item) {
typedef std::decay_t<T> TValue;
static const std::size_t itemsize = sizeof(TValue);
static const std::size_t voidsize = sizeof(void*);
static const std::size_t voidsizem1 = voidsize - 1;
static const std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize;
typedef std::array<void*, data_t_count> data_t;
data_t data { {} };
std::memcpy(&data[0], std::addressof(item), itemsize);
int pushcount = 0;
for (const auto& v : data) {
lua_pushlightuserdata(L, v);
pushcount += 1;
}
return pushcount;
}
template <typename T>
inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 2) {
static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
typedef std::array<void*, data_t_count> data_t;
data_t voiddata { {} };
for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
voiddata[i] = lua_touserdata(L, upvalue_index(index++));
}
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
}
template <typename T>
inline std::pair<T, int> get_as_upvalues_using_function(lua_State* L, int function_index = -1) {
static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
typedef std::array<void*, data_t_count> data_t;
function_index = lua_absindex(L, function_index);
int index = 0;
data_t voiddata { {} };
for (std::size_t d = 0; d < sizeof(T); d += sizeof(void*)) {
// first upvalue is nullptr to respect environment shenanigans
// So +2 instead of +1
const char* upvalue_name = lua_getupvalue(L, function_index, index + 2);
if (upvalue_name == nullptr) {
// We should freak out here...
break;
}
voiddata[index] = lua_touserdata(L, -1);
++index;
}
lua_pop(L, index);
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
}
template <bool checked, typename Handler, typename Fx, typename... Args>
static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, Handler&&, record&, Fx&& fx, Args&&... args) {
return std::forward<Fx>(fx)(std::forward<Args>(args)...);
}
template <bool checked, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename Handler, typename Fx, typename... FxArgs>
static decltype(auto) eval(types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L_, int start_index_, Handler&& handler_,
record& tracking_, Fx&& fx_, FxArgs&&... fxargs_) {
#if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS_I_)
// We can save performance/time by letting errors unwind produced arguments
// rather than checking everything once, and then potentially re-doing work
if constexpr (checked) {
return eval<checked>(types<Args...>(),
std::index_sequence<Is...>(),
L_,
start_index_,
std::forward<Handler>(handler_),
tracking_,
std::forward<Fx>(fx_),
std::forward<FxArgs>(fxargs_)...,
*stack_detail::check_get_arg<Arg>(L_, start_index_ + tracking_.used, handler_, tracking_));
}
else
#endif
{
return eval<checked>(types<Args...>(),
std::index_sequence<Is...>(),
L_,
start_index_,
std::forward<Handler>(handler_),
tracking_,
std::forward<Fx>(fx_),
std::forward<FxArgs>(fxargs_)...,
stack_detail::unchecked_get_arg<Arg>(L_, start_index_ + tracking_.used, tracking_));
}
}
template <bool checkargs = detail::default_safe_function_calls, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs>
inline decltype(auto) call(types<R>, types<Args...> argument_types_, std::index_sequence<I...> argument_indices_, lua_State* L_,
int start_index_, Fx&& fx_, FxArgs&&... args_) {
static_assert(meta::all_v<meta::is_not_move_only<Args>...>,
"One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take "
"a reference and std::move it manually if this was your intention.");
argument_handler<types<R, Args...>> handler {};
record tracking {};
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
if constexpr (checkargs) {
multi_check<Args...>(L_, start_index_, handler);
}
#endif
if constexpr (std::is_void_v<R>) {
eval<checkargs>(
argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
}
else {
return eval<checkargs>(
argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
}
}
} // namespace stack_detail
template <typename T>
int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
push(L, std::forward<T>(arg));
return luaL_ref(L, tableindex);
}
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
using args_indices = std::make_index_sequence<sizeof...(Args)>;
if constexpr (std::is_void_v<R>) {
stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
else {
return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
}
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
if constexpr (std::is_void_v<R>) {
call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
else {
return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
}
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
using expected_count_t = meta::count_for_pack<lua_size, Args...>;
if constexpr (std::is_void_v<R>) {
call<check_args>(tr,
ta,
L,
(std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
std::forward<Fx>(fx),
std::forward<FxArgs>(args)...);
}
else {
return call<check_args>(tr,
ta,
L,
(std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
std::forward<Fx>(fx),
std::forward<FxArgs>(args)...);
}
}
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args,
typename Fx, typename... FxArgs>
inline int call_into_lua(types<Ret0, Ret...> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
if constexpr (std::is_void_v<Ret0>) {
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
if constexpr (clean_stack) {
lua_settop(L, 0);
}
return 0;
}
else {
(void)tr;
decltype(auto) r
= call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
using R = meta::unqualified_t<decltype(r)>;
using is_stack = meta::any<is_stack_based<R>, std::is_same<R, absolute_index>, std::is_same<R, ref_index>, std::is_same<R, raw_index>>;
if constexpr (clean_stack && !is_stack::value) {
lua_settop(L, 0);
}
return push_reference(L, std::forward<decltype(r)>(r));
}
}
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... FxArgs>
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
using traits_type = lua_bind_traits<meta::unqualified_t<Fx>>;
using args_list = typename traits_type::args_list;
using returns_list = typename traits_type::returns_list;
return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
}
inline call_syntax get_call_syntax(lua_State* L, const string_view& key, int index) {
if (lua_gettop(L) < 1) {
return call_syntax::dot;
}
luaL_getmetatable(L, key.data());
auto pn = pop_n(L, 1);
if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
return call_syntax::dot;
}
return call_syntax::colon;
}
inline void script(
lua_State* L, lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
detail::typical_chunk_name_t basechunkname = {};
const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
lua_error(L);
}
}
inline void script(
lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
detail::typical_chunk_name_t basechunkname = {};
const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
lua_error(L);
}
}
inline void script_file(lua_State* L, const std::string& filename, load_mode mode = load_mode::any) {
if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
lua_error(L);
}
}
inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_)
if (L == nullptr) {
return;
}
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
lua_pushlightuserdata(L, (void*)handler);
auto pn = pop_n(L, 1);
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
#else
(void)L;
(void)handler;
#endif
}
inline void luajit_exception_off(lua_State* L) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_)
if (L == nullptr) {
return;
}
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
#else
(void)L;
#endif
}
} // namespace stack
} // namespace sol
#endif // SOL_STACK_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_STACK_HPP
#define SOL_STACK_HPP
#include <sol/trampoline.hpp>
#include <sol/stack_core.hpp>
#include <sol/stack_reference.hpp>
#include <sol/stack_check.hpp>
#include <sol/stack_get.hpp>
#include <sol/stack_check_get.hpp>
#include <sol/stack_push.hpp>
#include <sol/stack_pop.hpp>
#include <sol/stack_field.hpp>
#include <sol/stack_probe.hpp>
#include <sol/error.hpp>
#include <sol/assert.hpp>
#include <cstring>
#include <array>
namespace sol {
namespace detail {
using typical_chunk_name_t = char[SOL_ID_SIZE_I_];
using typical_file_chunk_name_t = char[SOL_FILE_ID_SIZE_I_];
inline const std::string& default_chunk_name() {
static const std::string name = "";
return name;
}
template <std::size_t N>
const char* make_chunk_name(const string_view& code, const std::string& chunkname, char (&basechunkname)[N]) {
if (chunkname.empty()) {
auto it = code.cbegin();
auto e = code.cend();
std::size_t i = 0;
static const std::size_t n = N - 4;
for (i = 0; i < n && it != e; ++i, ++it) {
basechunkname[i] = *it;
}
if (it != e) {
for (std::size_t c = 0; c < 3; ++i, ++c) {
basechunkname[i] = '.';
}
}
basechunkname[i] = '\0';
return &basechunkname[0];
}
else {
return chunkname.c_str();
}
}
inline void clear_entries(stack_reference r) {
stack::push(r.lua_state(), lua_nil);
while (lua_next(r.lua_state(), -2)) {
absolute_index key(r.lua_state(), -2);
auto pn = stack::pop_n(r.lua_state(), 1);
stack::set_field<false, true>(r.lua_state(), key, lua_nil, r.stack_index());
}
}
inline void clear_entries(const reference& registry_reference) {
auto pp = stack::push_pop(registry_reference);
stack_reference ref(registry_reference.lua_state(), -1);
clear_entries(ref);
}
} // namespace detail
namespace stack {
namespace stack_detail {
template <typename T>
inline int push_as_upvalues(lua_State* L, T& item) {
typedef std::decay_t<T> TValue;
static const std::size_t itemsize = sizeof(TValue);
static const std::size_t voidsize = sizeof(void*);
static const std::size_t voidsizem1 = voidsize - 1;
static const std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize;
typedef std::array<void*, data_t_count> data_t;
data_t data { {} };
std::memcpy(&data[0], std::addressof(item), itemsize);
int pushcount = 0;
for (const auto& v : data) {
lua_pushlightuserdata(L, v);
pushcount += 1;
}
return pushcount;
}
template <typename T>
inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 2) {
static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
typedef std::array<void*, data_t_count> data_t;
data_t voiddata { {} };
for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
voiddata[i] = lua_touserdata(L, upvalue_index(index++));
}
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
}
template <typename T>
inline std::pair<T, int> get_as_upvalues_using_function(lua_State* L, int function_index = -1) {
static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
typedef std::array<void*, data_t_count> data_t;
function_index = lua_absindex(L, function_index);
int index = 0;
data_t voiddata { {} };
for (std::size_t d = 0; d < sizeof(T); d += sizeof(void*)) {
// first upvalue is nullptr to respect environment shenanigans
// So +2 instead of +1
const char* upvalue_name = lua_getupvalue(L, function_index, index + 2);
if (upvalue_name == nullptr) {
// We should freak out here...
break;
}
voiddata[index] = lua_touserdata(L, -1);
++index;
}
lua_pop(L, index);
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
}
template <bool checked, typename Handler, typename Fx, typename... Args>
static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, Handler&&, record&, Fx&& fx, Args&&... args) {
return std::forward<Fx>(fx)(std::forward<Args>(args)...);
}
template <bool checked, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename Handler, typename Fx, typename... FxArgs>
static decltype(auto) eval(types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L_, int start_index_, Handler&& handler_,
record& tracking_, Fx&& fx_, FxArgs&&... fxargs_) {
#if 0 && SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
// NOTE: THIS IS TERMPORARILY TURNED OFF BECAUSE IT IMPACTS ACTUAL SEMANTICS W.R.T. THINGS LIKE LUAJIT,
// SO IT MUST REMAIN OFF UNTIL WE CAN ESTABLISH SIMILAR BEHAVIOR IN MODES WHERE `checked == false`!
// We can save performance/time by letting errors unwind produced arguments
// rather than checking everything once, and then potentially re-doing work
if constexpr (checked) {
return eval<checked>(types<Args...>(),
std::index_sequence<Is...>(),
L_,
start_index_,
std::forward<Handler>(handler_),
tracking_,
std::forward<Fx>(fx_),
std::forward<FxArgs>(fxargs_)...,
*stack_detail::check_get_arg<Arg>(L_, start_index_ + tracking_.used, handler_, tracking_));
}
else
#endif
{
return eval<checked>(types<Args...>(),
std::index_sequence<Is...>(),
L_,
start_index_,
std::forward<Handler>(handler_),
tracking_,
std::forward<Fx>(fx_),
std::forward<FxArgs>(fxargs_)...,
stack_detail::unchecked_get_arg<Arg>(L_, start_index_ + tracking_.used, tracking_));
}
}
template <bool checkargs = detail::default_safe_function_calls, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs>
inline decltype(auto) call(types<R>, types<Args...> argument_types_, std::index_sequence<I...> argument_indices_, lua_State* L_,
int start_index_, Fx&& fx_, FxArgs&&... args_) {
static_assert(meta::all_v<meta::is_not_move_only<Args>...>,
"One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take "
"a reference and std::move it manually if this was your intention.");
argument_handler<types<R, Args...>> handler {};
record tracking {};
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
if constexpr (checkargs) {
multi_check<Args...>(L_, start_index_, handler);
}
#endif
if constexpr (std::is_void_v<R>) {
eval<checkargs>(
argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
}
else {
return eval<checkargs>(
argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
}
}
template <typename T>
void raw_table_set(lua_State* L, T&& arg, int tableindex = -2) {
int push_count = push(L, std::forward<T>(arg));
SOL_ASSERT(push_count == 1);
std::size_t unique_index = static_cast<std::size_t>(luaL_len(L, tableindex) + 1u);
lua_rawseti(L, tableindex, static_cast<int>(unique_index));
}
} // namespace stack_detail
template <typename T>
int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
int push_count = push(L, std::forward<T>(arg));
SOL_ASSERT(push_count == 1);
return luaL_ref(L, tableindex);
}
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
using args_indices = std::make_index_sequence<sizeof...(Args)>;
if constexpr (std::is_void_v<R>) {
stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
else {
return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
}
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
if constexpr (std::is_void_v<R>) {
call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
else {
return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
}
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
using expected_count_t = meta::count_for_pack<lua_size, Args...>;
if constexpr (std::is_void_v<R>) {
call<check_args>(tr,
ta,
L,
(std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
std::forward<Fx>(fx),
std::forward<FxArgs>(args)...);
}
else {
return call<check_args>(tr,
ta,
L,
(std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
std::forward<Fx>(fx),
std::forward<FxArgs>(args)...);
}
}
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args,
typename Fx, typename... FxArgs>
inline int call_into_lua(types<Ret0, Ret...> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
if constexpr (std::is_void_v<Ret0>) {
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
if constexpr (clean_stack) {
lua_settop(L, 0);
}
return 0;
}
else {
(void)tr;
decltype(auto) r
= call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
using R = meta::unqualified_t<decltype(r)>;
using is_stack = meta::any<is_stack_based<R>, std::is_same<R, absolute_index>, std::is_same<R, ref_index>, std::is_same<R, raw_index>>;
if constexpr (clean_stack && !is_stack::value) {
lua_settop(L, 0);
}
return push_reference(L, std::forward<decltype(r)>(r));
}
}
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... FxArgs>
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
using traits_type = lua_bind_traits<meta::unqualified_t<Fx>>;
using args_list = typename traits_type::args_list;
using returns_list = typename traits_type::returns_list;
return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
}
inline call_syntax get_call_syntax(lua_State* L, const string_view& key, int index) {
if (lua_gettop(L) < 1) {
return call_syntax::dot;
}
luaL_getmetatable(L, key.data());
auto pn = pop_n(L, 1);
if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
return call_syntax::dot;
}
return call_syntax::colon;
}
inline void script(
lua_State* L, lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
detail::typical_chunk_name_t basechunkname = {};
const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
lua_error(L);
}
}
inline void script(
lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
detail::typical_chunk_name_t basechunkname = {};
const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
lua_error(L);
}
}
inline void script_file(lua_State* L, const std::string& filename, load_mode mode = load_mode::any) {
if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
lua_error(L);
}
}
inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
if (L == nullptr) {
return;
}
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
lua_pushlightuserdata(L, (void*)handler);
auto pn = pop_n(L, 1);
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
#else
(void)L;
(void)handler;
#endif
}
inline void luajit_exception_off(lua_State* L) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
if (L == nullptr) {
return;
}
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
#else
(void)L;
#endif
}
namespace stack_detail {
inline error get_error(lua_State* L, int target) {
auto maybe_exc = stack::check_get<error&>(L, target);
if (maybe_exc.has_value()) {
return maybe_exc.value();
}
return error(detail::direct_error, stack::get<std::string>(L, target));
}
inline detail::error_exception get_error_exception(lua_State* L, int target) {
auto maybe_exc = stack::check_get<detail::error_exception&>(L, target);
if (maybe_exc.has_value()) {
return maybe_exc.value();
}
return detail::error_exception(detail::direct_error, stack::get<std::string>(L, target));
}
}
} // namespace stack
} // namespace sol
#endif // SOL_STACK_HPP

View file

@ -1,98 +1,98 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this Spermission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DETAIL_PAIRS_HPP
#define SOL_DETAIL_PAIRS_HPP
#include <sol/version.hpp>
#include <sol/stack.hpp>
#include <sol/stack_reference.hpp>
#include <sol/protected_function.hpp>
#include <sol/assert.hpp>
#include <optional>
namespace sol { namespace stack { namespace stack_detail {
inline bool maybe_push_lua_next_function(lua_State* L_) {
stack::get_field<true, false>(L_, "next");
bool is_next = stack::check<protected_function>(L_);
if (is_next) {
return true;
}
stack::get_field<true, false>(L_, "table");
stack::record tracking{};
if (!stack::loose_table_check(L_, -1, &no_panic, tracking)) {
return false;
}
lua_getfield(L_, -1, "next");
bool is_table_next_func = stack::check<protected_function>(L_, -1);
if (is_table_next_func) {
return true;
}
lua_pop(L_, 1);
return false;
}
inline std::optional<protected_function> find_lua_next_function(lua_State* L_) {
if (maybe_push_lua_next_function(L_)) {
return stack::pop<protected_function>(L_);
}
return std::nullopt;
}
inline int c_lua_next(lua_State* L_) noexcept {
stack_reference table_stack_ref(L_, raw_index(1));
stateless_stack_reference key_stack_ref(L_, raw_index(2));
int result = lua_next(table_stack_ref.lua_state(), table_stack_ref.stack_index());
if (result == 0) {
stack::push(L_, lua_nil);
return 1;
}
return 2;
}
inline int readonly_pairs(lua_State* L_) noexcept {
int pushed = 0;
if (!maybe_push_lua_next_function(L_)) {
// we do not have the "next" function in the global namespace
// from the "table" global entiry, use our own
pushed += stack::push(L_, &c_lua_next);
}
else {
pushed += 1;
}
int metatable_exists = lua_getmetatable(L_, 1);
sol_c_assert(metatable_exists == 1);
const auto& index_key = to_string(sol::meta_function::index);
lua_getfield(L_, lua_gettop(L_), index_key.c_str());
lua_remove(L_, -2);
pushed += 1;
pushed += stack::push(L_, lua_nil);
return pushed;
}
}}} // sol::stack::stack_detail
#endif // SOL_DETAIL_PAIRS_HPP
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this Spermission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DETAIL_PAIRS_HPP
#define SOL_DETAIL_PAIRS_HPP
#include <sol/version.hpp>
#include <sol/stack.hpp>
#include <sol/stack_reference.hpp>
#include <sol/protected_function.hpp>
#include <sol/assert.hpp>
#include <optional>
namespace sol { namespace stack { namespace stack_detail {
inline bool maybe_push_lua_next_function(lua_State* L_) {
stack::get_field<true, false>(L_, "next");
bool is_next = stack::check<protected_function>(L_);
if (is_next) {
return true;
}
stack::get_field<true, false>(L_, "table");
stack::record tracking{};
if (!stack::loose_table_check(L_, -1, &no_panic, tracking)) {
return false;
}
lua_getfield(L_, -1, "next");
bool is_table_next_func = stack::check<protected_function>(L_, -1);
if (is_table_next_func) {
return true;
}
lua_pop(L_, 1);
return false;
}
inline std::optional<protected_function> find_lua_next_function(lua_State* L_) {
if (maybe_push_lua_next_function(L_)) {
return stack::pop<protected_function>(L_);
}
return std::nullopt;
}
inline int c_lua_next(lua_State* L_) noexcept {
stack_reference table_stack_ref(L_, raw_index(1));
stateless_stack_reference key_stack_ref(L_, raw_index(2));
int result = lua_next(table_stack_ref.lua_state(), table_stack_ref.stack_index());
if (result == 0) {
stack::push(L_, lua_nil);
return 1;
}
return 2;
}
inline int readonly_pairs(lua_State* L_) noexcept {
int pushed = 0;
if (!maybe_push_lua_next_function(L_)) {
// we do not have the "next" function in the global namespace
// from the "table" global entiry, use our own
pushed += stack::push(L_, &c_lua_next);
}
else {
pushed += 1;
}
int metatable_exists = lua_getmetatable(L_, 1);
SOL_ASSERT(metatable_exists == 1);
const auto& index_key = to_string(sol::meta_function::index);
lua_getfield(L_, lua_gettop(L_), index_key.c_str());
lua_remove(L_, -2);
pushed += 1;
pushed += stack::push(L_, lua_nil);
return pushed;
}
}}} // sol::stack::stack_detail
#endif // SOL_DETAIL_PAIRS_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -30,6 +30,13 @@
namespace sol { namespace stack {
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic push
#if !SOL_IS_ON(SOL_COMPILER_CLANG)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
namespace stack_detail {
template <typename OptionalType, typename T, typename Handler>
OptionalType get_optional(lua_State* L, int index, Handler&& handler, record& tracking) {
@ -70,9 +77,8 @@ namespace sol { namespace stack {
actual* mem = static_cast<actual*>(memory);
return static_cast<actual>(*mem);
}
actual r {};
if constexpr (!derive<element>::value) {
return {};
return OptionalType();
}
else {
memory = detail::align_usertype_unique_tag<true, false>(memory);
@ -80,6 +86,7 @@ namespace sol { namespace stack {
memory = detail::align_usertype_unique<actual, true, false>(memory);
string_view ti = usertype_traits<element>::qualified_name();
int cast_operation;
actual r {};
if constexpr (is_actual_type_rebindable_for_v<Tu>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<Tu, void>;
string_view rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
@ -103,19 +110,23 @@ namespace sol { namespace stack {
default:
break;
}
return {};
return OptionalType();
}
}
else {
if (!check<T>(L, index, std::forward<Handler>(handler))) {
tracking.use(static_cast<int>(!lua_isnone(L, index)));
return {};
return OptionalType();
}
return OptionalType(stack_detail::unchecked_get<T>(L, index, tracking));
}
}
} // namespace stack_detail
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif
template <typename T, typename>
struct qualified_check_getter {
typedef decltype(stack_detail::unchecked_get<T>(nullptr, -1, std::declval<record&>())) R;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -32,7 +32,7 @@
#include <cstdlib>
#include <cmath>
#include <optional>
#if SOL_IS_ON(SOL_STD_VARIANT_I_)
#if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant>
#endif // variant shenanigans (thanks, Mac OSX)
@ -76,7 +76,7 @@ namespace sol { namespace stack {
int isnum = 0;
const lua_Number value = lua_tonumberx(L, index, &isnum);
if (isnum != 0) {
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
const auto integer_value = llround(value);
if (static_cast<lua_Number>(integer_value) == value) {
tracking.use(1);
@ -139,7 +139,7 @@ namespace sol { namespace stack {
}
};
#if SOL_IS_ON(SOL_STD_VARIANT_I_)
#if SOL_IS_ON(SOL_STD_VARIANT)
template <typename... Tn, typename C>
struct unqualified_check_getter<std::variant<Tn...>, C> {
typedef std::variant<Tn...> V;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -28,7 +28,7 @@
namespace sol { namespace stack {
template <typename X, type expected, typename>
template <typename X, typename>
struct qualified_checker {
template <typename Handler>
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@ -32,7 +32,7 @@
#include <utility>
#include <cmath>
#include <optional>
#if SOL_IS_ON(SOL_STD_VARIANT_I_)
#if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant>
#endif // variant shenanigans
@ -116,7 +116,7 @@ namespace sol { namespace stack {
}
else if constexpr (meta::any_same_v<T,
char
#if SOL_IS_ON(SOL_CHAR8_T_I_)
#if SOL_IS_ON(SOL_CHAR8_T)
,
char8_t
#endif
@ -129,7 +129,7 @@ namespace sol { namespace stack {
tracking.use(1);
#if SOL_LUA_VERSION_I_ >= 503
// Lua 5.3 and greater checks for numeric precision
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
// imprecise, sloppy conversions
int isnum = 0;
lua_tointegerx(L_, index, &isnum);
@ -138,7 +138,7 @@ namespace sol { namespace stack {
// expected type, actual type
handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string_integral);
}
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
// this check is precise, do not convert
if (lua_isinteger(L_, index) == 1) {
return true;
@ -160,7 +160,7 @@ namespace sol { namespace stack {
return success;
#else
// Lua 5.2 and below checks
#if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS_I_)
#if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS)
// must pre-check, because it will convert
type t = type_of(L_, index);
if (t != type::number) {
@ -170,7 +170,7 @@ namespace sol { namespace stack {
}
#endif // Do not allow strings to be numbers
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
int isnum = 0;
const lua_Number v = lua_tonumberx(L_, index, &isnum);
const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
@ -179,9 +179,9 @@ namespace sol { namespace stack {
#endif // Safe numerics and number precision checking
if (!success) {
// Use defines to provide a better error message!
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string);
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
handler(L_, index, type::number, t, detail::not_a_number_or_number_string);
#else
handler(L_, index, type::number, t, detail::not_a_number);
@ -192,7 +192,7 @@ namespace sol { namespace stack {
}
else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
tracking.use(1);
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
bool success = lua_isnumber(L_, index) == 1;
if (!success) {
// expected type, actual type
@ -218,6 +218,7 @@ namespace sol { namespace stack {
}
else if constexpr (is_unique_usertype_v<T>) {
using element = unique_usertype_element_t<T>;
using element_no_cv = meta::unqualified_t<element>;
using actual = unique_usertype_actual_t<T>;
const type indextype = type_of(L_, index);
tracking.use(1);
@ -229,7 +230,7 @@ namespace sol { namespace stack {
return true;
}
int metatableindex = lua_gettop(L_);
if (stack_detail::check_metatable<d::u<element>>(L_, metatableindex)) {
if (stack_detail::check_metatable<d::u<element_no_cv>>(L_, metatableindex)) {
void* memory = lua_touserdata(L_, index);
memory = detail::align_usertype_unique_destructor(memory);
detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
@ -371,7 +372,7 @@ namespace sol { namespace stack {
}
return stack::unqualified_check<ValueType>(L_, index, &no_panic, tracking);
}
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
return stack_detail::check_function_pointer<std::remove_pointer_t<T>>(L_, index, std::forward<Handler>(handler), tracking);
}
@ -388,9 +389,7 @@ namespace sol { namespace stack {
return success;
}
else if constexpr (meta::is_specialization_of_v<T, user>) {
unqualified_checker<lightuserdata_value, type::userdata> c;
(void)c;
return c.check(L_, index, std::forward<Handler>(handler), tracking);
return stack::unqualified_check<detail::as_value_tag<lightuserdata_value>>(L_, index, std::forward<Handler>(handler), tracking);
}
else {
if constexpr (std::is_pointer_v<T>) {
@ -508,13 +507,13 @@ namespace sol { namespace stack {
return true;
}
else {
#if SOL_IS_ON(SOL_USE_INTEROP_I_)
#if SOL_IS_ON(SOL_USE_INTEROP)
if (stack_detail::interop_check<U>(L_, index, indextype, handler, tracking)) {
return true;
}
#endif // interop extensibility
tracking.use(1);
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
if (lua_iscfunction(L_, index) != 0) {
// a potential match...
return true;
@ -539,7 +538,7 @@ namespace sol { namespace stack {
bool success = false;
bool has_derived = derive<T>::value || weak_derive<T>::value;
if (has_derived) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow
auto pn = stack::pop_n(L_, 1);
@ -579,6 +578,104 @@ namespace sol { namespace stack {
}
};
template <typename T, std::size_t N, type expect>
struct unqualified_checker<exhaustive_until<T, N>, expect> {
template <typename K, typename V, typename Handler>
static bool check_two(types<K, V>, lua_State* arg_L, int relindex, type, Handler&& handler, record& tracking) {
tracking.use(1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(arg_L, 3, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
int index = lua_absindex(arg_L, relindex);
lua_pushnil(arg_L);
while (lua_next(arg_L, index) != 0) {
const bool is_key_okay = stack::check<K>(arg_L, -2, std::forward<Handler>(handler), tracking);
if (!is_key_okay) {
lua_pop(arg_L, 2);
return false;
}
const bool is_value_okay = stack::check<V>(arg_L, -1, std::forward<Handler>(handler), tracking);
if (!is_value_okay) {
lua_pop(arg_L, 2);
return false;
}
lua_pop(arg_L, 1);
}
return true;
}
template <typename V, typename Handler>
static bool check_one(types<V>, lua_State* arg_L, int relindex, type, Handler&& handler, record& tracking) {
tracking.use(1);
size_t index = lua_absindex(arg_L, relindex);
// Zzzz slower but necessary thanks to the lower version API and missing functions qq
std::size_t idx = 0;
int vi = 0;
for (lua_Integer i = 0;; (void)(i += lua_size<V>::value), lua_pop(arg_L, static_cast<int>(vi))) {
vi = 0;
if (idx >= N) {
return true;
}
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(arg_L, 2, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
bool isnil = false;
for (; vi < static_cast<int>(lua_size<V>::value); ++vi) {
lua_pushinteger(arg_L, i);
lua_gettable(arg_L, static_cast<int>(index));
type vt = type_of(arg_L, -1);
isnil = vt == type::lua_nil;
if (isnil) {
if (i == 0) {
vi += 1;
goto loop_continue;
}
lua_pop(arg_L, static_cast<int>(vi + 1));
return true;
}
}
if (!stack::check<V>(arg_L, -lua_size<V>::value, std::forward<Handler>(handler), tracking)) {
lua_pop(arg_L, lua_size<V>::value);
return false;
}
++idx;
loop_continue:;
}
}
template <typename Handler>
static bool check(lua_State* arg_L, int index, Handler&& handler, record& tracking) {
using Tu = meta::unqualified_t<T>;
if constexpr (is_container_v<Tu>) {
if constexpr (meta::is_associative<Tu>::value) {
typedef typename Tu::value_type P;
typedef typename P::first_type K;
typedef typename P::second_type V;
return check_two(types<K, V>(), arg_L, index, expect, std::forward<Handler>(handler), tracking);
}
else {
typedef typename Tu::value_type V;
return check_one(types<V>(), arg_L, index, expect, std::forward<Handler>(handler), tracking);
}
}
else {
unqualified_checker<Tu, expect> c {};
return c.check(arg_L, index, std::forward<Handler>(handler), tracking);
}
}
};
template <typename T, type expect>
struct unqualified_checker<non_exhaustive<T>, expect> {
template <typename Handler>
static bool check(lua_State* arg_L, int index, Handler&& handler, record& tracking) {
return stack::check<T>(arg_L, index, std::forward<Handler>(handler), tracking);
}
};
template <typename... Args>
struct unqualified_checker<std::tuple<Args...>, type::poly> {
template <typename Handler>
@ -595,7 +692,7 @@ namespace sol { namespace stack {
}
};
#if SOL_IS_ON(SOL_STD_VARIANT_I_)
#if SOL_IS_ON(SOL_STD_VARIANT)
template <typename... Tn>
struct unqualified_checker<std::variant<Tn...>, type::poly> {

Some files were not shown because too many files have changed in this diff Show more