[Debian-astro-commits] [gyoto] 116/221: Simplify introspection code by using new class Property::Value
Thibaut Jean-Claude Paumard
thibaut at moszumanska.debian.org
Fri May 22 20:52:38 UTC 2015
This is an automated email from the git hooks/post-receive script.
thibaut pushed a commit to branch master
in repository gyoto.
commit 30a2278267e2130611faee81126582a0a3eaef1a
Author: Thibaut Paumard <paumard at users.sourceforge.net>
Date: Thu Nov 27 12:05:00 2014 +0100
Simplify introspection code by using new class Property::Value
---
include/GyotoObject.h | 212 ++++++++++++++++++++++++--------------------
lib/Object.C | 240 +++++++++++++++++++++++++-------------------------
yorick/gyoto_utils.C | 50 +++++------
3 files changed, 256 insertions(+), 246 deletions(-)
diff --git a/include/GyotoObject.h b/include/GyotoObject.h
index 7034e8d..b9b2330 100644
--- a/include/GyotoObject.h
+++ b/include/GyotoObject.h
@@ -122,102 +122,6 @@ namespace Gyoto {
static Property const * const properties; \
virtual Property const * getProperties() const
-
-/**
- * \brief Object with properties
- */
-class Gyoto::Object
-{
- protected:
- std::string kind_;
- public:
- GYOTO_OBJECT;
- Object (std::string const &kind) ;
- Object () ;
- Object (Object const &orig) ;
- virtual ~Object();
- void set(Property const &p, double val);
- void set(Property const &p, double val, std::string const &unit);
- void set(Property const &p, bool val);
- void set(Property const &p, std::string const &val);
- void set(Property const &p, std::vector<double> const &val);
- //void set(std::string const pname, double val);
- void get(Property const &p, double &val) const ;
- void get(Property const &p, double &val, std::string const &unit) const ;
- void get(Property const &p, bool &val) const ;
- void get(Property const &p, std::string &val) const ;
- void get(Property const &p, std::vector<double> &val) const;
- //void get(std::string const pname, double &val);
- Property const * property(std::string const pname) const;
-
-#ifdef GYOTO_USE_XERCES
- void fillProperty(Gyoto::FactoryMessenger *fmp, Property const &p) const ;
-
- /// Called from Factory
- /**
- * Object implementations should impement fillElement to save their
- * parameters to XML and call the Metric::fillElement(fmp) for the
- * shared properties
- */
- virtual void fillElement(Gyoto::FactoryMessenger *fmp) const ;
-
- /**
- * \brief Main loop in Subcontractor_t function
- *
- * The Subcontractor_t function for each Metric kind should look
- * somewhat like this (templated as
- * Gyoto::Metric::Subcontractor<MyKind>):
-\code
-SmartPointer<Metric::Generic>
-Gyoto::Metric::MyKind::Subcontractor(FactoryMessenger* fmp) {
- SmartPointer<MyKind> gg = new MyKind();
- gg -> setParameters(fmp);
- return gg;
-}
-\endcode
- *
- * Each metric kind should implement setParameter(string name,
- * string content, string unit) to interpret the individual XML
- * elements. setParameters() can be overloaded in case the specific
- * Metric class needs low level access to the FactoryMessenger. See
- * Gyoto::Astrobj::UniformSphere::setParameters().
- */
- virtual void setParameters(Gyoto::FactoryMessenger *fmp) ;
-#endif
- /**
- * \brief Set parameter by name
- *
- * Assume MyKind is a subclass of Metric::Generic which has two
- * members (a string StringMember and a double DoubleMember):
-\code
-int MyKind::setParameter(std::string name, std::string content, std::string unit) {
- if (name=="StringMember") setStringMember(content);
- else if (name=="DoubleMember") setDoubleMemeber(atof(content.c_str()), unit);
- else return Generic::setParameter(name, content, unit);
- return 0;
-}
-\endcode
- * If MyKind is not a direct subclass of Generic, it should call the
- * corresponding setParameter() implementation instead of
- * Generic::setParameter().
- *
- * \param name XML name of the parameter
- * \param content string representation of the value
- * \param unit string representation of the unit
- * \return 0 if this parameter is known, 1 if it is not.
- */
- virtual int setParameter(std::string name,
- std::string content,
- std::string unit);
-
- virtual void setParameter(Gyoto::Property const &p,
- std::string const &name,
- std::string const &content,
- std::string const &unit);
-
-};
-
-
/**
* \brief Property
*/
@@ -299,6 +203,122 @@ class Gyoto::Property
Property const * find(std::string name) const;
+ class Value {
+ public:
+ Value();
+ ~Value();
+
+ double Double;
+ Value(double);
+ operator double() const;
+
+ bool Bool;
+ Value(bool);
+ operator bool() const;
+
+ long Long;
+ Value(long);
+ operator long() const;
+
+ std::string String;
+ Value(std::string);
+ operator std::string() const;
+
+ std::vector<double> VDouble;
+ Value(std::vector<double>);
+ operator std::vector<double>() const;
+
+ };
+
+};
+
+
+/**
+ * \brief Object with properties
+ */
+class Gyoto::Object
+{
+ protected:
+ std::string kind_;
+ public:
+ GYOTO_OBJECT;
+ Object (std::string const &kind) ;
+ Object () ;
+ Object (Object const &orig) ;
+ virtual ~Object();
+ void set(Property const &p, Property::Value const & val);
+ void set(Property const &p, Property::Value const & val, std::string const &unit);
+
+ Property::Value get(Property const &p) const;
+ Property::Value get(Property const &p, std::string const &unit) const;
+
+ Property const * property(std::string const pname) const;
+
+#ifdef GYOTO_USE_XERCES
+ void fillProperty(Gyoto::FactoryMessenger *fmp, Property const &p) const ;
+
+ /// Called from Factory
+ /**
+ * Object implementations should impement fillElement to save their
+ * parameters to XML and call the Metric::fillElement(fmp) for the
+ * shared properties
+ */
+ virtual void fillElement(Gyoto::FactoryMessenger *fmp) const ;
+
+ /**
+ * \brief Main loop in Subcontractor_t function
+ *
+ * The Subcontractor_t function for each Metric kind should look
+ * somewhat like this (templated as
+ * Gyoto::Metric::Subcontractor<MyKind>):
+\code
+SmartPointer<Metric::Generic>
+Gyoto::Metric::MyKind::Subcontractor(FactoryMessenger* fmp) {
+ SmartPointer<MyKind> gg = new MyKind();
+ gg -> setParameters(fmp);
+ return gg;
+}
+\endcode
+ *
+ * Each metric kind should implement setParameter(string name,
+ * string content, string unit) to interpret the individual XML
+ * elements. setParameters() can be overloaded in case the specific
+ * Metric class needs low level access to the FactoryMessenger. See
+ * Gyoto::Astrobj::UniformSphere::setParameters().
+ */
+ virtual void setParameters(Gyoto::FactoryMessenger *fmp) ;
+#endif
+ /**
+ * \brief Set parameter by name
+ *
+ * Assume MyKind is a subclass of Metric::Generic which has two
+ * members (a string StringMember and a double DoubleMember):
+\code
+int MyKind::setParameter(std::string name, std::string content, std::string unit) {
+ if (name=="StringMember") setStringMember(content);
+ else if (name=="DoubleMember") setDoubleMemeber(atof(content.c_str()), unit);
+ else return Generic::setParameter(name, content, unit);
+ return 0;
+}
+\endcode
+ * If MyKind is not a direct subclass of Generic, it should call the
+ * corresponding setParameter() implementation instead of
+ * Generic::setParameter().
+ *
+ * \param name XML name of the parameter
+ * \param content string representation of the value
+ * \param unit string representation of the unit
+ * \return 0 if this parameter is known, 1 if it is not.
+ */
+ virtual int setParameter(std::string name,
+ std::string content,
+ std::string unit);
+
+ virtual void setParameter(Gyoto::Property const &p,
+ std::string const &name,
+ std::string const &content,
+ std::string const &unit);
+
};
#endif
diff --git a/lib/Object.C b/lib/Object.C
index b878dad..8b68725 100644
--- a/lib/Object.C
+++ b/lib/Object.C
@@ -9,124 +9,133 @@ using namespace Gyoto ;
GYOTO_PROPERTY_FINALIZE(Object, NULL);
+/// Value
+
+Property::Value::Value() {}
+Property::Value::~Value() {}
+
+Property::Value::Value(double val) : Double(val) {}
+Property::Value::operator double() const {return Double;}
+
+Property::Value::Value(bool val) : Bool(val) {}
+Property::Value::operator bool() const {return Bool;}
+
+Property::Value::Value(long val) : Long(val) {}
+Property::Value::operator long() const {return Long;}
+
+Property::Value::Value(std::string val) : String(val) {}
+Property::Value::operator std::string() const {return String;}
+
+Property::Value::Value(std::vector<double> val) : VDouble(val) {}
+Property::Value::operator std::vector<double>() const {return VDouble;}
+
+/// Object
+
Gyoto::Object::Object(std::string const &name):kind_(name) {}
Gyoto::Object::Object():kind_("") {}
Gyoto::Object::Object(Object const &o):kind_(o.kind_) {}
Gyoto::Object::~Object() {}
+void Object::set(Property const &p,
+ Property::Value const &val,
+ std::string const &unit) {
-void Object::set(Property const &p, double val) {
- if (p.type != Property::double_t)
- throwError("Property is no a double");
- Property::set_double_t set = p.setter.set_double;
- if (!set) throwError("Can't set this Property");
- (this->*set)(val);
-}
-
-void Object::set(Property const &p, double val, std::string const &unit) {
- if (p.type != Property::double_t)
- throwError("Property is no a double");
- Property::set_double_unit_t setu = p.setter_unit.set_double;
- if (setu) {
- (this->*setu)(val, unit);
- } else {
- if (unit != "") throwError("Can't set this property with unit");
- set(p, val);
+ if (p.type == Property::double_t) {
+ Property::set_double_unit_t setu = p.setter_unit.set_double;
+ if (setu) {
+ (this->*setu)(val, unit);
+ } else {
+ if (unit != "") throwError("Can't set this property with unit");
+ set(p, val);
+ }
+ return;
}
-}
-void Object::set(Property const &p, bool val) {
- if (p.type != Property::bool_t)
- throwError("Property is no a bool");
- Property::set_bool_t set = p.setter.set_bool;
- if (!set) throwError("Can't set this Property");
- (this->*set)(val);
-}
+ if (unit != "")
+ throwError("Can't set this property with unit (not a double)");
-void Object::set(Property const &p, string const &val) {
- if (p.type == Property::bool_t) {
- cerr << "Object::set("<<p.name<<", "<<val<<")"<<std::endl<<std::endl;
- set(p, val==p.name);
- } else if ( p.type == Property::string_t
- || p.type == Property::filename_t) {
- Property::set_string_t set = p.setter.set_string;
- if (!set) throwError("Can't set this Property");
- (this->*set)(val);
- } else throwError("Cannot set this Property from a string");
-}
+ set(p, val);
+ return;
-void Object::set(Property const &p, vector<double> const &val) {
- if (p.type != Property::vector_double_t)
- throwError("Property is not a vector<double>");
- Property::set_vector_double_t set = p.setter.set_vdouble;
- if (!set) throwError("Can't set this Property");
- (this->*set)(val);
}
-// void Object::set(std::string const pname, double val) {
-// Property const * const p = property(pname);
-// if (!p) throwError ("No such Property");
-// set(*p, val);
-// }
-
-void Object::get(Property const &p, double &val) const {
- if (p.type != Property::double_t)
- throwError("Property is no a double");
- Property::get_double_t get = p.getter.get_double;
- if (!get) throwError("Can't get this Property");
- val = (this->*get)();
+void Object::set(Property const &p, Property::Value const &val) {
+# define ___local_case(type) \
+ case Property::type##_t: \
+ { \
+ Property::set_##type##_t set = p.setter.set_##type; \
+ if (!set) throwError("Can't set this Property"); \
+ (this->*set)(val); \
+ } \
+ break
+
+ switch (p.type) {
+ ___local_case(double);
+ ___local_case(bool);
+ ___local_case(long);
+ case Property::filename_t:
+ ___local_case(string);
+ case Property::vector_double_t:
+ {
+ Property::set_vector_double_t set = p.setter.set_vdouble;
+ if (!set) throwError("Can't set this Property");
+ (this->*set)(val);
+ }
+ break;
+ default:
+ throwError("Unimplemented Property type in Object::set");
+ }
+# undef ___local_case
}
-void Object::get(Property const &p, double &val, std::string const &unit) const {
- if (p.type != Property::double_t)
- throwError("Property is no a double");
- Property::get_double_unit_t getu = p.getter_unit.get_double;
- if (getu) {
- val = (this->*getu)(unit);
- } else {
- if (unit != "") throwError("Can't get this Property with unit");
- get(p, val);
+Property::Value Object::get(Property const &p,
+ std::string const &unit) const {
+
+ if (p.type == Property::double_t) {
+ Property::get_double_unit_t getu = p.getter_unit.get_double;
+ if (getu) return (this->*getu)(unit);
+ if (unit != "") throwError("Can't get this property with unit");
+ return get(p);
}
-}
+ if (unit != "")
+ throwError("Can't set this property with unit (not a double)");
-void Object::get(Property const &p, bool &val) const {
- if (p.type != Property::bool_t)
- throwError("Property is no a bool");
- Property::get_bool_t get = p.getter.get_bool;
- if (!get) throwError("Can't get this Property");
- val = (this->*get)();
+ return get(p);
}
-void Object::get(Property const &p, string &val) const {
- if (p.type == Property::bool_t) {
- bool bval;
- get(p, bval);
- if (bval) val=p.name;
- else val=p.name_false;
- } else if ( p.type == Property::string_t
- || p.type == Property::filename_t) {
- Property::get_string_t get = p.getter.get_string;
- if (!get) throwError("Can't get this Property as a string");
- val = (this->*get)();
+Property::Value Object::get(Property const &p) const {
+# define ___local_case(type) \
+ case Property::type##_t: \
+ { \
+ Property::get_##type##_t get = p.getter.get_##type; \
+ if (!get) throwError("Can't get this Property"); \
+ val = (this->*get)(); \
+ } \
+ break
+
+ Property::Value val;
+ switch (p.type) {
+ ___local_case(bool);
+ ___local_case(double);
+ ___local_case(long);
+ case Property::filename_t:
+ ___local_case(string);
+ case Property::vector_double_t:
+ {
+ Property::get_vector_double_t get = p.getter.get_vdouble;
+ if (!get) throwError("Can't get this Property");
+ val = (this->*get)();
+ }
+ break;
+ default:
+ throwError("Unimplemented Property type in Object::get");
}
+ return val;
+# undef ___local_case
}
-void Object::get(Property const &p, vector<double> &val) const {
- if (p.type != Property::vector_double_t)
- throwError("Property is not a vector<double>");
- Property::get_vector_double_t get = p.getter.get_vdouble;
- if (!get) throwError("Can't get this Property");
- val = (this->*get)();
-}
-
-// void Object::get(std::string const pname, double &val) {
-// Property const * const p = property(pname);
-// if (!p) throwError ("No such Property");
-// get(*p, val);
-// }
-
Property const * Object::property(std::string const pname) const {
return getProperties() -> find(pname);
}
@@ -136,33 +145,17 @@ void Object::fillProperty(Gyoto::FactoryMessenger *fmp, Property const &p) const
string name=p.name;
switch (p.type) {
case Property::bool_t:
- {
- bool val;
- get(p, val);
- fmp->setParameter(val?name:p.name_false);
- }
+ fmp->setParameter(get(p)?name:p.name_false);
break;
case Property::double_t:
- {
- double val;
- get(p, val);
- fmp->setParameter(name, val);
- }
+ fmp->setParameter(name, double(get(p)));
break;
case Property::string_t:
case Property::filename_t:
- {
- string val;
- get(p, val);
- fmp->setParameter(name, val);
- }
+ fmp->setParameter(name, std::string(get(p)));
break;
case Property::vector_double_t:
- {
- std::vector<double> val;
- get(p, val);
- fmp->setParameter(name, val);
- }
+ fmp->setParameter(name, get(p).VDouble);
break;
default:
throwError("Property type unimplemented in Object::fillProperty()");
@@ -206,23 +199,26 @@ void Object::setParameters(Gyoto::FactoryMessenger *fmp) {
void Object::setParameter(Property const &p, string const &name,
string const & content, string const & unit) {
+ Property::Value val;
switch (p.type) {
case Property::bool_t:
- Object::set(p, name==p.name);
- return;
+ val = (name==p.name);
+ break;
case Property::double_t:
- set(p, atof(content.c_str()), unit);
+ val = atof(content.c_str());
+ set(p, val, unit);
return;
case Property::filename_t:
case Property::string_t:
- set(p, content);
- return;
+ val = content;
+ break;
case Property::vector_double_t:
- set(p, FactoryMessenger::parseArray(content));
- return;
+ val = FactoryMessenger::parseArray(content);
+ break;
default:
throwError("Property type unimplemented in Object::setParameter()");
}
+ set(p, val);
}
int Object::setParameter(string name, string content, string unit) {
diff --git a/yorick/gyoto_utils.C b/yorick/gyoto_utils.C
index ffa91e8..e285490 100644
--- a/yorick/gyoto_utils.C
+++ b/yorick/gyoto_utils.C
@@ -354,37 +354,30 @@ long int __ygyoto_var_idx(long id) {
void ypush_property(Gyoto::SmartPointer<Gyoto::SmartPointee> ptr,
Gyoto::Property const& p, int iarg,
std::string name, std::string unit) {
+ Gyoto::Property::Value val;
+ if (p.type == Gyoto::Property::double_t)
+ val = ptr->get(p, unit);
+ else
+ val = ptr->get(p);
+
switch(p.type) {
case Gyoto::Property::bool_t:
- {
- bool val;
- ptr->get(p, val);
- ypush_long(name==p.name?val:!val);
- }
+ ypush_long(name==p.name?bool(val):!val);
break;
case Gyoto::Property::double_t:
- {
- double val;
- ptr->get(p, val, unit);
- ypush_double(val);
- }
+ ypush_double(val);
break;
case Gyoto::Property::string_t:
case Gyoto::Property::filename_t:
- {
- string val;
- ptr->get(p, val);
- *ypush_q(0) = p_strcpy(val.c_str());
- }
+ *ypush_q(0) = p_strcpy(string(val).c_str());
break;
case Gyoto::Property::vector_double_t:
{
- std::vector<double> val;
- ptr->get(p, val);
- size_t n=val.size();
+ std::vector<double> vval = val;
+ size_t n = vval.size();
long dims[]={1, long(n)};
double * buf = ypush_d(dims);
- for (size_t i=0; i<n; ++i) buf[i]=val[i];
+ for (size_t i=0; i<n; ++i) buf[i]=vval[i];
}
break;
default:
@@ -395,31 +388,32 @@ void ypush_property(Gyoto::SmartPointer<Gyoto::SmartPointee> ptr,
void yget_property(Gyoto::SmartPointer<Gyoto::SmartPointee> ptr,
Gyoto::Property const& p, int iarg, std::string name,
std::string unit) {
+ Gyoto::Property::Value val;
switch(p.type) {
case Gyoto::Property::bool_t:
{
- bool val=ygets_l(iarg);
+ val=ygets_l(iarg);
if (name != p.name) val = !val;
- ptr->set(p, val);
}
break;
case Gyoto::Property::double_t:
ptr->set(p, ygets_d(iarg), unit);
- break;
+ return;
case Gyoto::Property::filename_t:
case Gyoto::Property::string_t:
- ptr -> set(p, string(ygets_q(iarg)));
- return;
+ val = string(ygets_q(iarg));
+ break;
case Gyoto::Property::vector_double_t:
{
long n;
double *buf = ygeta_d(iarg, &n, NULL);
- std::vector<double> val(n, 0.);
- for (size_t i=0; i<n; ++i) val[i]=buf[i];
- ptr -> set(p, val);
+ std::vector<double> vval(n, 0.);
+ for (size_t i=0; i<n; ++i) vval[i]=buf[i];
+ val = vval;
}
- return;
+ break;
default:
y_error("Property type unimplemented in yget_property()");
}
+ ptr->set(p, val);
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-astro/packages/gyoto.git
More information about the Debian-astro-commits
mailing list