mirror of
https://github.com/matrix-construct/construct
synced 2024-11-26 00:32:35 +01:00
ircd::mods: Add sym_ptr/sym_ref to link symbols with a typed object.
This commit is contained in:
parent
a8fc400130
commit
6a0e5e4de5
3 changed files with 118 additions and 5 deletions
|
@ -41,6 +41,8 @@ using mapi::version_t;
|
|||
IRCD_EXCEPTION(ircd::error, error)
|
||||
IRCD_EXCEPTION(error, filesystem_error)
|
||||
IRCD_EXCEPTION(error, invalid_export)
|
||||
IRCD_EXCEPTION(error, expired_symbol)
|
||||
IRCD_EXCEPTION(error, undefined_symbol)
|
||||
|
||||
extern struct log::log log;
|
||||
|
||||
|
@ -80,6 +82,38 @@ struct module
|
|||
template<> const uint8_t *module::ptr<const uint8_t>(const std::string &name) const;
|
||||
template<> uint8_t *module::ptr<uint8_t>(const std::string &name);
|
||||
|
||||
class sym_ptr
|
||||
:std::weak_ptr<mod>
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
public:
|
||||
operator bool() const { return !expired(); }
|
||||
bool operator!() const { return expired(); }
|
||||
|
||||
template<class T> const T *get() const;
|
||||
template<class T> T *get();
|
||||
|
||||
template<class T> const T *operator->() const;
|
||||
template<class T> T *operator->();
|
||||
|
||||
template<class T> const T &operator*() const;
|
||||
template<class T> T &operator*();
|
||||
|
||||
sym_ptr(const std::string &modname, const std::string &symname);
|
||||
~sym_ptr() noexcept;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct sym_ref
|
||||
:protected sym_ptr
|
||||
{
|
||||
operator const T &() const { return sym_ptr::operator*<T>(); }
|
||||
operator T &() { return sym_ptr::operator*<T>(); }
|
||||
|
||||
using sym_ptr::sym_ptr;
|
||||
};
|
||||
|
||||
std::vector<std::string> symbols(const std::string &fullpath, const std::string §ion);
|
||||
std::vector<std::string> symbols(const std::string &fullpath);
|
||||
std::vector<std::string> sections(const std::string &fullpath);
|
||||
|
@ -114,6 +148,57 @@ using mods::module; // Bring struct module into mai
|
|||
|
||||
} // namespace ircd
|
||||
|
||||
template<class T>
|
||||
T &
|
||||
ircd::mods::sym_ptr::operator*()
|
||||
{
|
||||
if(unlikely(expired()))
|
||||
throw expired_symbol("The reference to a symbol in another module is no longer valid");
|
||||
|
||||
return *get<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
ircd::mods::sym_ptr::operator->()
|
||||
{
|
||||
return get<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
ircd::mods::sym_ptr::get()
|
||||
{
|
||||
return reinterpret_cast<T *>(ptr);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T &
|
||||
ircd::mods::sym_ptr::operator*()
|
||||
const
|
||||
{
|
||||
if(unlikely(expired()))
|
||||
throw expired_symbol("The const reference to a symbol in another module is no longer valid");
|
||||
|
||||
return *get<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T *
|
||||
ircd::mods::sym_ptr::operator->()
|
||||
const
|
||||
{
|
||||
return get<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T *
|
||||
ircd::mods::sym_ptr::get()
|
||||
const
|
||||
{
|
||||
return reinterpret_cast<const T *>(ptr);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T &
|
||||
ircd::mods::module::get(const std::string &name)
|
||||
|
|
|
@ -105,8 +105,8 @@ try
|
|||
|
||||
module listener("listen.so");
|
||||
module client_versions("client_versions.so");
|
||||
module client_login("client_login.so");
|
||||
module client_register("client_register.so");
|
||||
module client_login("client_login.so");
|
||||
|
||||
// This is the main program loop. Right now all it does is sleep until notified
|
||||
// to shutdown, but it can do other things eventually. Other subsystems may have
|
||||
|
|
36
ircd/mods.cc
36
ircd/mods.cc
|
@ -174,8 +174,8 @@ const
|
|||
template<> uint8_t *
|
||||
ircd::mods::module::ptr<uint8_t>(const std::string &name)
|
||||
{
|
||||
const auto &mod(**this);
|
||||
return &mod.handle.get<uint8_t>(name);
|
||||
auto &mod(**this);
|
||||
return mod.ptr<uint8_t>(name);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -184,7 +184,7 @@ ircd::mods::module::ptr<const uint8_t>(const std::string &name)
|
|||
const
|
||||
{
|
||||
const auto &mod(**this);
|
||||
return &mod.handle.get<const uint8_t>(name);
|
||||
return mod.ptr<const uint8_t>(name);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -195,7 +195,35 @@ const
|
|||
return false;
|
||||
|
||||
const auto &mod(**this);
|
||||
return mod.handle.has(name);
|
||||
return mod.has(name);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sym_ptr
|
||||
//
|
||||
|
||||
ircd::mods::sym_ptr::sym_ptr(const std::string &modname,
|
||||
const std::string &symname)
|
||||
:std::weak_ptr<mod>
|
||||
{
|
||||
module(modname)
|
||||
}
|
||||
,ptr{[this, &modname, &symname]
|
||||
{
|
||||
const life_guard<mods::mod> mod(*this);
|
||||
|
||||
if(unlikely(!mod->has(symname)))
|
||||
throw undefined_symbol("Could not find symbol '%s' in module '%s'", symname, mod->name());
|
||||
|
||||
return mod->ptr(symname);
|
||||
}()}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::mods::sym_ptr::~sym_ptr()
|
||||
noexcept
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue