/*
MultiNode sample code
Henry Smith (henry@enigmasoftware.ca)
main.cpp
*/
#include "MultiNode.h"
#include <string>
#include <iostream>
#include <boost/bind.hpp>
using namespace std;
////////////////////////////////////////////////////////////////////////////////
//
// An example class derived from MultiNode
//
////////////////////////////////////////////////////////////////////////////////
class ExampleObject
: public MultiNode<ExampleObject>
{
public:
static void RunTest ();
public:
ExampleObject (const string& inName, bool inInteresting = false)
: mName(inName)
, mInteresting(inInteresting)
{
}
const string& ToString () const {
return mName;
}
// Some example predicates
bool IsInteresting () const {
return mInteresting;
}
bool NameContains (const string& inSubstring) const {
return (mName.find( inSubstring ) != string::npos);
}
private:
string mName;
bool mInteresting;
};
////////////////////////////////////////////////////////////////////////////////
//
// Family IDs
//
////////////////////////////////////////////////////////////////////////////////
enum Family
{
MainFamily,
SecondFamily
};
////////////////////////////////////////////////////////////////////////////////
//
// Example
//
////////////////////////////////////////////////////////////////////////////////
void
ExampleObject::RunTest ()
{
Ref parent (new ExampleObject ("parent", true)); // Mark as interesting
Ref child1 (new ExampleObject ("child1"));
Ref child2 (new ExampleObject ("child2", true)); // Mark as interesting
Ref grandchild1 (new ExampleObject ("grandchild1"));
Ref grandchild2 (new ExampleObject ("grandchild2"));
Ref grandchild3 (new ExampleObject ("grandchild3", true)); // Mark as interesting
// Build tree structure:
//
// -- (MainFamily) --
//
// parent
// child1
// grandchild1
// child2
// grandchild2
// grandchild3
//
parent->AddChildIn( MainFamily, child1 );
parent->AddChildIn( MainFamily, child2 );
child1->AddChildIn( MainFamily, grandchild1 );
child2->AddChildIn( MainFamily, grandchild2 );
child2->AddChildIn( MainFamily, grandchild3 );
cout << "-- (MainFamily) --\n"
<< "parent\n"
<< " child1\n"
<< " grandchild1\n"
<< " child2\n"
<< " grandchild2\n"
<< " grandchild3\n"
<< "\n";
// -- (SecondFamily) --
//
// child2
// child1
// grandchild2
// grandchild1
child2->AddChildIn( SecondFamily, child1 );
child1->AddChildIn( SecondFamily, grandchild2 );
grandchild2->AddChildIn( SecondFamily, grandchild1 );
cout << "-- (SecondFamily) --\n"
<< "child2\n"
<< " child1\n"
<< " grandchild2\n"
<< " grandchild1\n"
<< "\n";
// Visit some interesting objects
cout << "Visit 1 (all interesting objects):" << endl;
for (tree_iterator i (parent, &ExampleObject::IsInteresting); i; ++i)
{
// Do something with the object...
cout << "- " << i->ToString() << " visited." << endl;
}
cout << endl;
// Visit a different set of objects
cout << "Visit 2 (children of child2 with 3 in their name):" << endl;
for (child_iterator i (child2, boost::bind( &ExampleObject::NameContains, _1, "3" )); i; ++i)
{
cout << "- " << i->ToString() << " visited." << endl;
}
cout << endl;
// etc.
cout << "Visit 3 (parents of grandchild1, including self):" << endl;
for (parent_iterator i (grandchild1); i; ++i)
{
cout << "- " << i->ToString() << " visited." << endl;
}
cout << endl;
cout << "Visit 4 (the other family):" << endl;
for (tree_iterator i (child2, SecondFamily); i; ++i)
{
cout << "- " << i->ToString() << " visited." << endl;
}
cout << endl;
}
////////////////////////////////////////////////////////////////////////////////
//
// main
//
////////////////////////////////////////////////////////////////////////////////
int main ()
{
ExampleObject::RunTest();
return 0;
}