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