GOF Composite Design Pattern CompositeObject::Remove Recursive Implementation in C++ - c++

This is the part of question from my question asked in codereview website:
GOF Composite Design Pattern Implementation Using Modern C++
The post has complete information/implementation about it but here I am posting this question to understand about the following information:
How to implement CompositeEquipment::Remove?.
Based on my understanding, it should do recursive search in all composite object in which client has invoked and recursively all its child objects which can also be of composite type. Just to illustrate from above implementation, if client write the as cabinet->Remove(bus); it would not remove bus object as it is the child of chassis object. This seems to be incorrect to me. However I am not able to implement the CompositeEquipment::Remove in such a way that it searches recursively if child objects themselves are of composite.
So far I have came of with the following implementation which just searches the composite objects which client has involved for Remove method.
//To find out whether items are in the composite objects
class Name_Equal {
private:
Equipment::EquipmentSmartPtr val;
public:
Name_Equal(const Equipment::EquipmentSmartPtr& v) :val(v) { }
bool operator()(const Equipment::EquipmentSmartPtr& x) const {
return (x->Name() == val->Name());
}
};
void CompositeEquipment::Remove(EquipmentSmartPtr entry) {
find_equipment(_equipment, entry);
}
void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
EquipmentSmartPtr& entry){
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
}
}
Kindly let me know in case any additional information or complete code needs to post here as well.

There are two options:
Provide a virtual function Remove in the base class and make it a noop implementation. Then add a few more lines to CompositeEquipment::find_equipment.
void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
EquipmentSmartPtr& entry){
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
} else {
for ( EquipmentSmartPtr sptr : vec )
{
sptr->Remove(entry);
}
}
}
Use dynamic_cast to determine whether an item of the composite is a composite also. If so, call Remove on it. I prefer this option.
void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
EquipmentSmartPtr& entry){
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
} else {
for ( EquipmentSmartPtr sptr : vec )
{
Equipment* ptr = dynamic_cast<Equipment*>(sptr.get());
if ( ptr )
{
ptr->Remove(entry);
}
}
}
}
A bit about names... find_equipment seems a strange name for the function. I would put the whole thing in Remove.
void CompositeEquipment::Remove(EquipmentSmartPtr& entry){
std::vector<EquipmentSmartPtr>& vec = _equipment;
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
} else {
for ( EquipmentSmartPtr sptr : vec )
{
Equipment* ptr = dynamic_cast<Equipment*>(sptr.get());
if ( ptr )
{
ptr->Remove(entry);
}
}
}
}

Related

C++ - How to delete shared_ptr from vector based on it's value [duplicate]

This question already has answers here:
C++ remove_if on a vector of objects
(2 answers)
Closed 2 years ago.
I have the following class:
public:
Client(tcp::socket socket)
: socket_(std::move(socket))
{
}
void start();
int connectionId;
Than I have the following vector:
class Server {
public:
Server();
static std::vector<std::shared_ptr<Client>> Clients;
}
EDIT*
Can I do something like this:
for (int i = 0; i < Server::Clients.size(); ++i) {
if(Server::Clients[i]->connectionId == connectionId)
Server::Clients.erase(Server::Clients.begin()+i);
}
My question is how can I remove the shared pointer in Clients with a specific connectionId aka remove by value?
In C++17, you can do use std::remove_if. The following should work.
#include <algorithm>
Server &s = /* <getServerFromSomewhere> */;
auto new_end = remove_if(s.Clients.begin(), s.Clients.end(),
[] (std::shared_ptr<Client>& p) {
return p->connectionId == /* <someValueToBeRemoved> */;
}
);
s.Clients.resize(new_end - s.Clients.begin());
Use std::remove_if with a lambda as predicate and then container's method erase:
std::vector<std::shared_ptr<Client>> Clients;
int id{0}; // the id to be removed
Clients.erase(std::remove_if(Clients.begin(), Clients.end(), [id](const auto &entity) { return id == entity->connectionId; }), Clients.end());
If you don't have access to std::remove_if, you have to fall back to loop of a kind:
auto it = Clients.begin()
while (it != Clients.end())
{
if((*it)->connectionId = testValue)
{
// can connection id be non-unique?
it = Clients.erase(it);
//if yes, we have to save new iterator
continue;
}
it++;
}
If connectionId is unique use find_if to find that element and erase it, it's way cheaper.
If remove_if available, following code is possible, if it's advantage over first example is questionable.
auto new_end = remove_if(s.Clients.begin(), s.Clients.end(),
[=] (auto& ptr) {
return ptr->connectionId == testValue; /* value to be removed */
}
erase(new_end, Clients.end()); // remove tail of vector that is now consisting of empty elements.
Clients better be a deque than a vector, that way erasing an element from it won't cause the "tail" part of Clients list to be copied when every removal is done.

Function returning a container containing specific elements of input container

I have a vector or list of which I only want to apply code to specific elements. E.g.
class Container : public std::vector<Element*>
Or
class Container : public std::list<Element*>
And:
Container newContainer = inputContainer.Get(IsSomething);
if (!newContainer.empty()) {
for (Element* const el: newContainer ) {
[some stuff]
}
} else {
for (Element* const el : inputContainer) {
[some stuff]
}
}
I've written a member function Get() as follows.
template<typename Fn>
auto Container::Get(const Fn& fn) const {
Container output;
std::copy_if(cbegin(), cend(), std::inserter(output, output.end()), fn);
return output;
}
and IsSomething would be a lambda, e.g.
auto IsSomething= [](Element const* const el)->bool { return el->someBool; };
From performance perspective: Is this a good approach? Or would it be better to copy and remove?
template<typename Fn>
auto Container::Get(const Fn& fn) const {
Container output(*this);
output.erase(std::remove_if(output.begin(), output.end(), fn), end(output));
return output;
}
Or is there a better approach anyhow?
edit: different example
As my previous example can be written in a better way, let's show a different example:
while (!(container2 = container1.Get(IsSomething)).empty()&&TimesFooCalled<SomeValue)
{
Container container3(container2.Get(IsSomething));
if (!container3.empty()) {
Foo(*container3.BestElement());
} else {
Foo(*container2.BestElement());
}
}
Not answering your direct question, but note that you can implement the original algorithm without copying anything. Something like this:
bool found = false;
for (Element* const el: inputContainer) {
if (IsSomething(el)) {
found = true;
[some stuff]
}
}
if (!found) {
for (Element* const el : inputContainer) {
[some stuff]
}
}
The usual pattern that I use is something like this:
for(auto const * item : inputContainer) if(IsSomething(item)) {
// Do stuff with item
}
This is usually good enough, so other approaches seem overkill.
For better performance it is always better not to copy or remove elements from the list you get. In my experience it's even faster if you only go through the list once, for caching reasons. So here is what I would do to find one or the other "best" value from a list:
auto const isBetter = std::greater<Element>();
Element const * best = nullptr, const * alt_best = nullptr;
for(Element const * current : inputContainer) {
if(IsSomething(current)) {
if(!best || isBetter(*best, *current)) best = current;
} else {
if(!alt_best || isBetter(*alt_best, *current)) alt_best = current;
}
}
if(best) {
// do something with best
} else if(alt_best) {
// do something with alt_best
} else {
// empty list
}
If you find yourself doing this a lot or you want to make this part of your class's interface you could consider writing an iterator that skips elements you don't like.
If you actually want to remove the item from the list, you could do something like this:
inputContainer.erase(std::remove_if(std::begin(inputContainer), std::end(inputContainer),
[](Element const *item) {
if(IsSomething(item)) {
// Do something with item
return true;
}
return false;
}
));

C++ find_if - How to find an ID (int(

I wanted to find how to use find_if to find the SceneNode based on ID. I am unsure how to do this though.
I was able to for example, do this to remove the SceneNode based on the actual pointer like so:
SceneNode::Ptr SceneNode::detachChild(const SceneNode& node)
{
auto found = std::find_if(mChildren.begin(), mChildren.end(), [&](Ptr& p) -> bool {return p.get() == &node; });
...
but I am unsure on how to deal with find_if if I am looking for SceneNodes mID variable (which is an INT).
I.E.
SceneNode::Ptr SceneNode::findChild(int findID)
{
auto found = std::find_if(mChildren.begin(), mChildren.end(), ... ? = findID?; });
...
Does anyone have any good sites or info for me that explains find_if well? Thanks!
You basically had it...
auto found = std::find_if(
mChildren.begin(),
mChildren.end(),
[&](Ptr& p) -> bool { return p->mID == node.mID; }
);
Based on your first example, it appears that a Ptr & is the result of mChildren.begin().operator*() (or something compatible).
So:
SceneNode::Ptr SceneNode::findChild(int findID)
{
auto found = std::find_if(
mChildren.begin(), mChildren.end(),
[findID](Ptr &ptr)
{
return findID == ptr.get()->mID;
});
...
}
I think you want something like this:
SceneNode::Ptr SceneNode::findChild(int findID)
{
auto found = std::find_if(std::begin(mChildren), std::end(m_children),
[=](Ptr& p) { return p->mID == findID; }
);
// ...
}
This lambda will capture findID by value and compare it with the mID member of what Ptr points to.

How to refactor this while loop to get rid of "continue"?

I have a while (!Queue.empty()) loop that processes a queue of elements. There are a series of pattern matchers going from highest-priority to lowest-priority order. When a pattern is matched, the corresponding element is removed from the queue, and matching is restarted from the top (so that the highest-priority matchers get a chance to act first).
So right now it looks something like this (a simplified version):
while (!Queue.empty())
{
auto & Element = *Queue.begin();
if (MatchesPatternA(Element)) { // Highest priority, since it's first
// Act on it
// Remove Element from queue
continue;
}
if (MatchesPatternB(Element)) {
// Act on it
// Remove Element from queue
continue;
}
if (MatchesPatternC(Element)) { // Lowest priority, since it's last
// Act on it
// Remove Element from queue
continue;
}
// If we got this far, that means no pattern was matched, so
// Remove Element from queue
}
This works, but I want to refactor this loop in some way to remove the use of the keyword continue.
Why? Because if I want to outsource a pattern matching to an external function, it obviously breaks. E.g.
void ExternalMatching(...)
{
if (MatchesPatternB(Element)) {
// Act on it
// Remove Element from queue
continue; // This won't work here
}
}
while (!Queue.empty())
{
auto & Element = *Queue.begin();
if (MatchesPatternA(Element)) {
// Act on it
// Remove Element from queue
continue;
}
ExternalMatching(...);
if (MatchesPatternC(Element)) {
// Act on it
// Remove Element from queue
continue;
}
// If we got this far, that means no pattern was matched, so
// Remove Element from queue
}
I don't want to have to write repetitive if statements like if (ExternalMatching(...)) { ... continue; }, I'd rather find a cleaner way to express this logic.
This simplified example might make it seem like a good idea to make pattern matching more general rather than having distinct MatchesPatternA, MatchesPatternB, MatchesPatternC, etc. functions. But in my situation the patterns are quite complicated, and I'm not quite ready to generalize them yet. So I want to keep that part as is, separate functions.
Any elegant ideas? Thank you!
If you have access to C++11 I would like to suggest another solution. Basicaly I created a container of handlers and actions that can be adjusted in runtime. It may be a pro or con for your design depending on your requirements. Here it is:
#include <functional>
typedef std::pair<std::function<bool(const ElementType &)>,
std::function<void(ElementType &)> > HandlerData;
typedef std::vector<HandlerData> HandlerList;
HandlerList get_handlers()
{
HandlerList handlers;
handlers.emplace_back([](const ElementType &el){ return MatchesPatternA(el); },
[](ElementType &el){ /* Action */ });
handlers.emplace_back([](const ElementType &el){ return MatchesPatternB(el); },
[](ElementType &el){ /* Action */ });
handlers.emplace_back([](const ElementType &el){ return MatchesPatternC(el); },
[](ElementType &el){ /* Action */ });
return handlers;
}
int main()
{
auto handlers = get_handlers();
while(!Queue.empty()) {
auto &Element = *Queue.begin();
for(auto &h : handlers) {
// check if handler matches the element
if(h.first(Element)) {
// act on element
h.second(Element);
break;
}
}
// remove element
Queue.pop_front();
}
}
I would recommend using a function that does the pattern matching (but does not act on the result) and then a set of functions that act on the different options:
enum EventType {
A, B, C //, D, ...
};
while (!queue.empty()) {
auto & event = queue.front();
EventType e = eventType(event); // Internally does MatchesPattern*
// and returns the match
switch (e) {
case A:
processA(event);
break;
case B:
processB(event);
This way you clearly separate the matching from the processing, the loop is just a simple dispatcher
Consider an interface:
class IMatchPattern
{
public:
virtual bool MatchesPattern(const Element& e) = 0;
};
Then you can organize a container of objects implementing IMatchPattern, to allow for iterative access to each pattern match method.
You can change your ExternalMatching to return bool, indicating that the processing has been done. This way the caller would be able to continue evaluating if necessary:
bool ExternalMatching(...)
{
if (MatchesPatternB(Element) {
// Act on it
// Remove Element from queue
return true;
}
return false;
}
Now you can call it like this:
if (ExternalMatchin1(...)) continue;
if (ExternalMatchin2(...)) continue;
...
if (ExternalMatchingN(...)) continue;
Ok, I ended up rewriting the loop more akin to this.
Huge thanks and credit goes to Yuushi, dasblinkenlight, David Rodríguez for their help; this answer is based on a combination of their answers.
bool ExternalMatching(...)
{
bool Match;
if ((Match = MatchesPatternX(Element))) {
// Act on it
} else if ((Match = MatchesPatternY(Element))) {
// Act on it
}
return Match;
}
while (!Queue.empty())
{
auto & Element = Queue.front();
if (MatchesPatternA(Element)) { // Highest priority, since it's first
// Act on it
} else if (MatchesPatternB(Element)) {
// Act on it
} else if (ExternalMatching(...)) {
} else if (MatchesPatternC(Element)) { // Lowest priority, since it's last
// Act on it
}
// Remove Element from queue
}
Now, I know there's further room for improvement, see answers of Mateusz Pusz and Michael Sh. However, this is good enough to answer my original question, and it'll do for now. I'll consider improving it in the future.
If you're curious to see the real code (non-simplified version), see here:
https://github.com/shurcooL/Conception/blob/38f731ccc199d5391f46d8fce3cf9a9092f38c65/src/App.cpp#L592
Thanks everyone again!
I would like to suggest a Factory function that would take the Element and create an appropriate handler and return the interface pointer to the handler.
while (!Queue.empty())
{
auto & Element = *Queue.begin();
// get the appropriate handler object pointer e.g.
IPatternHandler *handler = Factory.GetHandler(Element);
handler->handle();
// clean up handler appropriately
}

Is there a better way? While loops and continues

There are many functions within the code I am maintaining which have what could be described as boilerplate heavy. Here is the boilerplate pattern which is repeated ad nausea throughout the application when handling DB I/O with a cursor:
if( !RowValue( row, m_InferredTable->YearColumn(), m_InferredTable->YearName(), m_InferredTable->TableName(), value )
|| !IsValidValue( value ) )
{
GetNextRow( cursor, m_InferredTable );
continue;
}
else
{
value.ChangeType(VT_INT);
element.SetYear( value.intVal );
}
The thing is not all of these statements like this deal with ints, this "element" object, the "year" column, etc. I've been asked to look at condensing it even further than it already is and I can't think of a way to do it. I keep tripping over the continue statement and the accessors of the various classes.
Edit: Thanks to all those that commented. This is why I love this site. Here is an expanded view:
while( row != NULL )
{
Element element;
value.ClearToZero();
if( !GetRowValue( row, m_InferredTable->DayColumn(), m_InferredTable->DayName(), m_InferredTable->TableName(), value )
|| !IsValidValue( value ) )
{
GetNextRow( cursor, m_InferredTable );
continue;
}
else
{
value.ChangeType(VT_INT);
element.SetDay( value.intVal );
}
And things continue onward like this. Not all values taken from a "row" are ints. The last clause in the while loop is "GetNextRow."
Okay, from what you've said, you have a structure something like this:
while (row!=NULL) {
if (!x) {
GetNextRow();
continue;
}
else {
SetType(someType);
SetValue(someValue);
}
if (!y) {
GetNextRow();
continue;
}
else {
SetType(SomeOtherType);
SetValue(someOtherValue);
}
// ...
GetNextRow();
}
If that really is correct, I'd get rid of all the GetNextRow calls except for the last one. I'd then structure the code something like:
while (row != NULL) {
if (x) {
SetType(someType);
SetValue(someValue);
}
else if (y) {
SetType(someOtherType);
SetValue(SomeOtherValue);
}
// ...
GetNextRow();
}
Edit: Another possibility would be to write your code as a for loop:
for (;row!=NULL;GetNextRow()) {
if (!x)
continue;
SetTypeAndValue();
if (!y)
continue;
SetTypeandValue();
// ...
Since the call to GetNextRow is now part of the loop itself, we don't have to (explicitly) call it each time -- the loop itself will take care of that. The next step (if you have enough of these to make it worthwhile) would be to work on shortening the code to set the types and values. One possibility would be to use template specialization:
// We never use the base template -- it just throws to indicate a problem.
template <class T>
SetValue(T const &value) {
throw(something);
}
// Then we provide a template specialization for each type we really use:
template <>
SetValue<int>(int value) {
SetType(VT_INT);
SetValue(value);
}
template <>
SetValue<float>(float value) {
SetType(VT_FLOAT);
SetValue(value);
}
This lets you combine a pair of calls to set the type and the value into a single call.
Edit: As far as cutting processing short goes, it depends -- if parsing a column is expensive (enough to care about) you can simply nest your conditions:
if (x) {
SetTypeAndValue();
if (y) {
SetTypeAndValue();
if (z) {
SetTypeAndValue();
and so on. The major shortcoming of this is that it'll get pretty deeply nested if (as you've said) you have 20+ conditions in a single loop. That being the case, I'd probably think hard about the for-loop based version I gave above.
Why not make a function to do all the work?
bool processElement(Element& element, Row* row, int value, Table& m_InferredTable, /*other params*/)
{
if( !GetRowValue( row, m_InferredTable->DayColumn(), m_InferredTable->DayName(), m_InferredTable->TableName(), value )
|| !IsValidValue( value ) )
{
GetNextRow( cursor, m_InferredTable );
return true;
}
else
{
value.ChangeType(VT_INT);
element.SetDay( value.intVal );
}
return false;
}
In your loop
while (row != NULL)
{
if (processElement(element, row, value, m_InferredTable))
continue;
// other code
}
Why not invert your if-test?
if (RowValue(row, m_InferredTable->YearColumn(), m_InferredTable->YearName(), m_InferredTable->TableName(), value )
&& IsValidValue( value ))
{
value.ChangeType(VT_INT);
element.SetYear( value.intVal );
}
else
{
GetNextRow( cursor, m_InferredTable );
}
My instinctual approach is to build a polymorphic approach here, where you eventually wind up doing something like(modulo your language and exact logic):
db_cursor cursor;
while(cursor.valid())
{
if(cursor.data.valid())
{
process();
}
cursor.next();
}
db_cursor would be a base class that your different table type classes inherit from, and the child classes would implement the validity functions.
Move it into a template function, templated on the element type (e.g. integer), which you can call over and over. Vary the behavior per data type with a trait template.
template <typename T> struct ElemTrait<T> {};
template <> struct ElemTrait<int> {
static inline void set(Val &value, Elem &element) {
value.ChangeType(VT_INT);
element.SetYear(value.intVal);
}
};
// template <> struct ElemTrait<float> { ... };
template <typename T>
void do_stuff( ... ) {
// ...
if (!RowValue(row,
m_InferredTable->YearColumn(),
m_InferredTable->YearName(),
m_InferredTable->TableName(), value)
|| !IsValidValue(value)
) {
GetNextRow(cursor, m_InferredTable);
continue;
} else {
ElemTrait<T>::set(value, element);
}
// ...
}
You can take out all the GetNextRow calls and the else clauses:
for (row = GetFirstRow () ; row != null ; GetNextRow ())
{
Element element;
value.ClearToZero();
if( !GetRowValue( row, m_InferredTable->DayColumn(), m_MetInferredOutTable->DayName(), m_MetInferredOutTable->TableName(), value )
|| !IsValidValue( value ) )
{
continue;
}
value.ChangeType(VT_INT);
element.SetDay( value.intVal );
}