
#include <tchar.h>
#include "iostream"
#include <vector>

//forward declarations
struct Boat;
struct Plane;

//create our visitor base class 
struct VisitorBase
{
	virtual void visit(const Boat& b) = 0;
	virtual void visit(const Plane& p) = 0;
};

//write our accept method in the base class
//this is helpful because it allows us to have containers of Visitable objects
struct Visitable
{
	virtual void accept(VisitorBase &v) const = 0;
};


// create the base craft struct which will have our only implementation of the accept() method
template <typename T>
struct Craft : Visitable
{
	unsigned int size, weight, RGBAColor;

	void accept(VisitorBase &v) const
	{
		const T* upcast = dynamic_cast<const T* const>(this);
		if(upcast != NULL)
			v.visit(*upcast);
	}
};

struct Plane : Craft<Plane>
{
	Plane(int numberOfPassengers, int numberOfParachutes) : numberOfPassengers(numberOfPassengers), numberOfParachutes(numberOfParachutes){};
	int numberOfPassengers, numberOfParachutes;
};


struct Boat : Craft<Boat>
{
	Boat(int numberOfLifeVests, int maxNumberOfPassengers) : numberOfLifeVests(numberOfLifeVests), maxNumberOfPassengers(maxNumberOfPassengers){};
	int numberOfLifeVests, maxNumberOfPassengers;
};




//subclass the visitor base class with some implementations
struct CraftSafetyComplianceVisitor  : VisitorBase
{
	bool compliant;

	CraftSafetyComplianceVisitor ():compliant(true){};

	virtual void visit(const Boat& boat)
	{
		compliant &= boat.numberOfLifeVests >= boat.maxNumberOfPassengers;
	};

	virtual void visit(const Plane& plane)
	{
		compliant &= plane.numberOfParachutes >= plane.numberOfPassengers;
	};
};


int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<Visitable*> crafts;
	crafts.push_back(new Boat(1,1));
	crafts.push_back(new Plane(1,1));

	CraftSafetyComplianceVisitor  v;
	for(std::vector<Visitable*>::iterator i = crafts.begin(); i != crafts.end(); i++)
	{
		(*i)->accept(v);
	}

	std::cout << (!v.compliant ? "not " : "") << "all crafts are in compliance" << std::endl;

	return 0;
}

