Provide eoParser::setORcreateParam to set a paramter in the parser to

a specific value.
This commit is contained in:
kuepper 2005-08-29 07:50:50 +00:00
commit f0fd15f20c
3 changed files with 421 additions and 399 deletions

View file

@ -21,7 +21,7 @@
Contact: todos@geneura.ugr.es, http://geneura.ugr.es Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk mkeijzer@dhi.dk
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef eoParam_h #ifndef eoParam_h
@ -45,6 +45,8 @@
#include <iterator> // for GCC 3.2 #include <iterator> // for GCC 3.2
#include <stdexcept> #include <stdexcept>
#include <eoScalarFitness.h> // for specializations #include <eoScalarFitness.h> // for specializations
/** /**
eoParam: Base class for monitoring and parsing parameters eoParam: Base class for monitoring and parsing parameters
*/ */
@ -52,14 +54,14 @@ class eoParam
{ {
public: public:
/** Empty constructor - called from outside any parser /** Empty constructor - called from outside any parser */
*/
eoParam () eoParam ()
: repLongName(""), repDefault(""), repDescription(""), : repLongName(""), repDefault(""), repDescription(""),
repShortHand(0), repRequired(false){} repShortHand(0), repRequired(false)
{}
/** /** Construct a Param.
* Construct a Param. *
* @param _longName Long name of the argument * @param _longName Long name of the argument
* @param _default The default value * @param _default The default value
* @param _description Description of the parameter. What is useful for. * @param _description Description of the parameter. What is useful for.
@ -70,7 +72,8 @@ public:
std::string _description, char _shortName = 0, bool _required = false) std::string _description, char _shortName = 0, bool _required = false)
: repLongName(_longName), repDefault(_default), : repLongName(_longName), repDefault(_default),
repDescription(_description ), repDescription(_description ),
repShortHand(_shortName), repRequired( _required) {} repShortHand(_shortName), repRequired( _required)
{}
/** /**
* Virtual destructor is needed. * Virtual destructor is needed.
@ -80,37 +83,37 @@ public:
/** /**
* Pure virtual function to get the value out. * Pure virtual function to get the value out.
*/ */
virtual std::string getValue ( void ) const = 0; virtual std::string getValue () const = 0;
/** /**
* Pure virtual function to set the value * Pure virtual function to set the value
*/ */
virtual void setValue(std::string _value) = 0 ; virtual void setValue(const std::string& _value) = 0 ;
/** /**
* Returns the short name. * Returns the short name.
*/ */
char shortName ( void ) const { return repShortHand; }; char shortName() const { return repShortHand; };
/** /**
* Returns the long name. * Returns the long name.
*/ */
const std::string& longName ( void ) const { return repLongName; }; const std::string& longName() const { return repLongName; };
/** /**
* Returns the description of the argument * Returns the description of the argument
*/ */
const std::string& description ( void ) const { return repDescription; }; const std::string& description() const { return repDescription; };
/** /**
* Returns the default value of the argument * Returns the default value of the argument
*/ */
const std::string& defValue ( void ) const { return repDefault; }; const std::string& defValue() const { return repDefault; };
/** /**
* Sets the default value of the argument, * Sets the default value of the argument,
*/ */
void defValue ( std::string str ) { repDefault = str; }; void defValue( const std::string& str ) { repDefault = str; };
/** /**
* ALlows to change the name (see the prefix in eoParser.h) * ALlows to change the name (see the prefix in eoParser.h)
@ -120,7 +123,7 @@ public:
/** /**
* Returns if required or not. * Returns if required or not.
*/ */
bool required ( void ) const { return repRequired; }; bool required() const { return repRequired; };
private: private:
std::string repLongName; std::string repLongName;
@ -130,6 +133,8 @@ private:
bool repRequired; bool repRequired;
}; };
/** /**
eoValueParam<ValueType>: templatized derivation of eoParam. Can be used to contain eoValueParam<ValueType>: templatized derivation of eoParam. Can be used to contain
any scalar value type. It makes use of std::strstream to get and set values. This any scalar value type. It makes use of std::strstream to get and set values. This
@ -138,33 +143,49 @@ private:
Note also that there is a template specialization for std::pair<double, double> and Note also that there is a template specialization for std::pair<double, double> and
for std::vector<double>. These stream their contents delimited with whitespace. for std::vector<double>. These stream their contents delimited with whitespace.
*/ */
template <class ValueType> template <class ValueType>
class eoValueParam : public eoParam class eoValueParam : public eoParam
{ {
public : public :
/** Construct a Param. */
eoValueParam(void) : eoParam() {} eoValueParam(void) : eoParam() {}
/** /** Construct a Param.
* Construct a Param. *
* @param _defaultValue The default value * @param _defaultValue The default value
* @param _longName Long name of the argument * @param _longName Long name of the argument
* @param _description Description of the parameter. What is useful for. * @param _description Description of the parameter. What is useful for.
* @param _shortName Short name of the argument (Optional) * @param _shortName Short name of the argument (Optional)
* @param _required If it is a necessary parameter or not * @param _required If it is a necessary parameter or not
*/ */
eoValueParam (ValueType _defaultValue, eoValueParam(ValueType _defaultValue,
std::string _longName, std::string _longName,
std::string _description = "No description", std::string _description = "No description",
char _shortHand = 0, char _shortHand = 0,
bool _required = false) bool _required = false)
: eoParam(_longName, "", _description, _shortHand, _required), repValue(_defaultValue) : eoParam(_longName, "", _description, _shortHand, _required),
repValue(_defaultValue)
{ {
eoParam::defValue(getValue()); eoParam::defValue(getValue());
} }
ValueType& value() { return repValue; } /** Parameter value
ValueType value() const { return repValue; }
@return parameter value
*/
ValueType& value()
{ return repValue; }
/** Parameter value
@overload
@return parameter value
*/
const ValueType& value() const
{ return repValue; }
std::string getValue(void) const std::string getValue(void) const
{ {
@ -180,7 +201,8 @@ public :
return os.str(); return os.str();
} }
void setValue(std::string _value)
void setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -190,7 +212,8 @@ public :
is >> repValue; is >> repValue;
} }
//private : protected:
ValueType repValue; ValueType repValue;
}; };
@ -198,14 +221,14 @@ public :
Specialization for std::string Specialization for std::string
*/ */
template <> template <>
inline std::string eoValueParam<std::string>::getValue(void) const inline std::string eoValueParam<std::string>::getValue() const
{ {
return repValue; return repValue;
} }
template <> template <>
inline void eoValueParam<bool>::setValue(std::string _value) inline void eoValueParam<bool>::setValue(const std::string& _value)
{ {
if (_value.empty()) if (_value.empty())
{ {
@ -239,7 +262,7 @@ inline std::string eoValueParam<std::pair<double, double> >::getValue(void) cons
/// Because MSVC does not support partial specialization, the std::pair is a double, not a T /// Because MSVC does not support partial specialization, the std::pair is a double, not a T
template <> template <>
inline void eoValueParam<std::pair<double, double> >::setValue(std::string _value) inline void eoValueParam<std::pair<double, double> >::setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -276,7 +299,7 @@ inline std::string eoValueParam<std::vector<std::vector<double> > >::getValue(vo
/// Because MSVC does not support partial specialization, the std::vector is a std::vector of doubles, not a T /// Because MSVC does not support partial specialization, the std::vector is a std::vector of doubles, not a T
template <> template <>
inline void eoValueParam<std::vector<std::vector<double> > >::setValue(std::string _value) inline void eoValueParam<std::vector<std::vector<double> > >::setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -320,7 +343,7 @@ inline std::string eoValueParam<std::vector<double> >::getValue(void) const
/// Because MSVC does not support partial specialization, the std::vector is a double, not a T /// Because MSVC does not support partial specialization, the std::vector is a double, not a T
template <> template <>
inline void eoValueParam<std::vector<double> >::setValue(std::string _value) inline void eoValueParam<std::vector<double> >::setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -355,7 +378,7 @@ inline std::string eoValueParam<std::vector<eoMinimizingFitness> >::getValue(voi
/// Because MSVC does not support partial specialization, the std::vector is a eoMinimizingFitness, not a T /// Because MSVC does not support partial specialization, the std::vector is a eoMinimizingFitness, not a T
// NOTE: g++ doesn support it either!!! // NOTE: g++ doesn support it either!!!
template <> template <>
inline void eoValueParam<std::vector<eoMinimizingFitness> >::setValue(std::string _value) inline void eoValueParam<std::vector<eoMinimizingFitness> >::setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -378,16 +401,16 @@ inline std::string eoValueParam<std::vector<void*> >::getValue(void) const
} }
template <> template <>
inline void eoValueParam<std::vector<void*> >::setValue(std::string) inline void eoValueParam<std::vector<void*> >::setValue(const std::string&)
{ {
throw std::runtime_error("I cannot setValue for a std::vector<EOT*>"); throw std::runtime_error("I cannot setValue for a std::vector<EOT*>");
return; return;
} }
/*template <class ContainerType> /*template <class ContainerType>
class eoContainerParam : public eoParam class eoContainerParam : public eoParam
{ {
public : public :
eoContainerParam (ContainerType& value, std::string _shortName, std::string _longName, eoContainerParam (ContainerType& value, std::string _shortName, std::string _longName,
std::string _default, std::string _default,
std::string _description, std::string _description,
@ -403,9 +426,9 @@ public :
// copy(std::istream_iterator<Container::value_type>(is), std::istream_iterator<Container::value_type>(), back_inserter(value)); // copy(std::istream_iterator<Container::value_type>(is), std::istream_iterator<Container::value_type>(), back_inserter(value));
// } // }
private : private :
ContainerType& value; ContainerType& value;
};*/ };*/
/** /**
* Another helper class for parsing parameters like * Another helper class for parsing parameters like

View file

@ -62,8 +62,9 @@ eoParameterLoader::~eoParameterLoader()
} }
eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription, string _lFileParamName, char _shortHand) : eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription,
programName( _argv[0]), string _lFileParamName, char _shortHand) :
programName(_argv[0]),
programDescription( _programDescription), programDescription( _programDescription),
needHelp(false, "help", "Prints this message", 'h'), needHelp(false, "help", "Prints this message", 'h'),
stopOnUnknownParam(true, "stopOnUnknownParam", "Stop if unkown param entered", '\0') stopOnUnknownParam(true, "stopOnUnknownParam", "Stop if unkown param entered", '\0')
@ -73,91 +74,50 @@ eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription,
unsigned i; unsigned i;
for (i = 1; i < _argc; ++i) for (i = 1; i < _argc; ++i)
{ {
if (_argv[i][0] == '@') if(_argv[i][0] == '@')
{ // read response file { // read response file
char *pts = _argv[i]+1; // yes a char*, sorry :-) char *pts = _argv[i]+1; // yes a char*, sorry :-)
ifstream ifs (pts); ifstream ifs (pts);
ifs.peek(); // check if it exists ifs.peek(); // check if it exists
if (!ifs) if (!ifs)
{ {
string msg = (string)("Could not open response file: ") + pts; string msg = string("Could not open response file: ") + pts;
throw runtime_error(msg); throw runtime_error(msg);
} }
// read - will be overwritten by command-line // read - will be overwritten by command-line
readFrom(ifs); readFrom(ifs);
break; // stop reading command line args for '@' break; // stop reading command line args for '@'
} }
} }
// now read arguments on command-line // now read arguments on command-line
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
stringstream stream; stringstream stream;
#else #else
strstream stream; strstream stream;
#endif #endif
for (i = 1; i < _argc; ++i) for (i = 1; i < _argc; ++i)
{ {
stream << _argv[i] << '\n'; stream << _argv[i] << '\n';
} }
readFrom(stream); readFrom(stream);
processParam(needHelp); processParam(needHelp);
processParam(stopOnUnknownParam); processParam(stopOnUnknownParam);
} }
/**
* get a handle on a param from its longName
* eoParam * eoParser::getParamWithLongName(const std::string& _name) const
* if not found, returns 0 (null pointer :-)
*
* Not very clean (requires hard-coding of the long name twice!)
* but very useful in many occasions...
*/
eoParam* eoParser::getParamWithLongName(std::string _name)
{ {
typedef std::multimap<std::string, eoParam*> MultiMapType; typedef std::multimap<std::string, eoParam*> MultiMapType;
typedef MultiMapType::const_iterator It; typedef MultiMapType::const_iterator iter;
for (It p = params.begin(); p != params.end(); ++p) std::string search(prefix+_name);
{ for(iter p = params.begin(); p != params.end(); ++p)
if (p->second->longName() == prefix+_name) if(p->second->longName() == search)
return p->second; return p->second;
}
return 0; return 0;
} }
/** it seems finally that the easiest use of the above method is
through the following, whose interface is similar to that of the
widely-used createParam
For some (probably very stupid) reason, I failed to put it in
the .cpp. Any hint???
*/
/*
template <class ValueType>
eoValueParam<ValueType>& eoParser::getORcreateParam (
ValueType _defaultValue,
std::string _longName,
std::string _description,
char _shortHand,
std::string _section,
bool _required)
{
eoParam* ptParam = getParamWithLongName(_longName);
if (ptParam) { // found
eoValueParam<ValueType>* ptTypedParam =
dynamic_cast<eoValueParam<ValueType>*>(ptParam);
return *ptTypedParam;
}
// not found -> create it
return createParam (_defaultValue, _longName, _description,
_shortHand, _section, _required);
}
*/
void eoParser::processParam(eoParam& param, std::string section) void eoParser::processParam(eoParam& param, std::string section)
{ {

View file

@ -24,12 +24,13 @@
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** /**
CVS Info: $Date: 2004-04-05 15:28:12 $ $Version$ $Author: evomarc $ CVS Info: $Date: 2005-08-29 07:50:50 $ $Version$ $Author: kuepper $
*/ */
#ifndef eoParser_h #ifndef eoParser_h
#define eoParser_h #define eoParser_h
#include <map> #include <map>
#include <sstream>
#include <string> #include <string>
#include "eoParam.h" #include "eoParam.h"
@ -80,21 +81,25 @@ public :
std::string _section = "", std::string _section = "",
bool _required = false) bool _required = false)
{ {
eoValueParam<ValueType>* p = new eoValueParam<ValueType>(_defaultValue, _longName, _description, _shortHand, _required); eoValueParam<ValueType>* p = new eoValueParam<ValueType>(_defaultValue,
_longName,
_description,
_shortHand,
_required);
ownedParams.push_back(p); ownedParams.push_back(p);
processParam(*p, _section); processParam(*p, _section);
return *p; return *p;
} }
private : private :
std::vector<eoParam*> ownedParams; std::vector<eoParam*> ownedParams;
}; };
/** /**
eoParser: command line parser and configuration file reader eoParser: command line parser and configuration file reader
This class is persistent, so it can be stored and reloaded to restore This class is persistent, so it can be stored and reloaded to restore
@ -109,6 +114,7 @@ public:
* Constructor * Constructor
* a complete constructor that reads the command line an optionally reads * a complete constructor that reads the command line an optionally reads
* a configuration file. * a configuration file.
* *
* myEo --param-file=param.rc will then load using the parameter file param.rc * myEo --param-file=param.rc will then load using the parameter file param.rc
* *
@ -149,7 +155,7 @@ public:
virtual bool isItThere(eoParam& _param) const virtual bool isItThere(eoParam& _param) const
{ return getValue(_param).first; } { return getValue(_param).first; }
/** /**
* get a handle on a param from its longName * get a handle on a param from its longName
* *
* if not found, returns 0 (null pointer :-) * if not found, returns 0 (null pointer :-)
@ -157,25 +163,30 @@ public:
* Not very clean (requires hard-coding of the long name twice!) * Not very clean (requires hard-coding of the long name twice!)
* but very useful in many occasions... * but very useful in many occasions...
*/ */
eoParam* getParamWithLongName(std::string _name); eoParam * getParamWithLongName(const std::string& _name) const;
/** it seems finally that the easiest use of the above method is
/** Get or create parameter
It seems finally that the easiest use of the above method is
through the following, whose interface is similar to that of the through the following, whose interface is similar to that of the
widely-used createParam widely-used createParam.
For some (probably very stupid) reason, I failed to put it in
the .cpp. Any hint??? For some (probably very stupid) reason, I failed to put it in the
.cpp. Any hint???
*/ */
template <class ValueType> template <class ValueType>
eoValueParam<ValueType>& getORcreateParam eoValueParam<ValueType>& getORcreateParam(ValueType _defaultValue,
(ValueType _defaultValue,
std::string _longName, std::string _longName,
std::string _description, std::string _description,
char _shortHand = 0, char _shortHand = 0,
std::string _section = "", std::string _section = "",
bool _required = false) bool _required = false)
{ {
eoParam* ptParam = getParamWithLongName(_longName); eoParam* ptParam = getParamWithLongName(_longName);
if (ptParam) { // found if (ptParam) {
// found
eoValueParam<ValueType>* ptTypedParam = eoValueParam<ValueType>* ptTypedParam =
dynamic_cast<eoValueParam<ValueType>*>(ptParam); dynamic_cast<eoValueParam<ValueType>*>(ptParam);
return *ptTypedParam; return *ptTypedParam;
@ -183,9 +194,37 @@ public:
// not found -> create it // not found -> create it
return createParam (_defaultValue, _longName, _description, return createParam (_defaultValue, _longName, _description,
_shortHand, _section, _required); _shortHand, _section, _required);
} }
// /** accessors to the stopOnUnknownParam value */
/** Make sure parameter has specific value
This requires that operator<< is defined for ValueType.
*/
template <class ValueType>
void setORcreateParam(ValueType _defaultValue, std::string _longName,
std::string _description, char _shortHand = 0,
std::string _section = "", bool _required = false)
{
eoParam *param = getParamWithLongName(_longName);
if(0 == param) {
createParam(_defaultValue, _longName, _description,
_shortHand, _section, _required);
} else {
#ifdef HAVE_SSTREAM
std::ostringstream os;
#else
std::ostrstream os;
#endif
os << _defaultValue;
dynamic_cast<eoValueParam<int> *>(param)->setValue(os.str());
}
}
/** accessors to the stopOnUnknownParam value */
void setStopOnUnknownParam(bool _b) {stopOnUnknownParam.value()=_b;} void setStopOnUnknownParam(bool _b) {stopOnUnknownParam.value()=_b;}
bool getStopOnUnknownParam() {return stopOnUnknownParam.value();} bool getStopOnUnknownParam() {return stopOnUnknownParam.value();}