]> git.tdb.fi Git - libs/core.git/blobdiff - source/core/getopt.h
Restore the check that list options must take an argument
[libs/core.git] / source / core / getopt.h
index 53c9ddf2f0100681099df40466e125914e5e74b3..70841cbf6b8dc50da4800bfae42ebc78e6d7e122 100644 (file)
@@ -79,7 +79,21 @@ public:
        };
 
 private:
-       class OptBase: public Option
+       class Store
+       {
+       protected:
+               Store() { }
+       public:
+               virtual ~Store() { }
+
+               virtual Store *clone() const = 0;
+
+               virtual bool is_list() const = 0;
+               virtual void store() = 0;
+               virtual void store(const std::string &) = 0;
+       };
+
+       class OptionImpl: public Option
        {
        protected:
                char shrt;
@@ -89,14 +103,15 @@ private:
                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; }
@@ -105,19 +120,21 @@ private:
                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 bool is_list() const { return false; }
 
                virtual void store() { }
 
@@ -126,14 +143,18 @@ private:
        };
 
        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 bool is_list() const { return true; }
 
                virtual void store() { }
 
@@ -141,8 +162,10 @@ private:
                { data.push_back(lexical_cast<typename T::value_type>(a)); }
        };
 
+       typedef std::list<OptionImpl *> OptionList;
+
        bool help;
-       std::list<OptBase *> opts;
+       OptionList opts;
        std::vector<std::string> args;
 
 public:
@@ -159,14 +182,14 @@ public:
        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>
@@ -174,10 +197,10 @@ public:
        { 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
@@ -200,16 +223,16 @@ public:
        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