C - C++ interop working

lean
Avril 4 years ago
parent 315295bbf1
commit 29c74f50f8
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -17,7 +17,7 @@ void _do_panic(struct panicinfo pi, const char* fmt, ...) __attribute__((noretur
extern "C++" { extern "C++" {
#include <utility> #include <utility>
template<typename... Args> template<typename... Args>
__attribute__((noreturn)) inline void _real_panic(const char* file, const char* function, int line, const char* fmt, const Args&... args) __attribute__((noreturn)) inline void _real_panic(const char* file, const char* function, int line, const char* fmt, Args&&... args)
{ {
panicinfo i = { file, function, line }; panicinfo i = { file, function, line };
_do_panic(i, fmt, std::forward<Args>(args)...); _do_panic(i, fmt, std::forward<Args>(args)...);

@ -1,16 +1,44 @@
#ifndef _RNG_H #ifndef _RNG_H
#define _RNG_H #define _RNG_H
#include "shuffle3.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
// Tests enum rng_kind {
void frng_test(); RNG_KIND_FRNG,
void xorng_test(); RNG_KIND_DRNG,
void drng_test(); RNG_KIND_XORNG,
};
typedef struct rng_init
{
enum rng_kind kind;
union {
struct {
double state[2];
} frng;
struct {
int32_t state;
} drng;
struct {
uint64_t state[2];
} xorng;
} init;
} rng_init_opt;
void rng_test(); typedef struct rng_impl* _UNIQUE rng_t;
rng_t rng_new(rng_init_opt kind);
#define RNG_INIT(_kind,...) ((rng_init_opt){.kind=(_kind), .init.__VA_ARGS__ })
void rng_free(rng_t ptr);
// Tests
extern void rng_test();
extern void rng_test_spec(rng_t rng);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -28,6 +28,8 @@ struct RNG {
inline virtual float next_float() { return (float)sample(); } inline virtual float next_float() { return (float)sample(); }
inline virtual double next_double() { return sample(); } inline virtual double next_double() { return sample(); }
virtual ~RNG() = default;
protected: protected:
virtual double sample() = 0; virtual double sample() = 0;
}; };

@ -44,9 +44,10 @@ int main(int argc, char** argv)
struct prog_args args = {.argc = argc, .argv = argv}; struct prog_args args = {.argc = argc, .argv = argv};
rng_test(); rng_test();
//frng_test();
//xorng_test(); rng_t r = rng_new(RNG_INIT(RNG_KIND_FRNG, frng = { { 1.0, 2.0 } }));
//drng_test(); rng_test_spec(r);
rng_free(r);
if( argv[1] ) { if( argv[1] ) {
map_and_then(argv[1], &map_callback, &args); map_and_then(argv[1], &map_callback, &args);
@ -56,7 +57,7 @@ int main(int argc, char** argv)
} }
#ifdef _TEST #ifdef _TEST
static void do_test() static void do_reinterpret_test()
{ {
char* string = "Hello world.. how are you?????"; char* string = "Hello world.. how are you?????";
size_t string_sz = strlen(string); size_t string_sz = strlen(string);

@ -1,6 +1,7 @@
#include <iostream>
#include <cmath>
#include <rng/impl.hpp> #include <rng/impl.hpp>
#include <cmath>
inline unsigned char RNG::byte() inline unsigned char RNG::byte()
{ {
@ -45,3 +46,47 @@ std::int64_t RNG::next_long()
{ {
return (chance() ? 1l : -1l) * (std::int64_t)floor(sample() * (double)INT64_MAX); return (chance() ? 1l : -1l) * (std::int64_t)floor(sample() * (double)INT64_MAX);
} }
#include <rng.h>
#include <panic.h>
namespace { // C interface
using namespace std;
#define extract_ptr(ptr) ((RNG*)(ptr))
static inline RNG& extract_ref(rng_t rng)
{
return *extract_ptr(rng);
}
template<typename T>
static inline T* extract_downcast_ptr(rng_t rng)
{
return dynamic_cast<T*>(extract_ptr(rng));
}
extern "C"
{
rng_t rng_new(rng_init_opt opt)
{
switch(opt.kind)
{
case RNG_KIND_FRNG: return (rng_t) new rng::frng(opt.init.frng.state);
case RNG_KIND_DRNG: return (rng_t) new rng::drng(opt.init.drng.state);
case RNG_KIND_XORNG: return (rng_t) new rng::xoroshiro128plus(opt.init.xorng.state);
default: panic("Unknown RNG init opt: %d", opt.kind);
}
return nullptr;
}
void rng_free(rng_t rng)
{
RNG* ptr = (RNG*)rng;
delete ptr;
}
void rng_test_spec(rng_t rng)
{
cout << "rng_test_spec:" << endl;
rng::test_algo(std::move(extract_ref(rng)));
}
}
}

@ -6,26 +6,6 @@
namespace rng namespace rng
{ {
static inline void d_test()
{
using namespace std;
drng rng(100);
for(int i=0;i<10;i++) {
double d = rng.next_double();
long l = rng.next_long(-10, 10);
std::array<bool, 10> ar;
for(auto& i : ar) i = rng.chance();
cout << "D Sampled: " << d << endl;
cout << "D Long: " << l << endl;
cout << "D Bools: [ ";
for(const auto& i : ar) cout << i << " ";
cout << "]" << endl;
}
}
drng drng::from_time() { return drng(time(NULL)); } drng drng::from_time() { return drng(time(NULL)); }
int drng::rand() int drng::rand()
@ -39,8 +19,3 @@ namespace rng
return (double)val / (double)RAND_MAX; return (double)val / (double)RAND_MAX;
} }
} }
extern "C" void drng_test()
{
return rng::d_test();
}

@ -1,31 +1,3 @@
#include <rng/impl.hpp> #include <rng/impl.hpp>
#include <rng/frng.hpp> #include <rng/frng.hpp>
#include <iostream> #include <iostream>
namespace rng {
using namespace std;
static inline void f_test()
{
frng rng(1.0, 2.0);
for(int i=0;i<10;i++) {
double d = rng.next_double();
long l = rng.next_long(-10, 10);
std::array<bool, 10> ar;
for(auto& i : ar) i = rng.chance();
cout << "Sampled: " << d << endl;
cout << "Long: " << l << endl;
cout << "Bools: [ ";
for(const auto& i : ar) cout << i << " ";
cout << "]" << endl;
}
}
}
extern "C" void frng_test()
{
rng::f_test();
}

@ -32,6 +32,6 @@ extern "C" void rng_test()
cout << "drng:" << endl; cout << "drng:" << endl;
rng::test_algo(rng::drng(10)); rng::test_algo(rng::drng(10));
cout << "xoroshiro128+" << endl; cout << "xoroshiro128+:" << endl;
rng::test_algo(rng::xoroshiro128plus(100ul, 200ul)); rng::test_algo(rng::xoroshiro128plus(100ul, 200ul));
} }

@ -12,26 +12,6 @@ static inline constexpr u64 rotl(u64 x, int k)
namespace rng namespace rng
{ {
static inline void xo_test()
{
using namespace std;
XO rng(100ul, 123123123ul);
for(int i=0;i<10;i++) {
double d = rng.next_double();
long l = rng.next_long(-10, 10);
std::array<bool, 10> ar;
for(auto& i : ar) i = rng.chance();
cout << "XO Sampled: " << d << endl;
cout << "XO Long: " << l << endl;
cout << "XO Bools: [ ";
for(const auto& i : ar) cout << i << " ";
cout << "]" << endl;
}
}
inline constexpr u64 next(XO::State& s) inline constexpr u64 next(XO::State& s)
{ {
u64 s0 = s[0]; u64 s0 = s[0];
@ -104,8 +84,3 @@ namespace rng
return (next(state) & ((INT64_C(1) << 53) - 1)) * (1.00 / (INT64_C(1) << 53)); return (next(state) & ((INT64_C(1) << 53) - 1)) * (1.00 / (INT64_C(1) << 53));
} }
} }
extern "C" void xorng_test()
{
return rng::xo_test();
}

Loading…
Cancel
Save