# Holder The Holder offers a framework for resource management of polymorphic objects. It enables the use of input and output operators, and provides a short-hand for dynamic casting. Using the Holder, it becomes easier to store polymorphic objects in a container than it would be using pointers. The framework requires the user to implement three elements: The set of polymorphic classes inheriting from a chosen base class BaseClass; A Factory-method Factoryimplemented as a functor; An operator<<(std::ostream&, BaseClass&); ## Interface ### Holder The Holder class takes two template parameters:
    template <class BaseClass, class Factory>
    class Holder;
      typedef BasePtr
| The type of pointer used to hold objects.
      Holder()
| Constructor, no object will be managed.
      Holder(BasePtr ptr)
| The object pointed to by ptr will be managed.
      Holder(BaseClass *ptr)
| The object pointed to by ptr will be managed.
      BasePtr &operator()()
| Returns a pointer to the object held.
      template <class DerivedClass>
      DerivedClass& cast()
| Return a reference to the object as a DerivedClass.
      template <class DerivedClass>
      const DerivedClass& cast() const
| Return a reference to the object as a const DerivedClass.
### Element 1: the Class Hierarchy The class hierarchy is to be implemented freely, but it is recommended to include a virtual member function std::string() to_string() in the base class. ### Element 2: the Factory The functor Factory implementing the factory method should contain an implementation of either one of the two functions:
    Base* operator()(std::istream&) throw(cvmlcpp::ParseError)
or:
    Holder<Base, Factory>::BasePtr operator()(std::istream&) throw(cvmlcpp::ParseError)
### Element 3: the Output Operator The output operator should be implement as a compliment of Factory's operator()(std::istream&), that is, if output produced by the implemented operator<<(std::ostream&, BaseClass&); is given as input to the Factory, the object constructed by the Factory should be identical to object that produced the output. See the example. ## Example
    #include <cassert>
    #include <string>
    #include <iostream>
    #include <sstream>

    #include <boost/lexical_cast.hpp>

    #include <cvmlcpp/base/Holder>
    #include <cvmlcpp/volume/DTree>

    /*
     * The framework consists of 3 elements
     *
     * 1) The set of polymorphic classes
     * 2) A Factory-method implemented as a Functor
     * 3) An operator<<(...)
     */

    // First element: The set of polymorphic classes
    struct Furniture
    {
    	int price;

    	virtual ~Furniture() { }

    	virtual std::string to_string() const = 0;
    };

    struct Chair : public Furniture
    {
    	int legs;
    	virtual std::string to_string() const
    	{
    		return  std::string("<chair> <legs> ") +
    			boost::lexical_cast<std::string>(legs) +
    			std::string(" </legs> </chair>");
    	}
    };

    struct Table : public Furniture
    {
    	int surface;
    	virtual std::string to_string() const
    	{
    		return  std::string("<table> <surface> ") +
    			boost::lexical_cast<std::string>(surface) +
    			std::string(" </surface> </table>");
    	}
    };

    // Second element: A Factory-method implemented as a Functor
    class FurnitureFactory
    {
    	public:
    		// The factory should produce an object from the class hierarchy
    		// given an input stream. It may throw an exception of type
    		// cvmlcpp::ParseError if the input is invalid.
    		Furniture * operator()(std::istream& i_stream)
    			throw(cvmlcpp::ParseError)
    		{
    			i_stream >> tag; // read open tag
    			if (tag == "<chair>")
    				return parseChair(i_stream);
    			else if (tag == "<table>")
    				return parseChair(i_stream);
    			else throw (cvmlcpp::ParseError()); // Unknown tag

    			assert(false); // We should never get here
    			return (Furniture *)0;
    		}

    		Chair* parseChair(std::istream& i_stream)
    			throw(cvmlcpp::ParseError)
    		{
    			Chair* chair = new Chair();

    			// This is buggy but let's keep the example simple
    			try {
    				// Read "<legs> value </legs>"
    				i_stream >> tag >> chair->legs >> tag;
    				i_stream >> tag; // read "</chair>"
    			}
    			catch (std::exception &e) {
    				delete chair;
    				throw(cvmlcpp::ParseError());
    			}

    			return chair;
    		}

    		Table* parseTable(std::istream& i_stream)
    			throw(cvmlcpp::ParseError)
    		{
    			Table* table = new Table();

    			// This is buggy but let's keep the example simple
    			try {
    				// Read "<surface> value </surface>"
    				i_stream >> tag >> table->surface >> tag;
    				i_stream >> tag; // read "</table>"
    			}
    			catch (std::exception &e) {
    				delete table;
    				throw(cvmlcpp::ParseError());
    			}

    			return table;
    		}

    	private:
    		std::string tag;
    };

    // Third element: an output operator
    std::ostream& operator<<(std::ostream& o_stream, const Furniture &furniture)
    { return o_stream << furniture.to_string(); }

    // Needed for test
    bool operator==(const Chair& lhs, const Chair& rhs)
    { return lhs.legs == rhs.legs; }

    // XML representation of a DTree describing a room
    const char * roomXML =
    "<branch> \
    	<leaf> \
    		<index> 0 </index> \
    		<value> \
    			<chair> <legs> 4 </legs> </chair> \
    		</value> \
    	</leaf> \
    	<leaf> \
    		<index> 1 </index> \
    		<value> \
    			<chair> <legs> 3 </legs> </chair> \
    		</value> \
    	</leaf> \
    	<leaf> \
    		<index> 2 </index> \
    		<value> \
    			<chair> <legs> 1 </legs> </chair> \
    		</value> \
    	</leaf> \
    	<leaf> \
    		<index> 3 </index> \
    		<value> \
    			<table> <surface> 10 </surface> </table> \
    		</value> \
    	</leaf> \
    </branch>";

    int main()
    {
    	using namespace std;
    	using namespace cvmlcpp;

    	// Description of an object
    	const string chairxml = "<chair> <legs> 4 </legs> </chair>";

    	// Create a stream
    	stringstream input(chairxml);

    	// Read an object from a stream and hold it
    	Holder<Furniture, FurnitureFactory> holder1;
    	input >> holder1;

    	// Output the object
    	stringstream output;
    	output << holder1;

    	// Read the object back
    	Holder<Furniture, FurnitureFactory> holder2;
    	output >> holder2;

    	// Verify that they are equal
    	assert(holder1.cast<Chair>() == holder2.cast<Chair>());

    	// An XML-like source - the description of a room
    	stringstream roomStream(roomXML);

    	// Read a tree full of polymorphic objects from XML
    	DTree<Holder<Furniture, FurnitureFactory>, 2> room;
    	roomStream >> room;

    	cout << room;

    	return 0;
    }