Program Listing for File value_arg.hpp
↰ Return to documentation for file (include/ecl/command_line/value_arg.hpp
)
/*****************************************************************************
** Ifdefs
*****************************************************************************/
#ifndef TCLAP_VALUE_ARGUMENT_H
#define TCLAP_VALUE_ARGUMENT_H
#include <string>
#include <vector>
#include <cstdio>
#include "arg.hpp"
#include "constraint.hpp"
#define HAVE_SSTREAM
#if defined(HAVE_SSTREAM)
#include <sstream>
#elif defined(HAVE_STRSTREAM)
#include <strstream>
#else
#error "Need a stringstream (sstream or strstream) to compile!"
#endif
namespace ecl {
template<class T> class ValueArg;
namespace ValueArgHelper {
enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY };
template<class T> class ValueExtractor
{
friend class ValueArg<T>;
private:
T &_value;
ValueExtractor(T &value) : _value(value) { }
int extractValue( const std::string& val )
{
#if defined(HAVE_SSTREAM)
std::istringstream is(val);
#elif defined(HAVE_STRSTREAM)
std::istrstream is(val.c_str());
#else
#error "Need a stringstream (sstream or strstream) to compile!"
#endif
int valuesRead = 0;
while ( is.good() )
{
if ( is.peek() != EOF )
is >> _value;
else
break;
valuesRead++;
}
if ( is.fail() )
return EXTRACT_FAILURE;
if ( valuesRead > 1 )
return EXTRACT_TOO_MANY;
return 0;
}
};
template<> class ValueExtractor<std::string>
{
friend class ValueArg<std::string>;
private:
std::string &_value;
ValueExtractor(std::string &value) : _value(value) {}
int extractValue( const std::string& val )
{
_value = val;
return 0;
}
};
} //namespace ValueArgHelper
template<class T>
class ValueArg : public Arg
{
protected:
T _value;
std::string _typeDesc;
Constraint<T>* _constraint;
void _extractValue( const std::string& val );
public:
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
Visitor* v = NULL);
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
CmdLineInterface& parser,
Visitor* v = NULL );
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
CmdLineInterface& parser,
Visitor* v = NULL );
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
Visitor* v = NULL );
virtual bool processArg(int* i, std::vector<std::string>& args);
T& getValue() ;
virtual std::string shortID(const std::string& val = "val") const;
virtual std::string longID(const std::string& val = "val") const;
};
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( value ),
_typeDesc( typeDesc ),
_constraint( NULL )
{ }
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
CmdLineInterface& parser,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( val ),
_typeDesc( typeDesc ),
_constraint( NULL )
{
parser.add( this );
}
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( val ),
_typeDesc( constraint->shortID() ),
_constraint( constraint )
{ }
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
CmdLineInterface& parser,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( val ),
_typeDesc( constraint->shortID() ),
_constraint( constraint )
{
parser.add( this );
}
template<class T>
T& ValueArg<T>::getValue() { return _value; }
template<class T>
bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _ignoreable && Arg::ignoreRest() )
return false;
if ( _hasBlanks( args[*i] ) )
return false;
std::string flag = args[*i];
std::string value = "";
trimFlag( flag, value );
if ( argMatches( flag ) )
{
if ( _alreadySet )
throw( CmdLineParseException("Argument already set!", toString()) );
if ( Arg::delimiter() != ' ' && value == "" )
throw( ArgParseException(
"Couldn't find delimiter for this argument!",
toString() ) );
if ( value == "" )
{
(*i)++;
if ( static_cast<unsigned int>(*i) < args.size() )
_extractValue( args[*i] );
else
throw( ArgParseException("Missing a value for this argument!",
toString() ) );
}
else
_extractValue( value );
_alreadySet = true;
_checkWithVisitor();
return true;
}
else
return false;
}
template<class T>
std::string ValueArg<T>::shortID(const std::string& val) const
{
std::string stop_warnings = val; // Only to stop annoying warning messages, I dont think it slows things down
return Arg::shortID( _typeDesc );
}
template<class T>
std::string ValueArg<T>::longID(const std::string& val) const
{
std::string stop_warnings = val; // Only to stop annoying warning messages, I dont think it slows things down
return Arg::longID( _typeDesc );
}
template<class T> // Just to stop the warnings.
void ValueArg<T>::_extractValue( const std::string& val )
{
ValueArgHelper::ValueExtractor<T> ve(_value);
int err = ve.extractValue(val);
if ( err == ValueArgHelper::EXTRACT_FAILURE )
throw( ArgParseException("Couldn't read argument value from string '" +
val + "'", toString() ) );
if ( err == ValueArgHelper::EXTRACT_TOO_MANY )
throw( ArgParseException(
"More than one valid value parsed from string '" +
val + "'", toString() ) );
if ( _constraint != NULL )
if ( ! _constraint->check( _value ) )
throw( CmdLineParseException( "Value '" + val +
"' does not meet constraint: " +
_constraint->description(),
toString() ) );
}
} // namespace ecl
#endif