C++: Centralise code for preparing shared pointers.

This commit is contained in:
Martin Ling 2014-07-24 03:12:40 +01:00
parent ed0b7fed10
commit 7649683c2a
2 changed files with 43 additions and 43 deletions

View File

@ -22,12 +22,6 @@
namespace sigrok 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. */ /** Helper function to translate C errors to C++ exceptions. */
static void check(int result) static void check(int result)
{ {
@ -113,8 +107,8 @@ map<string, shared_ptr<Driver>> Context::get_drivers()
{ {
auto name = entry.first; auto name = entry.first;
auto driver = entry.second; auto driver = entry.second;
driver->parent = static_pointer_cast<Context>(shared_from_this()); result[name] = static_pointer_cast<Driver>(
result[name] = shared_ptr<Driver>(driver, reset_parent<Driver>); driver->get_shared_pointer(this));
} }
return result; return result;
} }
@ -126,9 +120,8 @@ map<string, shared_ptr<InputFormat>> Context::get_input_formats()
{ {
auto name = entry.first; auto name = entry.first;
auto input_format = entry.second; auto input_format = entry.second;
input_format->parent = static_pointer_cast<Context>(shared_from_this()); result[name] = static_pointer_cast<InputFormat>(
result[name] = shared_ptr<InputFormat>(input_format, input_format->get_shared_pointer(this));
reset_parent<InputFormat>);
} }
return result; return result;
} }
@ -140,9 +133,8 @@ map<string, shared_ptr<OutputFormat>> Context::get_output_formats()
{ {
auto name = entry.first; auto name = entry.first;
auto output_format = entry.second; auto output_format = entry.second;
output_format->parent = static_pointer_cast<Context>(shared_from_this()); result[name] = static_pointer_cast<OutputFormat>(
result[name] = shared_ptr<OutputFormat>(output_format, output_format->get_shared_pointer(this));
reset_parent<OutputFormat>);
} }
return result; return result;
} }
@ -301,11 +293,8 @@ vector<shared_ptr<HardwareDevice>> Driver::scan(
/* Create list of shared pointers to device instances for return. */ /* Create list of shared pointers to device instances for return. */
vector<shared_ptr<HardwareDevice>> result; vector<shared_ptr<HardwareDevice>> result;
for (auto device : devices) for (auto device : devices)
{ result.push_back(static_pointer_cast<HardwareDevice>(
device->parent = parent->shared_from_this(); device->get_shared_pointer(parent)));
result.push_back(shared_ptr<HardwareDevice>(device,
reset_parent<HardwareDevice>));
}
return result; return result;
} }
@ -384,10 +373,8 @@ vector<shared_ptr<Channel>> Device::get_channels()
{ {
vector<shared_ptr<Channel>> result; vector<shared_ptr<Channel>> result;
for (auto channel : channels) for (auto channel : channels)
{ result.push_back(static_pointer_cast<Channel>(
channel->parent = static_pointer_cast<Device>(shared_from_this()); channel->get_shared_pointer(this)));
result.push_back(shared_ptr<Channel>(channel, reset_parent<Channel>));
}
return result; return result;
} }
@ -420,7 +407,7 @@ HardwareDevice::~HardwareDevice()
shared_ptr<Driver> HardwareDevice::get_driver() 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>> map<string, shared_ptr<ChannelGroup>>
@ -431,10 +418,8 @@ HardwareDevice::get_channel_groups()
{ {
auto name = entry.first; auto name = entry.first;
auto channel_group = entry.second; auto channel_group = entry.second;
channel_group->parent = result[name] = static_pointer_cast<ChannelGroup>(
static_pointer_cast<HardwareDevice>(shared_from_this()); channel_group->get_shared_pointer(this));
result[name] = shared_ptr<ChannelGroup>(channel_group,
reset_parent<ChannelGroup>);
} }
return result; return result;
} }
@ -501,10 +486,8 @@ vector<shared_ptr<Channel>> ChannelGroup::get_channels()
{ {
vector<shared_ptr<Channel>> result; vector<shared_ptr<Channel>> result;
for (auto channel : channels) for (auto channel : channels)
{ result.push_back(static_pointer_cast<Channel>(
channel->parent = static_pointer_cast<Device>(parent->shared_from_this()); channel->get_shared_pointer(parent)));
result.push_back(shared_ptr<Channel>(channel, reset_parent<Channel>));
}
return result; return result;
} }
@ -532,10 +515,8 @@ vector<shared_ptr<TriggerStage>> Trigger::get_stages()
{ {
vector<shared_ptr<TriggerStage>> result; vector<shared_ptr<TriggerStage>> result;
for (auto stage : stages) for (auto stage : stages)
{ result.push_back(static_pointer_cast<TriggerStage>(
stage->parent = static_pointer_cast<Trigger>(shared_from_this()); stage->get_shared_pointer(this)));
result.push_back(shared_ptr<TriggerStage>(stage, reset_parent<TriggerStage>));
}
return result; return result;
} }
@ -543,8 +524,8 @@ shared_ptr<TriggerStage> Trigger::add_stage()
{ {
auto stage = new TriggerStage(sr_trigger_stage_add(structure)); auto stage = new TriggerStage(sr_trigger_stage_add(structure));
stages.push_back(stage); stages.push_back(stage);
stage->parent = static_pointer_cast<Trigger>(shared_from_this()); return static_pointer_cast<TriggerStage>(
return shared_ptr<TriggerStage>(stage, reset_parent<TriggerStage>); stage->get_shared_pointer(this));
} }
TriggerStage::TriggerStage(struct sr_trigger_stage *structure) : TriggerStage::TriggerStage(struct sr_trigger_stage *structure) :
@ -567,10 +548,8 @@ vector<shared_ptr<TriggerMatch>> TriggerStage::get_matches()
{ {
vector<shared_ptr<TriggerMatch>> result; vector<shared_ptr<TriggerMatch>> result;
for (auto match : matches) for (auto match : matches)
{ result.push_back(static_pointer_cast<TriggerMatch>(
match->parent = static_pointer_cast<TriggerStage>(shared_from_this()); match->get_shared_pointer(this)));
result.push_back(shared_ptr<TriggerMatch>(match, reset_parent<TriggerMatch>));
}
return result; return result;
} }

View File

@ -126,7 +126,7 @@ public:
template <class Parent, typename Struct> class SR_API StructureWrapper : template <class Parent, typename Struct> class SR_API StructureWrapper :
public enable_shared_from_this<StructureWrapper<Parent, Struct> > public enable_shared_from_this<StructureWrapper<Parent, Struct> >
{ {
public: protected:
/* Parent object which owns this child object's underlying structure. /* Parent object which owns this child object's underlying structure.
This shared pointer will be null when this child is unused, but 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 the parent are called at the correct time, i.e. only when all
references to both the parent and all its children are gone. */ references to both the parent and all its children are gone. */
shared_ptr<Parent> parent; 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: protected:
static void reset_parent(StructureWrapper<Parent, Struct> *object)
{
object->parent.reset();
}
Struct *structure; Struct *structure;
StructureWrapper<Parent, Struct>(Struct *structure) : StructureWrapper<Parent, Struct>(Struct *structure) :