diff --git a/include/rngxx/internal/dctor.h b/include/rngxx/internal/dctor.h new file mode 100644 index 0000000..b89a4f6 --- /dev/null +++ b/include/rngxx/internal/dctor.h @@ -0,0 +1,14 @@ +#ifndef _RNGXX_DCTOR_HACK_H +#define _RNGXX_DCTOR_HACK_H + +#include +#include +#include + +#include +// For some reason, dctors defined in any other file than crand.cpp do not work??! + +RNGXX_APPLY_CTOR(rng, sm64, u64); +RNGXX_APPLY_CTOR(rng, crand, u64); + +#endif /* _RNGXX_DCTOR_HACK_H */ diff --git a/include/rngxx/internal/init.hpp b/include/rngxx/internal/init.hpp index 83cc6d0..49384ba 100644 --- a/include/rngxx/internal/init.hpp +++ b/include/rngxx/internal/init.hpp @@ -10,9 +10,10 @@ namespace rng::init { + using ctor_func = std::function; struct DCLookupFailed final : std::exception{ inline DCLookupFailed(const std::string_view& n) : std::exception(), name(std::move(n)){} std::string name; }; - const std::function& apply_raw(std::string_view name, std::function fn) noexcept; + const ctor_func& apply_raw(std::string_view name, ctor_func fn) noexcept; template inline auto apply(std::string_view name, auto&& lam) noexcept @@ -22,10 +23,11 @@ namespace rng::init }); } - std::function& get(std::string_view name); + ctor_func& get(std::string_view name); } // To add to dynamic CTOR map -#define RNGXX_APPLY_CTOR(ns, T, TSeed) \ -const auto RNGXX_DCTOR_NAME(T) = rng::init::apply(#T, [](const TSeed* ptr) { return new ns::T(*ptr); }) +#define RNGXX_APPLY_CTOR(ns, T, TSeed) __attribute__((used))\ +const static auto& RNGXX_DCTOR_NAME(T) = rng::init::apply(#T, [](const TSeed* ptr) { return new ns::T(*ptr); }) +//const extern init::ctor_func& RNGXX_DCTOR_NAME(sm64); diff --git a/src/init.cpp b/src/init.cpp index 6e565ae..00b5ec0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -3,13 +3,13 @@ #include -using ctor_map = std::unordered_map>; +using ctor_map = std::unordered_map; static ctor_map* INIT_MAP=nullptr; namespace rng::init { - const std::function& apply_raw(std::string_view name, std::function fn) noexcept + const ctor_func& apply_raw(std::string_view name, ctor_func fn) noexcept { if(!INIT_MAP) INIT_MAP = new ctor_map(); @@ -18,7 +18,7 @@ namespace rng::init return map[name]; } - std::function& get(std::string_view name) + ctor_func& get(std::string_view name) { if(UNLIKELY(!INIT_MAP)) throw DCLookupFailed ( name ); auto& map = *INIT_MAP; diff --git a/src/rng/crand.cpp b/src/rng/crand.cpp index 8679228..098dab9 100644 --- a/src/rng/crand.cpp +++ b/src/rng/crand.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include "crand.h" @@ -71,4 +70,5 @@ namespace rng } -RNGXX_APPLY_CTOR(rng, crand, u64); +//TODO: Why does this have to be in THIS TU? +#include "../internal/dctor.h" diff --git a/src/rng/sm64.cpp b/src/rng/sm64.cpp index 5d4b493..cd133c6 100644 --- a/src/rng/sm64.cpp +++ b/src/rng/sm64.cpp @@ -1,7 +1,12 @@ -#include -#include +#include + +#include +#include +#include +#include #include -__attribute__((used)) -RNGXX_APPLY_CTOR(rng, sm64, u64); +#include +#include +#include "crand.h" diff --git a/src/test/main.c b/src/test/main.c index bffbafe..7325cc6 100644 --- a/src/test/main.c +++ b/src/test/main.c @@ -18,10 +18,17 @@ static int next(rng_t* rng, const int* min, const int* max) #define TREF(x) ( (const __typeof(x)[]){ (x) } ) -int main() +const struct { const char* const name; const enum rng_kind static_kind; } DEFAULT_ALG = { "crand", RNG_KIND_CRAND }; + +int main(int argc, char** argv) { - rng_dyn_ctor_ref rcref = rng_ctor_ref("sm64"); - rng_ctor_fn rctor = rng_ctor("crand"); + (void)argc; + const char* alg_name = argv[1] ?: DEFAULT_ALG.name; + const enum rng_kind* alg_dev = ((int)DEFAULT_ALG.static_kind) == -1 ? NULL : &DEFAULT_ALG.static_kind; + + printf("constructing for %s...\n", alg_name); + rng_dyn_ctor_ref rcref = rng_ctor_ref(alg_name); + rng_ctor_fn rctor = rng_ctor(alg_name); rng_t* engine = NULL; if(rctor) { @@ -33,11 +40,11 @@ int main() } if(!engine) { printf("fallback to `rng_new_named()`\n"); - engine = rng_new_named("crand", TREF((u64)time(NULL))); //rng_new(rng_kind_crand, (const u64[]){ time(null) }); + engine = rng_new_named(alg_name, TREF((u64)time(NULL))); //rng_new(rng_kind_crand, (const u64[]){ time(null) }); } - if(!engine) { - printf("fallback to static init\n"); - engine = rng_new(RNG_KIND_CRAND, (const u64[]){ time(NULL) }); + if(!engine && alg_dev) { + printf("fallback to static init of default arg (%d)\n", *alg_dev); + engine = rng_new(*alg_dev, (const u64[]){ time(NULL) }); } if(!engine) { fprintf(stderr, "failed to create engine\n");