git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: explicit handling of raw (unmanaged) pointers via the FFI
1ff046bAndy Arvanitis
pcc/include/purescript.hh+27−8
@@ -66,14 +66,15 @@ class any {
66 StringLiteral = 0x05,
66 StringLiteral = 0x05,
67 Function = 0x06,
67 Function = 0x06,
68 EffFunction = 0x07,
68 EffFunction = 0x07,
69+ RawPointer = 0x08,
69− Shared = 0x08,
70+ Shared = 0x10,
70− String = 0x08,
71+ String = 0x10,
71− Map = 0x09,
72+ Map = 0x11,
72− Data = 0x0A,
73+ Data = 0x12,
73− Array = 0x0B,
74+ Array = 0x13,
74− Closure = 0x0C,
75+ Closure = 0x14,
75− EffClosure = 0x0D,
76+ EffClosure = 0x15,
76− Pointer = 0x0E
77+ Pointer = 0x16
77 };
78 };
78
79
79 private:
80 private:
@@ -144,6 +145,7 @@ class any {
144 mutable cstring r;
145 mutable cstring r;
145 mutable fn f;
146 mutable fn f;
146 mutable eff_fn e;
147 mutable eff_fn e;
148+ mutable void * u;
147 mutable shared<std::string> s;
149 mutable shared<std::string> s;
148 mutable shared<map> m;
150 mutable shared<map> m;
149 mutable shared<data> v;
151 mutable shared<data> v;
@@ -215,6 +217,11 @@ class any {
215 any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
217 any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
216 : type(Type::Pointer), p(std::move(val)) {}
218 : type(Type::Pointer), p(std::move(val)) {}
217
219
220+ // Explicit void* to raw pointer value
221+ template <typename T>
222+ any(const T& val, typename std::enable_if<std::is_same<T,void*>::value>::type* = 0) noexcept
223+ : type(Type::RawPointer), u(val) {}
224+
218 any(std::nullptr_t) noexcept : type(Type::Pointer), p(nullptr) {}
225 any(std::nullptr_t) noexcept : type(Type::Pointer), p(nullptr) {}
219
226
220
227
@@ -294,6 +301,12 @@ class any {
294
301
295 auto extractPointer() const -> void*;
302 auto extractPointer() const -> void*;
296
303
304+ auto rawPointer() const -> void* {
305+ const any& variant = unthunkVariant(*this);
306+ assert(type == Type::RawPointer);
307+ return variant.u;
308+ }
309+
297 static auto unthunkVariant(const any&) -> const any&;
310 static auto unthunkVariant(const any&) -> const any&;
298
311
299 #define DEFINE_OPERATOR(op, ty, rty) \
312 #define DEFINE_OPERATOR(op, ty, rty) \
@@ -390,6 +403,12 @@ inline auto cast(const any& a) ->
390 return *static_cast<T*>(a.extractPointer());
403 return *static_cast<T*>(a.extractPointer());
391}
404}
392
405
406+template <typename T>
407+inline auto cast(const any& a) ->
408+ typename std::enable_if<std::is_same<void*, T>::value, T>::type {
409+ return a.rawPointer();
410+}
411+
393} // namespace PureScript
412} // namespace PureScript
394
413
395#undef WITH_ALLOCATOR
414#undef WITH_ALLOCATOR