1 #ifndef VTESTBED_GUILE_WRAPPER_HH 2 #define VTESTBED_GUILE_WRAPPER_HH 10 #include <vtestbed/guile/base.hh> 17 template <
class T>
class Traits;
41 wrapper_type* _wrapper;
44 using base_type::base_type;
46 inline Aspect(
const T& rhs): T(rhs) {}
47 inline Aspect(T&& rhs): T(std::move(rhs)) {}
48 inline ~Aspect() { this->_wrapper->clear(); this->_wrapper =
nullptr; }
50 inline void wrapper(wrapper_type* rhs) { this->_wrapper = rhs; }
51 inline wrapper_type* wrapper() {
return this->_wrapper; }
52 inline const wrapper_type* wrapper()
const {
return this->_wrapper; }
64 using value_type = Aspect<T>;
67 value_type* _ptr =
nullptr;
70 inline value_type* ptr() {
return this->_ptr; }
71 inline T* get() {
return this->_ptr; }
72 inline const T* get()
const {
return this->_ptr; }
73 inline void set(value_type* rhs) { this->_ptr = rhs; }
74 inline void release() {
delete this->_ptr; this->_ptr =
nullptr; }
75 inline void clear() { this->_ptr =
nullptr; }
76 inline value_type* copy() {
return new value_type(*this->_ptr); }
81 class Wrapper<std::unique_ptr<T>> {
90 inline value_type& get() {
return this->_ptr; }
91 inline const T& get()
const {
return this->_ptr; }
92 inline void set(value_type&& rhs) { this->_ptr = std::move(rhs); }
93 inline void release() { this->_ptr.reset(); }
94 inline void clear() { this->_ptr.reset(); }
99 class Wrapper<std::any> {
102 using value_type = std::any;
108 inline value_type& get() {
return this->_any; }
109 inline const value_type& get()
const {
return this->_any; }
110 inline void set(value_type&& rhs) { this->_any = std::move(rhs); }
111 inline void set(
const value_type& rhs) { this->_any = rhs; }
112 inline void release() { this->_any.reset(); }
113 inline void clear() { this->_any.reset(); }
117 template <
class T>
inline Wrapper<T>*
118 to_wrapper(SCM
object) {
119 return reinterpret_cast<Wrapper<T>*
>(scm_foreign_object_ref(
object, 0));
122 template <
class T>
inline void 123 finalize(SCM
object) {
124 to_wrapper<T>(
object)->release();
127 template <
class T>
inline SCM
128 make_type(
const char* name) {
129 return scm_make_foreign_object_type(scm_from_utf8_symbol(name),
130 scm_list_1(scm_from_utf8_symbol(
"pointer")),
134 template <
class T>
inline SCM
135 define_type(
const char* name) {
136 SCM type = make_type<T>(name);
137 scm_c_define(name, type);
141 template <
class T>
inline Wrapper<T>*
142 make_wrapper(Aspect<T>* ptr) {
143 auto* wrapper = allocate<Wrapper<T>>(
typeid(T).name());
144 ptr->wrapper(wrapper);
149 template <
class T>
inline Wrapper<std::unique_ptr<T>>*
151 auto* wrapper = allocate<Wrapper<std::unique_ptr<T>>>(
typeid(T).name());
152 wrapper->set(std::move(ptr));
156 inline Wrapper<std::any>*
157 make_wrapper(std::any&& any) {
158 auto* wrapper = allocate<Wrapper<std::any>>(any.type().name());
159 wrapper->set(std::move(any));
163 inline Wrapper<std::any>*
164 make_wrapper(
const std::any& any) {
165 auto* wrapper = allocate<Wrapper<std::any>>(any.type().name());
170 template <
class T>
inline Wrapper<T>*
172 return make_wrapper<T>(
new Aspect<T>);
175 template <
class T>
inline SCM
176 make_object(SCM type, Wrapper<T>* wrapper) {
177 return scm_make_foreign_object_1(type, wrapper);
180 template <
class T>
inline SCM
181 make_object(SCM type, Aspect<T>* ptr) {
182 return make_object<T>(type, make_wrapper<T>(ptr));
185 template <
class T>
inline SCM
187 return make_object<std::unique_ptr<T>>(type, make_wrapper<T>(std::move(ptr)));
191 make_object(SCM type, std::any&& any) {
192 return make_object<std::any>(type, make_wrapper(std::move(any)));
196 make_object(SCM type,
const std::any& any) {
197 return make_object<std::any>(type, make_wrapper(any));
200 template <
class T>
inline SCM
201 make_object(SCM type) {
202 return make_object<T>(type, make_wrapper<T>());
209 #endif // vim:filetype=cpp Aspect that extends Guile-unaware classes and provides a pointer to the corresponding wrapper object.