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)
{
{
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;
}
{
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;
}
{
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;
}
/* 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;
}
{
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;
}
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>>
{
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;
}
{
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;
}
{
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;
}
{
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) :
{
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;
}
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
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) :