|
|
|
@ -1,8 +1,21 @@
|
|
|
|
|
//#define _GNU_SOURCE
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
#include "../include/opaque.hh"
|
|
|
|
|
|
|
|
|
|
static void s_puts(const auto& string)
|
|
|
|
|
{
|
|
|
|
|
std::string_view str{string};
|
|
|
|
|
#ifdef DIRECT_WRITE
|
|
|
|
|
write(1, str.data(), str.size());
|
|
|
|
|
#else
|
|
|
|
|
printf("%.*s", (int)str.size(), str.data());
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void print_view(std::string_view ptr)
|
|
|
|
|
{
|
|
|
|
@ -37,15 +50,26 @@ enum class moh_hck {
|
|
|
|
|
|
|
|
|
|
/// Example using `make_opaque_handle`, like would be done for a C interface
|
|
|
|
|
template<moh_hck Create = moh_hck::Owned>
|
|
|
|
|
void use_moh()
|
|
|
|
|
static void use_moh()
|
|
|
|
|
{
|
|
|
|
|
std::string* str = new std::string(__PRETTY_FUNCTION__);
|
|
|
|
|
|
|
|
|
|
constexpr auto v_print = [](const opaque_handle& v) {
|
|
|
|
|
print(*v);
|
|
|
|
|
{
|
|
|
|
|
auto copied = v;
|
|
|
|
|
s_puts("(copied)");
|
|
|
|
|
print(*copied);
|
|
|
|
|
s_puts("(moved)");
|
|
|
|
|
print(*std::move(copied));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if constexpr(Create != moh_hck::Owned) {
|
|
|
|
|
constexpr auto _h = [](std::string* ptr, auto op) noexcept {
|
|
|
|
|
if(ptr) {
|
|
|
|
|
switch(op) {
|
|
|
|
|
case opaque_handle_operation::Clone: return new std::string(*ptr);
|
|
|
|
|
case opaque_handle_operation::Clone: return new std::string(std::as_const(*ptr));
|
|
|
|
|
case opaque_handle_operation::Delete: delete ptr; break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -54,22 +78,59 @@ void use_moh()
|
|
|
|
|
|
|
|
|
|
if constexpr(Create == moh_hck::Template) {
|
|
|
|
|
const opaque_handle v{make_opaque_handle<std::string, _h>(str)};
|
|
|
|
|
print(*v);
|
|
|
|
|
v_print(v);
|
|
|
|
|
} else /*if constexpr(Create == moh_hck::Ref)*/ {
|
|
|
|
|
const opaque_handle v{make_opaque_handle<std::string>(str, _h)};
|
|
|
|
|
print(*v);
|
|
|
|
|
v_print(v);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const opaque_handle v{make_opaque_handle<std::string>(str, [](std::string* ptr, auto op) noexcept {
|
|
|
|
|
if(ptr) {
|
|
|
|
|
switch(op) {
|
|
|
|
|
case opaque_handle_operation::Clone: return new std::string(*ptr);
|
|
|
|
|
case opaque_handle_operation::Clone: return new std::string(std::as_const(*ptr));
|
|
|
|
|
case opaque_handle_operation::Delete: delete ptr; break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return static_cast<std::string*>(nullptr);
|
|
|
|
|
})};
|
|
|
|
|
print(*v);
|
|
|
|
|
v_print(v);
|
|
|
|
|
}
|
|
|
|
|
s_puts("---\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Testing a hypothetical C interface
|
|
|
|
|
extern "C" {
|
|
|
|
|
struct c_struct_example;
|
|
|
|
|
|
|
|
|
|
c_struct_example* cs_create(const c_struct_example* __restrict__ from);
|
|
|
|
|
void cs_free(c_struct_example* p);
|
|
|
|
|
|
|
|
|
|
void cs_print(const c_struct_example* p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void use_c_struct()
|
|
|
|
|
{
|
|
|
|
|
using type = c_struct_example;
|
|
|
|
|
auto* allocp = cs_create(nullptr);
|
|
|
|
|
|
|
|
|
|
const opaque_handle v{make_opaque_handle<type>(allocp, [](auto* ptr, auto op) noexcept {
|
|
|
|
|
if(ptr) {
|
|
|
|
|
switch(op) {
|
|
|
|
|
case opaque_handle_operation::Clone: return cs_create(ptr);
|
|
|
|
|
case opaque_handle_operation::Delete: cs_free(ptr); break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return static_cast<type*>(nullptr);
|
|
|
|
|
})};
|
|
|
|
|
|
|
|
|
|
s_puts("> ");
|
|
|
|
|
cs_print(v);
|
|
|
|
|
{
|
|
|
|
|
auto copied = v;
|
|
|
|
|
s_puts("(copied)> ");
|
|
|
|
|
cs_print(copied);
|
|
|
|
|
s_puts("(moved)> ");
|
|
|
|
|
cs_print(std::move(copied));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -85,5 +146,52 @@ int main()
|
|
|
|
|
use_moh<moh_hck::Template>();
|
|
|
|
|
use_moh<moh_hck::Ref>();
|
|
|
|
|
use_moh<moh_hck::Owned>();
|
|
|
|
|
|
|
|
|
|
puts("\nUsing a C interface struct:");
|
|
|
|
|
use_c_struct();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
struct c_struct_example {
|
|
|
|
|
int i,j;
|
|
|
|
|
size_t sz;
|
|
|
|
|
char buf[256];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
c_struct_example* cs_create(const c_struct_example* __restrict__ from)
|
|
|
|
|
{
|
|
|
|
|
auto* ptr = reinterpret_cast<c_struct_example*>(aligned_alloc(alignof(c_struct_example), sizeof(c_struct_example)));
|
|
|
|
|
//memset(ptr, 0, sizeof(c_struct_example);
|
|
|
|
|
if(!from) {
|
|
|
|
|
ptr->i = 10;
|
|
|
|
|
ptr->j = 11;
|
|
|
|
|
snprintf(ptr->buf, 256, "Hello from C interface");
|
|
|
|
|
} else {
|
|
|
|
|
//memcpy(ptr, from, sizeof(c_struct_example));
|
|
|
|
|
*ptr = *from;
|
|
|
|
|
|
|
|
|
|
ptr->i +=1;
|
|
|
|
|
ptr->j -=1;
|
|
|
|
|
snprintf(ptr->buf, 256, "Hello from copied C interface (from %p)", from);
|
|
|
|
|
}
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cs_print(const c_struct_example* p)
|
|
|
|
|
{
|
|
|
|
|
#ifdef DIRECT_WRITE
|
|
|
|
|
char ibuf[512];
|
|
|
|
|
size_t n = snprintf(ibuf, 512, "%s: (%d, %d)", p->buf, p->i, p->j);
|
|
|
|
|
write(1, ibuf, n < sizeof(ibuf) ? n : 511);
|
|
|
|
|
write(1, "\n", 1);
|
|
|
|
|
#else
|
|
|
|
|
printf("%s: (%d, %d)\n", p->buf, p->i, p->j);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cs_free(c_struct_example* p)
|
|
|
|
|
{
|
|
|
|
|
free(p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|