]> sigrok.org Git - libsigrok.git/commitdiff
C++: Centralise code for preparing shared pointers.
authorMartin Ling <redacted>
Thu, 24 Jul 2014 02:12:40 +0000 (03:12 +0100)
committerMartin Ling <redacted>
Thu, 24 Jul 2014 20:00:45 +0000 (21:00 +0100)
bindings/cxx/classes.cpp
bindings/cxx/include/libsigrok/libsigrok.hpp

index f8065fd7a6f79de667b42f1f7e849c52ea29e7d4..af3b484038d882755d835f430a306d9d88732586 100644 (file)
 namespace sigrok
 {
 
-/** Custom shared_ptr deleter for children owned by their parent object. */
-template <class T> 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<string, shared_ptr<Driver>> Context::get_drivers()
        {
                auto name = entry.first;
                auto driver = entry.second;
-               driver->parent = static_pointer_cast<Context>(shared_from_this());
-               result[name] = shared_ptr<Driver>(driver, reset_parent<Driver>);
+               result[name] = static_pointer_cast<Driver>(
+                       driver->get_shared_pointer(this));
        }
        return result;
 }
@@ -126,9 +120,8 @@ map<string, shared_ptr<InputFormat>> Context::get_input_formats()
        {
                auto name = entry.first;
                auto input_format = entry.second;
-               input_format->parent = static_pointer_cast<Context>(shared_from_this());
-               result[name] = shared_ptr<InputFormat>(input_format,
-                       reset_parent<InputFormat>);
+               result[name] = static_pointer_cast<InputFormat>(
+                       input_format->get_shared_pointer(this));
        }
        return result;
 }
@@ -140,9 +133,8 @@ map<string, shared_ptr<OutputFormat>> Context::get_output_formats()
        {
                auto name = entry.first;
                auto output_format = entry.second;
-               output_format->parent = static_pointer_cast<Context>(shared_from_this());
-               result[name] = shared_ptr<OutputFormat>(output_format,
-                       reset_parent<OutputFormat>);
+               result[name] = static_pointer_cast<OutputFormat>(
+                       output_format->get_shared_pointer(this));
        }
        return result;
 }
@@ -301,11 +293,8 @@ vector<shared_ptr<HardwareDevice>> Driver::scan(
        /* Create list of shared pointers to device instances for return. */
        vector<shared_ptr<HardwareDevice>> result;
        for (auto device : devices)
-       {
-               device->parent = parent->shared_from_this();
-               result.push_back(shared_ptr<HardwareDevice>(device,
-                       reset_parent<HardwareDevice>));
-       }
+               result.push_back(static_pointer_cast<HardwareDevice>(
+                       device->get_shared_pointer(parent)));
        return result;
 }
 
@@ -384,10 +373,8 @@ vector<shared_ptr<Channel>> Device::get_channels()
 {
        vector<shared_ptr<Channel>> result;
        for (auto channel : channels)
-       {
-               channel->parent = static_pointer_cast<Device>(shared_from_this());
-               result.push_back(shared_ptr<Channel>(channel, reset_parent<Channel>));
-       }
+               result.push_back(static_pointer_cast<Channel>(
+                       channel->get_shared_pointer(this)));
        return result;
 }
 
@@ -420,7 +407,7 @@ HardwareDevice::~HardwareDevice()
 
 shared_ptr<Driver> HardwareDevice::get_driver()
 {
-       return static_pointer_cast<Driver>(driver->shared_from_this());
+       return static_pointer_cast<Driver>(driver->get_shared_pointer(parent));
 }
 
 map<string, shared_ptr<ChannelGroup>>
@@ -431,10 +418,8 @@ HardwareDevice::get_channel_groups()
        {
                auto name = entry.first;
                auto channel_group = entry.second;
-               channel_group->parent =
-                       static_pointer_cast<HardwareDevice>(shared_from_this());
-               result[name] = shared_ptr<ChannelGroup>(channel_group,
-                       reset_parent<ChannelGroup>);
+               result[name] = static_pointer_cast<ChannelGroup>(
+                       channel_group->get_shared_pointer(this));
        }
        return result;
 }
@@ -501,10 +486,8 @@ vector<shared_ptr<Channel>> ChannelGroup::get_channels()
 {
        vector<shared_ptr<Channel>> result;
        for (auto channel : channels)
-       {
-               channel->parent = static_pointer_cast<Device>(parent->shared_from_this());
-               result.push_back(shared_ptr<Channel>(channel, reset_parent<Channel>));
-       }
+               result.push_back(static_pointer_cast<Channel>(
+                       channel->get_shared_pointer(parent)));
        return result;
 }
 
@@ -532,10 +515,8 @@ vector<shared_ptr<TriggerStage>> Trigger::get_stages()
 {
        vector<shared_ptr<TriggerStage>> result;
        for (auto stage : stages)
-       {
-               stage->parent = static_pointer_cast<Trigger>(shared_from_this());
-               result.push_back(shared_ptr<TriggerStage>(stage, reset_parent<TriggerStage>));
-       }
+               result.push_back(static_pointer_cast<TriggerStage>(
+                       stage->get_shared_pointer(this)));
        return result;
 }
 
@@ -543,8 +524,8 @@ shared_ptr<TriggerStage> Trigger::add_stage()
 {
        auto stage = new TriggerStage(sr_trigger_stage_add(structure));
        stages.push_back(stage);
-       stage->parent = static_pointer_cast<Trigger>(shared_from_this());
-       return shared_ptr<TriggerStage>(stage, reset_parent<TriggerStage>);
+       return static_pointer_cast<TriggerStage>(
+               stage->get_shared_pointer(this));
 }
 
 TriggerStage::TriggerStage(struct sr_trigger_stage *structure) : 
@@ -567,10 +548,8 @@ vector<shared_ptr<TriggerMatch>> TriggerStage::get_matches()
 {
        vector<shared_ptr<TriggerMatch>> result;
        for (auto match : matches)
-       {
-               match->parent = static_pointer_cast<TriggerStage>(shared_from_this());
-               result.push_back(shared_ptr<TriggerMatch>(match, reset_parent<TriggerMatch>));
-       }
+               result.push_back(static_pointer_cast<TriggerMatch>(
+                       match->get_shared_pointer(this)));
        return result;
 }
 
index 19323a527a0d937d45baef8559db17f94ebc8fe5..65eea9e2ac08710baf43090d3eacd3ba27c443b7 100644 (file)
@@ -126,7 +126,7 @@ public:
 template <class Parent, typename Struct> class SR_API StructureWrapper :
        public enable_shared_from_this<StructureWrapper<Parent, Struct> >
 {
-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> parent;
+
+public:
+       shared_ptr<StructureWrapper<Parent, Struct> >
+       get_shared_pointer(Parent *parent)
+       {
+               this->parent = static_pointer_cast<Parent>(parent->shared_from_this());
+               return shared_ptr<StructureWrapper<Parent, Struct> >(
+                       this, reset_parent);
+       }
+       shared_ptr<StructureWrapper<Parent, Struct> >
+       get_shared_pointer(shared_ptr<Parent> parent)
+       {
+               this->parent = parent;
+               return shared_ptr<StructureWrapper<Parent, Struct> >(
+                       this, reset_parent);
+       }
 protected:
+       static void reset_parent(StructureWrapper<Parent, Struct> *object)
+       {
+               object->parent.reset();
+       }
+
        Struct *structure;
 
        StructureWrapper<Parent, Struct>(Struct *structure) :