This is opt-in for any children of `Random`, the macro `RNGXX_APPLY_CTOR(namespace, class_name, seed_type)` in `internal/init.hpp` enables this lookup. Non-internal implementors of Random can use this API also. This provides a dynamic way to load user-defined subclasses of Random at runtime. A symbol-based lookup may be added in the future. Version bumped. Fortune for rngxx's current commit: Future curse − 末凶iter
parent
ebc16f5638
commit
4b988ba83b
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "common.h"
|
||||
#include <rngxx.hpp>
|
||||
|
||||
namespace rng::init
|
||||
{
|
||||
struct DCLookupFailed final : std::exception{ inline DCLookupFailed(const std::string_view& n) : std::exception(), name(std::move(n)){} std::string name; };
|
||||
|
||||
const std::function<Random* (const void*)>& apply_raw(std::string_view name, std::function<Random* (const void*)> fn) noexcept;
|
||||
|
||||
template<typename T, typename _Ptr = void>
|
||||
inline auto apply(std::string_view name, auto&& lam)
|
||||
{
|
||||
return apply_raw(name, [lam](const void* seed) -> Random* {
|
||||
return static_cast<Random*>(lam(reinterpret_cast<const _Ptr*>(seed)));
|
||||
});
|
||||
}
|
||||
|
||||
std::function<Random* (const void*)>& get(std::string_view name);
|
||||
}
|
||||
|
||||
#define RNGXX_DCTOR_NAME(T) _rng__init_for_ ## T
|
||||
// To add to dynamic CTOR map
|
||||
#define RNGXX_APPLY_CTOR(ns, T, TSeed) \
|
||||
const static auto RNGXX_DCTOR_NAME(T) = rng::init::apply<ns::T, TSeed>(#T, [](const TSeed* ptr) { return new ns::T(*ptr); })
|
||||
|
@ -0,0 +1,41 @@
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
#include <init.hpp>
|
||||
|
||||
using ctor_map = std::unordered_map<std::string_view, std::function<Random* (const void*)>>;
|
||||
|
||||
static ctor_map* INIT_MAP=nullptr;
|
||||
|
||||
namespace rng::init
|
||||
{
|
||||
const std::function<Random* (const void*)>& apply_raw(std::string_view name, std::function<Random* (const void*)> fn) noexcept
|
||||
{
|
||||
if(!INIT_MAP) INIT_MAP = new ctor_map();
|
||||
|
||||
auto& map = *INIT_MAP;
|
||||
map[name] = std::move(fn);
|
||||
return map[name];
|
||||
}
|
||||
|
||||
std::function<Random* (const void*)>& get(std::string_view name)
|
||||
{
|
||||
if(UNLIKELY(!INIT_MAP)) throw DCLookupFailed ( name );
|
||||
auto& map = *INIT_MAP;
|
||||
if(map.contains(name)) return map[name];
|
||||
else throw DCLookupFailed ( name );
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
__attribute__((destructor))
|
||||
static void _rng_ctor__fini() {
|
||||
if(LIKELY(INIT_MAP)) {
|
||||
delete INIT_MAP;
|
||||
INIT_MAP = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in new issue