From 6401efb14339925e696a65eea8e8548f1fddf3ba Mon Sep 17 00:00:00 2001 From: Jose Bollo Date: Fri, 12 Apr 2019 11:18:46 +0200 Subject: binding-wrap: Rework of context handling The C++ wrapper for handling contexts has to be improved. This is a proposition of improvement. Change-Id: I7df36383f427d109356bdf4df573cba4b6e6ec05 Signed-off-by: Jose Bollo --- include/afb/c++/binding-wrap.hpp | 60 ++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 12 deletions(-) (limited to 'include/afb/c++') diff --git a/include/afb/c++/binding-wrap.hpp b/include/afb/c++/binding-wrap.hpp index a23e5537..6af3f845 100644 --- a/include/afb/c++/binding-wrap.hpp +++ b/include/afb/c++/binding-wrap.hpp @@ -258,8 +258,6 @@ public: void failf(const char *error, const char *info, ...) const; void failv(const char *error, const char *info, va_list args) const; - template < class T > T *context() const; - void addref() const; void unref() const; @@ -294,6 +292,54 @@ public: int get_uid() const; json_object *get_client_info() const; + + template < class T = void > + class contextclass { + + friend class req; + afb_req_t req_; + contextclass(afb_req_t r) : req_(r) {} + + public: + inline operator T *() const { return get(); } + inline operator T &() const { return *get(); } + inline T* get() const { + return reinterpret_cast( + afb_req_context(req_, 0, + nullptr, + nullptr, + nullptr)); + } + + inline void set(T *value, void (*destroyer)(T*) = [](T*t){delete t;}) const { + afb_req_context(req_, 1, + nullptr, + reinterpret_cast(destroyer), + reinterpret_cast(value)); + } + + inline void unset() { set(nullptr); } + inline void clear() { set(nullptr); } + + inline T *lazy(T *(*allocator)() = []()->T*{return new T();}, void (*destroyer)(T*) = [](T*t){delete t;}) const { + return reinterpret_cast( + afb_req_context(req_, 0, + [allocator](void*)->T*{return allocator();}, + reinterpret_cast(destroyer), + nullptr)); + } + + template + inline T *lazy(I *i, T *(*allocator)(I*) = [](I*i)->T*{return new T(i);}, void (*destroyer)(T*) = [](T*t){delete t;}) const { + return reinterpret_cast( + afb_req_context(req_, 0, + [allocator](void*i)->T*{return allocator(reinterpret_cast(i));}, + reinterpret_cast(destroyer), + reinterpret_cast(i))); + } + }; + + template < class T > contextclass context() const { return contextclass(req_); } }; /*************************************************************************/ @@ -476,16 +522,6 @@ inline void req::failf(const char *error, const char *info, ...) const va_end(args); } -template < class T > -inline T *req::context() const -{ - T* (*creater)(void*) = [](){return new T();}; - void (*freer)(T*) = [](T*t){delete t;}; - return reinterpret_cast(afb_req_context(req_, 0, - reinterpret_cast(creater), - reinterpret_cast(freer), nullptr)); -} - inline void req::addref() const { afb_req_addref(req_); } inline void req::unref() const { afb_req_unref(req_); } -- cgit 1.2.3-korg