refactored command line parser, fixed the docs
authorVadim Pisarevsky <vadim.pisarevsky@itseez.com>
Fri, 7 Sep 2012 13:44:01 +0000 (17:44 +0400)
committerVadim Pisarevsky <vadim.pisarevsky@itseez.com>
Fri, 7 Sep 2012 13:44:01 +0000 (17:44 +0400)
modules/core/doc/command_line_parser.rst
modules/core/include/opencv2/core/core.hpp
modules/core/src/command_line_parser.cpp

index 5f0e512..c54e65b 100644 (file)
@@ -58,15 +58,15 @@ The sample below demonstrates how to use CommandLineParser:
     }
 
     int N = parser.get<int>("N");
-    double fps = parser.get<double>parser("fps");
+    double fps = parser.get<double>("fps");
     std::string path = parser.get<std::string>("path");
 
-    use_time_stamp = parserer.has("timestamp");
+    use_time_stamp = parser.has("timestamp");
 
-    std::string img1 = parser.get<string>(1);
-    std::string img2 = parser.get<string>(2);
+    std::string img1 = parser.get<string>(0);
+    std::string img2 = parser.get<string>(1);
 
-    int repeat = parser.get<int>(3);
+    int repeat = parser.get<int>(2);
 
     if (!parser.check())
     {
index 2496c80..44941af 100644 (file)
@@ -221,7 +221,7 @@ CV_EXPORTS void setNumThreads(int nthreads);
 CV_EXPORTS int getNumThreads();
 CV_EXPORTS int getThreadNum();
 
-CV_EXPORTS_W const std::string& getBuildInformation();
+CV_EXPORTS_W const string& getBuildInformation();
 
 //! Returns the number of ticks.
 
@@ -4434,7 +4434,7 @@ protected:
 
 struct CV_EXPORTS Param
 {
-    enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6 };
+    enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, UNSIGNED_INT=8, UINT64=9 };
 
     Param();
     Param(int _type, bool _readonly, int _offset,
@@ -4505,142 +4505,73 @@ template<> struct ParamType<Algorithm>
     enum { type = Param::ALGORITHM };
 };
 
-// The CommandLineParser class is designed for command line arguments parsing
-
-class CV_EXPORTS CommandLineParserParams
+template<> struct ParamType<float>
 {
-    public:
-        std::string help_message;
-        std::string def_value;
-        std::vector<std::string> keys;
-        int number;
+    typedef float const_param_type;
+    typedef float member_type;
+    
+    enum { type = Param::FLOAT };
 };
-
-template <typename T>
-std::string get_type_name() { return "UNKNOW"; }
-
-bool cmp_params(const CommandLineParserParams & p1, const CommandLineParserParams & p2);
-
-template<typename T>
-T from_str(const std::string & str)
+    
+template<> struct ParamType<unsigned>
 {
-    T value;
-    std::stringstream ss(str);
-    ss >> value;
-
-    if (ss.fail())
-    {
-        std::string err_msg =
-                std::string("can not convert: [")
-                + str
-                + std::string("] to [")
-                + get_type_name<T>()
-                + std::string("]");
-
-        CV_Error(CV_StsBadArg, err_msg);
-    }
+    typedef unsigned const_param_type;
+    typedef unsigned member_type;
+    
+    enum { type = Param::UNSIGNED_INT };
+};
 
-    return value;
-}
+template<> struct ParamType<uint64>
+{
+    typedef uint64 const_param_type;
+    typedef uint64 member_type;
+    
+    enum { type = Param::UINT64 };
+};
 
-template<> std::string from_str(const std::string & str);
 
-template<typename T>
-std::string to_str(T value)
-{
-    std::ostringstream os;
-    os << value;
-    return os.str();
-}
+// The CommandLineParser class is designed for command line arguments parsing
 
 class CV_EXPORTS CommandLineParser
 {
-    public:
-        CommandLineParser(int argc, const char * const argv[], const std::string keys);
-
-        std::string getPathToApplication();
-
-        template <typename T>
-        T get(const std::string& name, bool space_delete = true)
-        {
-            try
-            {
-                for (size_t i = 0; i < data.size(); i++)
-                {
-                    for (size_t j = 0; j < data[i].keys.size(); j++)
-                    {
-                        if (name.compare(data[i].keys[j]) == 0)
-                        {
-                            std::string v = data[i].def_value;
-                            if (space_delete == true) v = cat_string(v);
-                            return from_str<T>(v);
-                        }
-                    }
-                }
-                error = true;
-                error_message += "Unknown parametes " + name + "\n";
-            }
-            catch (std::exception& e)
-            {
-                error = true;
-                error_message += "Exception: " + std::string(e.what()) + "\n";
-            }
-            return T();
-        }
-
-        template <typename T>
-        T get(int index, bool space_delete = true)
-        {
-            try
-            {
-                for (size_t i = 0; i < data.size(); i++)
-                {
-                    if (data[i].number == index - 1)
-                    {
-                        std::string v = data[i].def_value;
-                        if (space_delete == true) v = cat_string(v);
-                        return from_str<T>(v);
-                    }
-                }
-                error = true;
-                error_message += "Unknown parametes #" + to_str<int>(index) + "\n";
-            }
-            catch(std::exception & e)
-            {
-                error = true;
-                error_message += "Exception: " + std::string(e.what()) + "\n";
-            }
-            return T();
-        }
-
-        bool has(const std::string& name);
-
-        bool check();
-
-        void about(std::string message);
-
-        void printMessage();
-        void printErrors();
-
-    protected:
-        bool error;
-        std::string error_message;
-        std::string about_message;
-
-        std::string path_to_app;
-        std::string app_name;
-
-        std::vector<CommandLineParserParams> data;
+public:
+    CommandLineParser(int argc, const char* const argv[], const string& keys);
+    CommandLineParser(const CommandLineParser& parser);
+    CommandLineParser& operator = (const CommandLineParser& parser);
 
-        std::vector<std::string> split_range_string(std::string str, char fs, char ss);
-        std::vector<std::string> split_string(std::string str, char symbol = ' ', bool create_empty_item = false);
-        std::string cat_string(std::string str);
+    string getPathToApplication() const;
 
-        void apply_params(std::string key, std::string value);
-        void apply_params(int i, std::string value);
+    template <typename T>
+    T get(const string& name, bool space_delete = true) const
+    {
+        T val = T();
+        getByName(name, space_delete, ParamType<T>::type, (void*)&val);
+        return val;
+    }
 
-        void sort_params();
+    template <typename T>
+    T get(int index, bool space_delete = true) const
+    {
+        T val = T();
+        getByIndex(index, space_delete, ParamType<T>::type, (void*)&val);
+        return val;
+    }
+    
+    bool has(const string& name) const;
+    
+    bool check() const;
+    
+    void about(const string& message);
+    
+    void printMessage() const;
+    void printErrors() const;
 
+protected:
+    void getByName(const string& name, bool space_delete, int type, void* dst) const;
+    void getByIndex(int index, bool space_delete, int type, void* dst) const;
+    
+    struct Impl;
+    Impl* impl;
 };
 
 /////////////////////////////// Parallel Primitives //////////////////////////////////
index dc137e7..8cfeaf3 100644 (file)
 \r
 namespace cv\r
 {\r
-    bool cmp_params(const CommandLineParserParams & p1, const CommandLineParserParams & p2)\r
+    \r
+struct CommandLineParserParams\r
+{\r
+public:\r
+    string help_message;\r
+    string def_value;\r
+    vector<string> keys;\r
+    int number;\r
+};\r
+    \r
+\r
+struct CommandLineParser::Impl\r
+{\r
+    bool error;\r
+    string error_message;\r
+    string about_message;\r
+    \r
+    string path_to_app;\r
+    string app_name;\r
+    \r
+    vector<CommandLineParserParams> data;\r
+    \r
+    vector<string> split_range_string(const string& str, char fs, char ss) const;\r
+    vector<string> split_string(const string& str, char symbol = ' ', bool create_empty_item = false) const;\r
+    string cat_string(const string& str) const;\r
+    \r
+    void apply_params(const string& key, const string& value);\r
+    void apply_params(int i, string value);\r
+    \r
+    void sort_params();\r
+    int refcount;\r
+};\r
+\r
+    \r
+static string get_type_name(int type)\r
+{\r
+    if( type == Param::INT )\r
+        return "int";\r
+    if( type == Param::UNSIGNED_INT )\r
+        return "unsigned";\r
+    if( type == Param::UINT64 )\r
+        return "unsigned long long";\r
+    if( type == Param::FLOAT )\r
+        return "float";\r
+    if( type == Param::REAL )\r
+        return "double";\r
+    if( type == Param::STRING )\r
+        return "string";\r
+    return "unknown";\r
+}\r
+    \r
+static void from_str(const string& str, int type, void* dst)\r
+{\r
+    std::stringstream ss(str);\r
+    if( type == Param::INT )\r
+        ss >> *(int*)dst;\r
+    else if( type == Param::UNSIGNED_INT )\r
+        ss >> *(unsigned*)dst;\r
+    else if( type == Param::UINT64 )\r
+        ss >> *(uint64*)dst;\r
+    else if( type == Param::FLOAT )\r
+        ss >> *(float*)dst;\r
+    else if( type == Param::REAL )\r
+        ss >> *(double*)dst;\r
+    else if( type == Param::STRING )\r
+        ss >> *(string*)dst;\r
+    \r
+    if (ss.fail())\r
     {\r
-        if (p1.number > p2.number)\r
-            return false;\r
+        string err_msg = "can not convert: [" + str +\r
+        + "] to [" + get_type_name(type) + "]";\r
+        \r
+        CV_Error(CV_StsBadArg, err_msg);\r
+    }\r
+}\r
 \r
-        if (p1.number == -1 && p2.number == -1)\r
+void CommandLineParser::getByName(const string& name, bool space_delete, int type, void* dst) const\r
+{\r
+    try\r
+    {\r
+        for (size_t i = 0; i < impl->data.size(); i++)\r
         {\r
-            if (p1.keys[0].compare(p2.keys[0]) > 0)\r
+            for (size_t j = 0; j < impl->data[i].keys.size(); j++)\r
             {\r
-                return false;\r
+                if (name.compare(impl->data[i].keys[j]) == 0)\r
+                {\r
+                    string v = impl->data[i].def_value;\r
+                    if (space_delete)\r
+                        v = impl->cat_string(v);\r
+                    from_str(v, type, dst);\r
+                    return;\r
+                }\r
             }\r
         }\r
-\r
-        return true;\r
+        impl->error = true;\r
+        impl->error_message += "Unknown parametes " + name + "\n";\r
     }\r
+    catch (std::exception& e)\r
+    {\r
+        impl->error = true;\r
+        impl->error_message += "Exception: " + string(e.what()) + "\n";\r
+    }\r
+}\r
 \r
-    CommandLineParser::CommandLineParser(int argc, const char * const argv[], const std::string keys)\r
+\r
+void CommandLineParser::getByIndex(int index, bool space_delete, int type, void* dst) const\r
+{\r
+    try\r
     {\r
-        // path to application\r
-        size_t pos_s = std::string(argv[0]).find_last_of("/\\");\r
-        if (pos_s == std::string::npos)\r
+        for (size_t i = 0; i < impl->data.size(); i++)\r
         {\r
-            path_to_app = "";\r
-            app_name = std::string(argv[0]);\r
+            if (impl->data[i].number == index)\r
+            {\r
+                string v = impl->data[i].def_value;\r
+                if (space_delete == true) v = impl->cat_string(v);\r
+                from_str(v, type, dst);\r
+                return;\r
+            }\r
         }\r
-        else\r
+        impl->error = true;\r
+        impl->error_message += "Unknown parametes #" + format("%d", index) + "\n";\r
+    }\r
+    catch(std::exception & e)\r
+    {\r
+        impl->error = true;\r
+        impl->error_message += "Exception: " + string(e.what()) + "\n";\r
+    }\r
+}\r
+\r
+static bool cmp_params(const CommandLineParserParams & p1, const CommandLineParserParams & p2)\r
+{\r
+    if (p1.number > p2.number)\r
+        return false;\r
+\r
+    if (p1.number == -1 && p2.number == -1)\r
+    {\r
+        if (p1.keys[0].compare(p2.keys[0]) > 0)\r
         {\r
-            path_to_app = std::string(argv[0]).substr(0, pos_s);\r
-            app_name = std::string(argv[0]).substr(pos_s + 1, std::string(argv[0]).length() - pos_s);\r
+            return false;\r
         }\r
+    }\r
 \r
-        error = false;\r
-        error_message = "";\r
+    return true;\r
+}\r
 \r
-        // parse keys\r
-        std::vector<std::string> k = split_range_string(keys, '{', '}');\r
+CommandLineParser::CommandLineParser(int argc, const char* const argv[], const string& keys)\r
+{\r
+    impl = new Impl;\r
+    impl->refcount = 1;\r
+    \r
+    // path to application\r
+    size_t pos_s = string(argv[0]).find_last_of("/\\");\r
+    if (pos_s == string::npos)\r
+    {\r
+        impl->path_to_app = "";\r
+        impl->app_name = string(argv[0]);\r
+    }\r
+    else\r
+    {\r
+        impl->path_to_app = string(argv[0]).substr(0, pos_s);\r
+        impl->app_name = string(argv[0]).substr(pos_s + 1, string(argv[0]).length() - pos_s);\r
+    }\r
 \r
-        int jj = 0;\r
-        for (size_t i = 0; i < k.size(); i++)\r
-        {\r
-            std::vector<std::string> l = split_string(k[i], '|', true);\r
-            CommandLineParserParams p;\r
-            p.keys = split_string(l[0]);\r
-            p.def_value = l[1];\r
-            p.help_message = cat_string(l[2]);\r
-            p.number = -1;\r
-            if (p.keys[0][0] == '@')\r
-            {\r
-                p.number = jj;\r
-                jj++;\r
-            }\r
+    impl->error = false;\r
+    impl->error_message = "";\r
 \r
-            data.push_back(p);\r
-        }\r
+    // parse keys\r
+    vector<string> k = impl->split_range_string(keys, '{', '}');\r
 \r
-        // parse argv\r
-        jj = 0;\r
-        for (int i = 1; i < argc; i++)\r
+    int jj = 0;\r
+    for (size_t i = 0; i < k.size(); i++)\r
+    {\r
+        vector<string> l = impl->split_string(k[i], '|', true);\r
+        CommandLineParserParams p;\r
+        p.keys = impl->split_string(l[0]);\r
+        p.def_value = l[1];\r
+        p.help_message = impl->cat_string(l[2]);\r
+        p.number = -1;\r
+        if (p.keys[0][0] == '@')\r
         {\r
-            std::string s = std::string(argv[i]);\r
-\r
-            if (s.find('=') != std::string::npos && s.find('=') < s.length())\r
-            {\r
-                std::vector<std::string> k_v = split_string(s, '=', true);\r
-                for (int h = 0; h < 2; h++)\r
-                {\r
-                    if (k_v[0][0] == '-')\r
-                        k_v[0] = k_v[0].substr(1, k_v[0].length() -1);\r
-                }\r
-                apply_params(k_v[0], k_v[1]);\r
-            }\r
-            else if (s.length() > 1 && s[0] == '-')\r
-            {\r
-                for (int h = 0; h < 2; h++)\r
-                {\r
-                    if (s[0] == '-')\r
-                        s = s.substr(1, s.length() - 1);\r
-                }\r
-                apply_params(s, "true");\r
-            }\r
-            else if (s[0] != '-')\r
-            {\r
-                apply_params(jj, s);\r
-                jj++;\r
-            }\r
+            p.number = jj;\r
+            jj++;\r
         }\r
 \r
-        sort_params();\r
+        impl->data.push_back(p);\r
     }\r
 \r
-    void CommandLineParser::about(std::string message)\r
+    // parse argv\r
+    jj = 0;\r
+    for (int i = 1; i < argc; i++)\r
     {\r
-        about_message = message;\r
-    }\r
+        string s = string(argv[i]);\r
 \r
-    void CommandLineParser::apply_params(std::string key, std::string value)\r
-    {\r
-        for (size_t i = 0; i < data.size(); i++)\r
+        if (s.find('=') != string::npos && s.find('=') < s.length())\r
         {\r
-            for (size_t k = 0; k < data[i].keys.size(); k++)\r
+            vector<string> k_v = impl->split_string(s, '=', true);\r
+            for (int h = 0; h < 2; h++)\r
             {\r
-                if (key.compare(data[i].keys[k]) == 0)\r
-                {\r
-                    data[i].def_value = value;\r
-                    break;\r
-                }\r
+                if (k_v[0][0] == '-')\r
+                    k_v[0] = k_v[0].substr(1, k_v[0].length() -1);\r
             }\r
+            impl->apply_params(k_v[0], k_v[1]);\r
         }\r
-    }\r
-\r
-    void CommandLineParser::apply_params(int i, std::string value)\r
-    {\r
-        for (size_t j = 0; j < data.size(); j++)\r
+        else if (s.length() > 1 && s[0] == '-')\r
         {\r
-            if (data[j].number == i)\r
+            for (int h = 0; h < 2; h++)\r
             {\r
-                data[j].def_value = value;\r
-                break;\r
+                if (s[0] == '-')\r
+                    s = s.substr(1, s.length() - 1);\r
             }\r
+            impl->apply_params(s, "true");\r
         }\r
-    }\r
-\r
-    void CommandLineParser::sort_params()\r
-    {\r
-        for (size_t i = 0; i < data.size(); i++)\r
+        else if (s[0] != '-')\r
         {\r
-            sort(data[i].keys.begin(), data[i].keys.end());\r
+            impl->apply_params(jj, s);\r
+            jj++;\r
         }\r
+    }\r
 \r
-        sort (data.begin(), data.end(), cmp_params);\r
+    impl->sort_params();\r
+}\r
+    \r
+    \r
+CommandLineParser::CommandLineParser(const CommandLineParser& parser)\r
+{\r
+    impl = parser.impl;\r
+    CV_XADD(&impl->refcount, 1);\r
+}\r
+    \r
+CommandLineParser& CommandLineParser::operator = (const CommandLineParser& parser)\r
+{\r
+    if( this != &parser )\r
+    {\r
+        if(CV_XADD(&impl->refcount, -1) == 1)\r
+            delete impl;\r
+        impl = parser.impl;\r
+        CV_XADD(&impl->refcount, 1);\r
     }\r
+    return *this;\r
+}\r
+\r
+void CommandLineParser::about(const string& message)\r
+{\r
+    impl->about_message = message;\r
+}\r
 \r
-    std::string CommandLineParser::cat_string(std::string str)\r
+void CommandLineParser::Impl::apply_params(const string& key, const string& value)\r
+{\r
+    for (size_t i = 0; i < data.size(); i++)\r
     {\r
-        while (!str.empty() && str[0] == ' ')\r
+        for (size_t k = 0; k < data[i].keys.size(); k++)\r
         {\r
-            str = str.substr(1, str.length() - 1);\r
+            if (key.compare(data[i].keys[k]) == 0)\r
+            {\r
+                data[i].def_value = value;\r
+                break;\r
+            }\r
         }\r
+    }\r
+}\r
 \r
-        while (!str.empty() && str[str.length() - 1] == ' ')\r
+void CommandLineParser::Impl::apply_params(int i, string value)\r
+{\r
+    for (size_t j = 0; j < data.size(); j++)\r
+    {\r
+        if (data[j].number == i)\r
         {\r
-            str = str.substr(0, str.length() - 1);\r
+            data[j].def_value = value;\r
+            break;\r
         }\r
-\r
-        return str;\r
     }\r
+}\r
 \r
-    std::string CommandLineParser::getPathToApplication()\r
+void CommandLineParser::Impl::sort_params()\r
+{\r
+    for (size_t i = 0; i < data.size(); i++)\r
     {\r
-        return path_to_app;\r
+        sort(data[i].keys.begin(), data[i].keys.end());\r
     }\r
 \r
-    bool CommandLineParser::has(const std::string& name)\r
+    sort (data.begin(), data.end(), cmp_params);\r
+}\r
+\r
+string CommandLineParser::Impl::cat_string(const string& str) const\r
+{\r
+    int left = 0, right = (int)str.length();\r
+    while( left <= right && str[left] == ' ' )\r
+        left++;\r
+    while( right > left && str[right-1] == ' ' )\r
+        right--;\r
+    return left >= right ? string("") : str.substr(left, right-left);\r
+}\r
+\r
+string CommandLineParser::getPathToApplication() const\r
+{\r
+    return impl->path_to_app;\r
+}\r
+\r
+bool CommandLineParser::has(const string& name) const\r
+{\r
+    for (size_t i = 0; i < impl->data.size(); i++)\r
     {\r
-        for (size_t i = 0; i < data.size(); i++)\r
+        for (size_t j = 0; j < impl->data[i].keys.size(); j++)\r
         {\r
-            for (size_t j = 0; j < data[i].keys.size(); j++)\r
+            if (name.compare(impl->data[i].keys[j]) == 0 && string("true").compare(impl->data[i].def_value) == 0)\r
             {\r
-                if (name.compare(data[i].keys[j]) == 0 && std::string("true").compare(data[i].def_value) == 0)\r
-                {\r
-                    return true;\r
-                }\r
+                return true;\r
             }\r
         }\r
-        return false;\r
     }\r
+    return false;\r
+}\r
 \r
-    bool CommandLineParser::check()\r
-    {\r
-        return error == false;\r
-    }\r
+bool CommandLineParser::check() const\r
+{\r
+    return impl->error == false;\r
+}\r
 \r
-    void CommandLineParser::printErrors()\r
+void CommandLineParser::printErrors() const\r
+{\r
+    if (impl->error)\r
     {\r
-        if (error)\r
-        {\r
-            std::cout << std::endl << "ERRORS:" << std::endl << error_message << std::endl;\r
-        }\r
+        std::cout << std::endl << "ERRORS:" << std::endl << impl->error_message << std::endl;\r
     }\r
+}\r
 \r
-    void CommandLineParser::printMessage()\r
-    {\r
-        if (about_message != "")\r
-            std::cout << about_message << std::endl;\r
+void CommandLineParser::printMessage() const\r
+{\r
+    if (impl->about_message != "")\r
+        std::cout << impl->about_message << std::endl;\r
 \r
-        std::cout << "Usage: " << app_name << " [params] ";\r
+    std::cout << "Usage: " << impl->app_name << " [params] ";\r
 \r
-        for (size_t i = 0; i < data.size(); i++)\r
+    for (size_t i = 0; i < impl->data.size(); i++)\r
+    {\r
+        if (impl->data[i].number > -1)\r
         {\r
-            if (data[i].number > -1)\r
-            {\r
-                std::string name = data[i].keys[0].substr(1, data[i].keys[0].length() - 1);\r
-                std::cout << name << " ";\r
-            }\r
+            string name = impl->data[i].keys[0].substr(1, impl->data[i].keys[0].length() - 1);\r
+            std::cout << name << " ";\r
         }\r
+    }\r
 \r
-        std::cout << std::endl << std::endl;\r
+    std::cout << std::endl << std::endl;\r
 \r
-        for (size_t i = 0; i < data.size(); i++)\r
+    for (size_t i = 0; i < impl->data.size(); i++)\r
+    {\r
+        if (impl->data[i].number == -1)\r
         {\r
-            if (data[i].number == -1)\r
+            std::cout << "\t";\r
+            for (size_t j = 0; j < impl->data[i].keys.size(); j++)\r
             {\r
-                std::cout << "\t";\r
-                for (size_t j = 0; j < data[i].keys.size(); j++)\r
+                string k = impl->data[i].keys[j];\r
+                if (k.length() > 1)\r
                 {\r
-                    std::string k = data[i].keys[j];\r
-                    if (k.length() > 1)\r
-                    {\r
-                        std::cout << "--";\r
-                    }\r
-                    else\r
-                    {\r
-                        std::cout << "-";\r
-                    }\r
-                    std::cout << k;\r
-\r
-                    if (j != data[i].keys.size() - 1)\r
-                    {\r
-                        std::cout << ", ";\r
-                    }\r
+                    std::cout << "--";\r
                 }\r
-                std::string dv = cat_string(data[i].def_value);\r
-                if (dv.compare("") != 0)\r
+                else\r
                 {\r
-                    std::cout << " (value:" << dv << ")";\r
+                    std::cout << "-";\r
                 }\r
-                std::cout << std::endl << "\t\t" << data[i].help_message << std::endl;\r
-            }\r
-        }\r
-        std::cout << std::endl;\r
-\r
-        for (size_t i = 0; i < data.size(); i++)\r
-        {\r
-            if (data[i].number != -1)\r
-            {\r
-                std::cout << "\t";\r
-                std::string k = data[i].keys[0];\r
-                k = k.substr(1, k.length() - 1);\r
-\r
                 std::cout << k;\r
 \r
-                std::string dv = cat_string(data[i].def_value);\r
-                if (dv.compare("") != 0)\r
+                if (j != impl->data[i].keys.size() - 1)\r
                 {\r
-                    std::cout << " (value:" << dv << ")";\r
+                    std::cout << "";\r
                 }\r
-                std::cout << std::endl << "\t\t" << data[i].help_message << std::endl;\r
             }\r
+            string dv = impl->cat_string(impl->data[i].def_value);\r
+            if (dv.compare("") != 0)\r
+            {\r
+                std::cout << " (value:" << dv << ")";\r
+            }\r
+            std::cout << std::endl << "\t\t" << impl->data[i].help_message << std::endl;\r
         }\r
     }\r
+    std::cout << std::endl;\r
 \r
-    std::vector<std::string> CommandLineParser::split_range_string(std::string str, char fs, char ss)\r
+    for (size_t i = 0; i < impl->data.size(); i++)\r
     {\r
-        std::vector<std::string> vec;\r
-        std::string word = "";\r
-        bool begin = false;\r
-\r
-        while (!str.empty())\r
+        if (impl->data[i].number != -1)\r
         {\r
-            if (str[0] == fs)\r
-            {\r
-                if (begin == true)\r
-                {\r
-                    CV_Error(CV_StsParseError,\r
-                             std::string("error in split_range_string(")\r
-                             + str\r
-                             + std::string(", ")\r
-                             + std::string(1, fs)\r
-                             + std::string(", ")\r
-                             + std::string(1, ss)\r
-                             + std::string(")")\r
-                             );\r
-                }\r
-                begin = true;\r
-                word = "";\r
-                str = str.substr(1, str.length() - 1);\r
-            }\r
+            std::cout << "\t";\r
+            string k = impl->data[i].keys[0];\r
+            k = k.substr(1, k.length() - 1);\r
+\r
+            std::cout << k;\r
 \r
-            if (str[0] == ss)\r
+            string dv = impl->cat_string(impl->data[i].def_value);\r
+            if (dv.compare("") != 0)\r
             {\r
-                if (begin == false)\r
-                {\r
-                    CV_Error(CV_StsParseError,\r
-                             std::string("error in split_range_string(")\r
-                             + str\r
-                             + std::string(", ")\r
-                             + std::string(1, fs)\r
-                             + std::string(", ")\r
-                             + std::string(1, ss)\r
-                             + std::string(")")\r
-                             );\r
-                }\r
-                begin = false;\r
-                vec.push_back(word);\r
+                std::cout << " (value:" << dv << ")";\r
             }\r
+            std::cout << std::endl << "\t\t" << impl->data[i].help_message << std::endl;\r
+        }\r
+    }\r
+}\r
+\r
+vector<string> CommandLineParser::Impl::split_range_string(const string& _str, char fs, char ss) const\r
+{\r
+    string str = _str;\r
+    vector<string> vec;\r
+    string word = "";\r
+    bool begin = false;\r
 \r
+    while (!str.empty())\r
+    {\r
+        if (str[0] == fs)\r
+        {\r
             if (begin == true)\r
             {\r
-                word += str[0];\r
+                CV_Error(CV_StsParseError,\r
+                         string("error in split_range_string(")\r
+                         + str\r
+                         + string(", ")\r
+                         + string(1, fs)\r
+                         + string(", ")\r
+                         + string(1, ss)\r
+                         + string(")")\r
+                         );\r
             }\r
+            begin = true;\r
+            word = "";\r
             str = str.substr(1, str.length() - 1);\r
         }\r
 \r
-        if (begin == true)\r
+        if (str[0] == ss)\r
         {\r
-            CV_Error(CV_StsParseError,\r
-                     std::string("error in split_range_string(")\r
-                     + str\r
-                     + std::string(", ")\r
-                     + std::string(1, fs)\r
-                     + std::string(", ")\r
-                     + std::string(1, ss)\r
-                     + std::string(")")\r
-                     );\r
+            if (begin == false)\r
+            {\r
+                CV_Error(CV_StsParseError,\r
+                         string("error in split_range_string(")\r
+                         + str\r
+                         + string(", ")\r
+                         + string(1, fs)\r
+                         + string(", ")\r
+                         + string(1, ss)\r
+                         + string(")")\r
+                         );\r
+            }\r
+            begin = false;\r
+            vec.push_back(word);\r
         }\r
 \r
-        return vec;\r
+        if (begin == true)\r
+        {\r
+            word += str[0];\r
+        }\r
+        str = str.substr(1, str.length() - 1);\r
     }\r
 \r
-    std::vector<std::string> CommandLineParser::split_string(std::string str, char symbol, bool create_empty_item)\r
+    if (begin == true)\r
     {\r
-        std::vector<std::string> vec;\r
-        std::string word = "";\r
+        CV_Error(CV_StsParseError,\r
+                 string("error in split_range_string(")\r
+                 + str\r
+                 + string(", ")\r
+                 + string(1, fs)\r
+                 + string(", ")\r
+                 + string(1, ss)\r
+                 + string(")")\r
+                 );\r
+    }\r
+\r
+    return vec;\r
+}\r
 \r
-        while (!str.empty())\r
+vector<string> CommandLineParser::Impl::split_string(const string& _str, char symbol, bool create_empty_item) const\r
+{\r
+    string str = _str;\r
+    vector<string> vec;\r
+    string word = "";\r
+\r
+    while (!str.empty())\r
+    {\r
+        if (str[0] == symbol)\r
         {\r
-            if (str[0] == symbol)\r
-            {\r
-                if (!word.empty() || create_empty_item)\r
-                {\r
-                    vec.push_back(word);\r
-                    word = "";\r
-                }\r
-            }\r
-            else\r
+            if (!word.empty() || create_empty_item)\r
             {\r
-                word += str[0];\r
+                vec.push_back(word);\r
+                word = "";\r
             }\r
-            str = str.substr(1, str.length() - 1);\r
         }\r
-\r
-        if (word != "" || create_empty_item)\r
+        else\r
         {\r
-            vec.push_back(word);\r
+            word += str[0];\r
         }\r
-\r
-        return vec;\r
+        str = str.substr(1, str.length() - 1);\r
     }\r
 \r
-    #undef clp_get\r
-    #define clp_get(T) template<> T CommandLineParser::get<T>(const std::string& name, bool space_delete);\r
-\r
-    clp_get(int)\r
-    clp_get(unsigned int)\r
-    clp_get(long)\r
-    clp_get(unsigned long)\r
-    clp_get(long long)\r
-    clp_get(unsigned long long)\r
-    clp_get(size_t)\r
-    clp_get(float)\r
-    clp_get(double)\r
-    clp_get(uint64)\r
-    clp_get(int64)\r
-    clp_get(std::string)\r
-\r
-    #undef clp_from_str\r
-    #define clp_from_str(T) template<> T from_str<T>(const std::string & str);\r
-\r
-    clp_from_str(int)\r
-    clp_from_str(unsigned int)\r
-    clp_from_str(long)\r
-    clp_from_str(unsigned long)\r
-    clp_from_str(long long)\r
-    clp_from_str(unsigned long long)\r
-    clp_from_str(size_t)\r
-    clp_from_str(uint64)\r
-    clp_from_str(int64)\r
-    clp_from_str(float)\r
-    clp_from_str(double)\r
-\r
-    template<>\r
-    std::string from_str(const std::string & str)\r
+    if (word != "" || create_empty_item)\r
     {\r
-        return str;\r
+        vec.push_back(word);\r
     }\r
 \r
-    #undef clp_type_name\r
-    #define clp_type_name(type, name) template<> std::string get_type_name<type>() { return std::string(name);}\r
-\r
-    clp_type_name(int, "int")\r
-    clp_type_name(unsigned int, "unsigned int")\r
-    clp_type_name(long, "long")\r
-    clp_type_name(long long, "long long")\r
-    clp_type_name(unsigned long long, "unsigned long long")\r
-    clp_type_name(size_t, "size_t")\r
-    clp_type_name(float, "float")\r
-    clp_type_name(double, "double")\r
+    return vec;\r
+}\r
 \r
 }\r