// Francois Beaune
// January 2001

#include <cstring>
#include <iostream>
#include <map>

using namespace std;

class CStringCmp {
public:
	bool operator()(const char *s1, const char *s2) {
		return strcmp(s1, s2) < 0;
	}
};

class Object {
	typedef void (Object::*mptr_double)(double); // pointer to 'Object' method taking double
	
	map<const char *,mptr_double,CStringCmp>
		mm_double;	// map string to method taking double
public:
	virtual void RegisterProperty(const char *name, mptr_double method) {
		mm_double[name] = method;
	}

	virtual bool SetProperty(const char *name, double value) {
		mptr_double method = mm_double[name];

		if(method)
			(this->*method)(value);

		return method;
	}
};

class Sphere : public Object {
	double radius;
public:
	Sphere(double r) : radius(r) {
		RegisterProperty("radius",mptr_double(&Sphere::SetRadius));
	}

	void SetRadius(double r) {
		radius = r;
	}

	double Radius() const {
		return radius;
	}
};

int main() {
	Sphere *s = new Sphere(1);

	if(s->SetProperty("radius",10))
		cout << "s->radius set to " << s->Radius() << '.' << endl;

	if(!s->SetProperty("undefined",1234))
		cout << "The property \"undefined\" does not exist for object 's'." << endl;

	Object *o = new Sphere(2);

	if(o->SetProperty("radius",20))
		cout << "o->radius set to " <<
			dynamic_cast<Sphere *>(o)->Radius() << '.' << endl;

	return 0;
}
