]> git.tdb.fi Git - libs/core.git/blobdiff - source/core/getopt.h
Restructure internals of GetOpt
[libs/core.git] / source / core / getopt.h
index 53c9ddf2f0100681099df40466e125914e5e74b3..911934ac08adb7399bbd914b6778a8df8eb99f03 100644 (file)
@@ -79,7 +79,20 @@ public:
        };
 
 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;
@@ -89,14 +102,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 +119,19 @@ 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 void store() { }
 
@@ -126,14 +140,16 @@ 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 void store() { }
 
@@ -141,8 +157,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 +177,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 +192,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 +218,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