delete *i;
}
-GetOpt::OptBase &GetOpt::add_option(OptBase *opt)
+GetOpt::OptionImpl &GetOpt::add_option(char s, const string &l, const Store &t, ArgType a)
{
+ if(l.empty())
+ throw invalid_argument("GetOpt::add_option");
+
for(OptionList::iterator i=opts.begin(); i!=opts.end(); )
{
- if((opt->get_short()!=0 && (*i)->get_short()==opt->get_short()) || (*i)->get_long()==opt->get_long())
+ if((s!=0 && (*i)->get_short()==s) || (*i)->get_long()==l)
{
delete *i;
opts.erase(i++);
++i;
}
- opts.push_back(opt);
+ opts.push_back(new OptionImpl(s, l, t, a));
return *opts.back();
}
-GetOpt::OptBase &GetOpt::get_option(char s)
+GetOpt::OptionImpl &GetOpt::get_option(char s)
{
for(OptionList::iterator i=opts.begin(); i!=opts.end(); ++i)
if((*i)->get_short()==s)
throw usage_error(string("Unknown option -")+s);
}
-GetOpt::OptBase &GetOpt::get_option(const string &l)
+GetOpt::OptionImpl &GetOpt::get_option(const string &l)
{
for(OptionList::iterator i=opts.begin(); i!=opts.end(); ++i)
if((*i)->get_long()==l)
unsigned equals = 0;
for(; arg[equals] && arg[equals]!='='; ++equals) ;
- OptBase &opt = get_option(string(arg, equals));
+ OptionImpl &opt = get_option(string(arg, equals));
if(arg[equals])
// Process the part after the = as option argument
// Loop through all characters in the argument
for(; *arg; ++arg)
{
- OptBase &opt = get_option(*arg);
+ OptionImpl &opt = get_option(*arg);
if(arg[1] && opt.get_arg_type()!=NO_ARG)
{
}
-GetOpt::OptBase::OptBase(char s, const std::string &l, ArgType a):
+GetOpt::OptionImpl::OptionImpl(char s, const std::string &l, const Store &t, ArgType a):
shrt(s),
lng(l),
arg_type(a),
seen_count(0),
ext_seen_count(0),
- metavar("ARG")
+ metavar("ARG"),
+ store(t.clone())
+{ }
+
+GetOpt::OptionImpl::~OptionImpl()
{
- if(lng.empty())
- throw invalid_argument("empty long option name");
+ delete store;
}
-GetOpt::OptBase &GetOpt::OptBase::set_help(const string &h)
+GetOpt::OptionImpl &GetOpt::OptionImpl::set_help(const string &h)
{
help = h;
return *this;
}
-GetOpt::OptBase &GetOpt::OptBase::set_help(const string &h, const string &m)
+GetOpt::OptionImpl &GetOpt::OptionImpl::set_help(const string &h, const string &m)
{
help = h;
metavar = m;
return *this;
}
-GetOpt::OptBase &GetOpt::OptBase::bind_seen_count(unsigned &c)
+GetOpt::OptionImpl &GetOpt::OptionImpl::bind_seen_count(unsigned &c)
{
ext_seen_count = &c;
return *this;
}
-void GetOpt::OptBase::process()
+void GetOpt::OptionImpl::process()
{
if(arg_type==REQUIRED_ARG)
throw usage_error("--"+lng+" requires an argument");
try
{
- store();
+ store->store();
}
catch(const exception &e)
{
}
}
-void GetOpt::OptBase::process(const string &arg)
+void GetOpt::OptionImpl::process(const string &arg)
{
if(arg_type==NO_ARG)
throw usage_error("--"+lng+" takes no argument");
try
{
- store(arg);
+ store->store(arg);
}
catch(const exception &e)
{
};
private:
- class OptBase: public Option
+ class Store
+ {
+ protected:
+ Store() { }
+ public:
+ virtual ~Store() { }
+
+ virtual Store *clone() const = 0;
+
+ virtual void store() = 0;
+ virtual void store(const std::string &) = 0;
+ };
+
+ class OptionImpl: public Option
{
protected:
char shrt;
unsigned *ext_seen_count;
std::string help;
std::string metavar;
+ Store *store;
- OptBase(char, const std::string &, ArgType);
public:
- virtual ~OptBase() { }
+ OptionImpl(char, const std::string &, const Store &, ArgType);
+ virtual ~OptionImpl();
- virtual OptBase &set_help(const std::string &);
- virtual OptBase &set_help(const std::string &, const std::string &);
- virtual OptBase &bind_seen_count(unsigned &);
+ virtual OptionImpl &set_help(const std::string &);
+ virtual OptionImpl &set_help(const std::string &, const std::string &);
+ virtual OptionImpl &bind_seen_count(unsigned &);
char get_short() const { return shrt; }
const std::string &get_long() const { return lng; }
ArgType get_arg_type() const { return arg_type; }
virtual unsigned get_seen_count() const { return seen_count; }
void process();
void process(const std::string &);
- protected:
- virtual void store() = 0;
- virtual void store(const std::string &) = 0;
};
template<typename T>
- class SimpleOption: public OptBase
+ class SimpleStore: public Store
{
private:
T &data;
public:
- SimpleOption(char s, const std::string &l, T &d, ArgType a): OptBase(s, l, a), data(d) { }
+ SimpleStore(T &d): data(d) { }
+
+ virtual SimpleStore *clone() const
+ { return new SimpleStore(data); }
virtual void store() { }
};
template<typename T>
- class ListOption: public OptBase
+ class ListStore: public Store
{
private:
T &data;
public:
- ListOption(char s, const std::string &l, T &d, ArgType a): OptBase(s, l, a), data(d)
- { if(arg_type!=REQUIRED_ARG) throw std::invalid_argument("ListOption arg_type!=REQUIRED"); }
+ ListStore(T &d): data(d) { }
+
+ virtual ListStore *clone() const
+ { return new ListStore(data); }
virtual void store() { }
{ data.push_back(lexical_cast<typename T::value_type>(a)); }
};
- typedef std::list<OptBase *> OptionList;
+ typedef std::list<OptionImpl *> OptionList;
bool help;
OptionList opts;
and an unsigned will be incremented; any other type will be ignored. */
template<typename T>
Option &add_option(char s, const std::string &l, T &d, ArgType a = NO_ARG)
- { return add_option(new SimpleOption<T>(s, l, d, a)); }
+ { return add_option(s, l, SimpleStore<T>(d), a); }
/** Adds an option with both short and long forms. The option may be
specified multiple times, and the argument from each occurrence is stored in
the list. The argument type must be REQUIRED_ARG. */
template<typename T>
Option &add_option(char s, const std::string &l, std::list<T> &d, ArgType a = REQUIRED_ARG)
- { return add_option(new ListOption<std::list<T> >(s, l, d, a)); }
+ { return add_option(s, l, ListStore<std::list<T> >(d), a); }
/** Adds an option with only a long form. */
template<typename T>
{ return add_option(0, l, d, a); }
private:
- OptBase &add_option(OptBase *);
+ OptionImpl &add_option(char, const std::string &, const Store &, ArgType);
- OptBase &get_option(char);
- OptBase &get_option(const std::string &);
+ OptionImpl &get_option(char);
+ OptionImpl &get_option(const std::string &);
public:
/** Processes argc/argv style command line arguments. The contents of argv
std::string generate_help() const;
};
-template<> inline void GetOpt::SimpleOption<bool>::store()
+template<> inline void GetOpt::SimpleStore<bool>::store()
{ data = true; }
-template<> inline void GetOpt::SimpleOption<unsigned>::store()
+template<> inline void GetOpt::SimpleStore<unsigned>::store()
{ ++data; }
-template<> inline void GetOpt::SimpleOption<std::string>::store(const std::string &a)
+template<> inline void GetOpt::SimpleStore<std::string>::store(const std::string &a)
{ data = a; }
-template<> inline void GetOpt::ListOption<std::list<std::string> >::store(const std::string &a)
+template<> inline void GetOpt::ListStore<std::list<std::string> >::store(const std::string &a)
{ data.push_back(a); }
} // namespace Msp