From: Martin Ling Date: Thu, 24 Jul 2014 02:12:40 +0000 (+0100) Subject: C++: Centralise code for preparing shared pointers. X-Git-Tag: libsigrok-0.4.0~1206 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=7649683c2a5ee9fd859227fcd4cb875b9f47a2b1;p=libsigrok.git C++: Centralise code for preparing shared pointers. --- diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index f8065fd7..af3b4840 100644 --- a/bindings/cxx/classes.cpp +++ b/bindings/cxx/classes.cpp @@ -22,12 +22,6 @@ namespace sigrok { -/** Custom shared_ptr deleter for children owned by their parent object. */ -template void reset_parent(T *child) -{ - child->parent.reset(); -} - /** Helper function to translate C errors to C++ exceptions. */ static void check(int result) { @@ -113,8 +107,8 @@ map> Context::get_drivers() { auto name = entry.first; auto driver = entry.second; - driver->parent = static_pointer_cast(shared_from_this()); - result[name] = shared_ptr(driver, reset_parent); + result[name] = static_pointer_cast( + driver->get_shared_pointer(this)); } return result; } @@ -126,9 +120,8 @@ map> Context::get_input_formats() { auto name = entry.first; auto input_format = entry.second; - input_format->parent = static_pointer_cast(shared_from_this()); - result[name] = shared_ptr(input_format, - reset_parent); + result[name] = static_pointer_cast( + input_format->get_shared_pointer(this)); } return result; } @@ -140,9 +133,8 @@ map> Context::get_output_formats() { auto name = entry.first; auto output_format = entry.second; - output_format->parent = static_pointer_cast(shared_from_this()); - result[name] = shared_ptr(output_format, - reset_parent); + result[name] = static_pointer_cast( + output_format->get_shared_pointer(this)); } return result; } @@ -301,11 +293,8 @@ vector> Driver::scan( /* Create list of shared pointers to device instances for return. */ vector> result; for (auto device : devices) - { - device->parent = parent->shared_from_this(); - result.push_back(shared_ptr(device, - reset_parent)); - } + result.push_back(static_pointer_cast( + device->get_shared_pointer(parent))); return result; } @@ -384,10 +373,8 @@ vector> Device::get_channels() { vector> result; for (auto channel : channels) - { - channel->parent = static_pointer_cast(shared_from_this()); - result.push_back(shared_ptr(channel, reset_parent)); - } + result.push_back(static_pointer_cast( + channel->get_shared_pointer(this))); return result; } @@ -420,7 +407,7 @@ HardwareDevice::~HardwareDevice() shared_ptr HardwareDevice::get_driver() { - return static_pointer_cast(driver->shared_from_this()); + return static_pointer_cast(driver->get_shared_pointer(parent)); } map> @@ -431,10 +418,8 @@ HardwareDevice::get_channel_groups() { auto name = entry.first; auto channel_group = entry.second; - channel_group->parent = - static_pointer_cast(shared_from_this()); - result[name] = shared_ptr(channel_group, - reset_parent); + result[name] = static_pointer_cast( + channel_group->get_shared_pointer(this)); } return result; } @@ -501,10 +486,8 @@ vector> ChannelGroup::get_channels() { vector> result; for (auto channel : channels) - { - channel->parent = static_pointer_cast(parent->shared_from_this()); - result.push_back(shared_ptr(channel, reset_parent)); - } + result.push_back(static_pointer_cast( + channel->get_shared_pointer(parent))); return result; } @@ -532,10 +515,8 @@ vector> Trigger::get_stages() { vector> result; for (auto stage : stages) - { - stage->parent = static_pointer_cast(shared_from_this()); - result.push_back(shared_ptr(stage, reset_parent)); - } + result.push_back(static_pointer_cast( + stage->get_shared_pointer(this))); return result; } @@ -543,8 +524,8 @@ shared_ptr Trigger::add_stage() { auto stage = new TriggerStage(sr_trigger_stage_add(structure)); stages.push_back(stage); - stage->parent = static_pointer_cast(shared_from_this()); - return shared_ptr(stage, reset_parent); + return static_pointer_cast( + stage->get_shared_pointer(this)); } TriggerStage::TriggerStage(struct sr_trigger_stage *structure) : @@ -567,10 +548,8 @@ vector> TriggerStage::get_matches() { vector> result; for (auto match : matches) - { - match->parent = static_pointer_cast(shared_from_this()); - result.push_back(shared_ptr(match, reset_parent)); - } + result.push_back(static_pointer_cast( + match->get_shared_pointer(this))); return result; } diff --git a/bindings/cxx/include/libsigrok/libsigrok.hpp b/bindings/cxx/include/libsigrok/libsigrok.hpp index 19323a52..65eea9e2 100644 --- a/bindings/cxx/include/libsigrok/libsigrok.hpp +++ b/bindings/cxx/include/libsigrok/libsigrok.hpp @@ -126,7 +126,7 @@ public: template class SR_API StructureWrapper : public enable_shared_from_this > { -public: +protected: /* Parent object which owns this child object's underlying structure. This shared pointer will be null when this child is unused, but @@ -141,7 +141,28 @@ public: the parent are called at the correct time, i.e. only when all references to both the parent and all its children are gone. */ shared_ptr parent; + +public: + shared_ptr > + get_shared_pointer(Parent *parent) + { + this->parent = static_pointer_cast(parent->shared_from_this()); + return shared_ptr >( + this, reset_parent); + } + shared_ptr > + get_shared_pointer(shared_ptr parent) + { + this->parent = parent; + return shared_ptr >( + this, reset_parent); + } protected: + static void reset_parent(StructureWrapper *object) + { + object->parent.reset(); + } + Struct *structure; StructureWrapper(Struct *structure) :