1 // Copyright (C) 2012  Davis E. King (davis@dlib.net)
2 // License: Boost Software License   See LICENSE.txt for the full license.
3 #ifndef DLIB_GET_OPTiON_Hh_
4 #define DLIB_GET_OPTiON_Hh_
5 
6 #include "get_option_abstract.h"
7 #include "../string.h"
8 #include "../is_kind.h"
9 
10 namespace dlib
11 {
12 
13 // ----------------------------------------------------------------------------------------
14 
15     class option_parse_error : public error
16     {
17     public:
option_parse_error(const std::string & option_string,const std::string & str)18         option_parse_error(const std::string& option_string, const std::string& str):
19             error(EOPTION_PARSE,"Error parsing argument for option '" + option_string + "', offending string is '" + str + "'.") {}
20     };
21 
22 // ----------------------------------------------------------------------------------------
23 
24     template <typename config_reader_type, typename T>
impl_config_reader_get_option(const config_reader_type & cr,const std::string & option_name,const std::string & full_option_name,T default_value)25     T impl_config_reader_get_option (
26         const config_reader_type& cr,
27         const std::string& option_name,
28         const std::string& full_option_name,
29         T default_value
30     )
31     {
32         std::string::size_type pos = option_name.find_first_of(".");
33         if (pos == std::string::npos)
34         {
35             if (cr.is_key_defined(option_name))
36             {
37                 try{ return string_cast<T>(cr[option_name]); }
38                 catch (string_cast_error&) { throw option_parse_error(full_option_name, cr[option_name]); }
39             }
40         }
41         else
42         {
43             std::string block_name = option_name.substr(0,pos);
44             if (cr.is_block_defined(block_name))
45             {
46                 return impl_config_reader_get_option(cr.block(block_name),
47                                                      option_name.substr(pos+1),
48                                                      full_option_name,
49                                                      default_value);
50             }
51         }
52 
53         return default_value;
54     }
55 
56 // ----------------------------------------------------------------------------------------
57 
58     template <typename cr_type, typename T>
get_option(const cr_type & cr,const std::string & option_name,T default_value)59     typename enable_if<is_config_reader<cr_type>,T>::type get_option (
60         const cr_type& cr,
61         const std::string& option_name,
62         T default_value
63     )
64     {
65         return impl_config_reader_get_option(cr, option_name, option_name, default_value);
66     }
67 
68 // ----------------------------------------------------------------------------------------
69 
70     template <typename parser_type, typename T>
get_option(const parser_type & parser,const std::string & option_name,T default_value)71     typename disable_if<is_config_reader<parser_type>,T>::type get_option (
72         const parser_type& parser,
73         const std::string& option_name,
74         T default_value
75     )
76     {
77         // make sure requires clause is not broken
78         DLIB_ASSERT( parser.option_is_defined(option_name) == true &&
79                      parser.option(option_name).number_of_arguments() == 1,
80             "\t T get_option()"
81             << "\n\t option_name: " << option_name
82             << "\n\t parser.option_is_defined(option_name):            " << parser.option_is_defined(option_name)
83             << "\n\t parser.option(option_name).number_of_arguments(): " << parser.option(option_name).number_of_arguments()
84             );
85 
86         if (parser.option(option_name))
87         {
88             try
89             {
90                 default_value = string_cast<T>(parser.option(option_name).argument());
91             }
92             catch (string_cast_error&)
93             {
94                 throw option_parse_error(option_name, parser.option(option_name).argument());
95             }
96         }
97         return default_value;
98     }
99 
100 // ----------------------------------------------------------------------------------------
101 
102     template <typename parser_type, typename cr_type, typename T>
get_option(const parser_type & parser,const cr_type & cr,const std::string & option_name,T default_value)103     typename disable_if<is_config_reader<parser_type>,T>::type get_option (
104         const parser_type& parser,
105         const cr_type& cr,
106         const std::string& option_name,
107         T default_value
108     )
109     {
110         // make sure requires clause is not broken
111         DLIB_ASSERT( parser.option_is_defined(option_name) == true &&
112                      parser.option(option_name).number_of_arguments() == 1,
113             "\t T get_option()"
114             << "\n\t option_name: " << option_name
115             << "\n\t parser.option_is_defined(option_name):            " << parser.option_is_defined(option_name)
116             << "\n\t parser.option(option_name).number_of_arguments(): " << parser.option(option_name).number_of_arguments()
117             );
118 
119         if (parser.option(option_name))
120             return get_option(parser, option_name, default_value);
121         else
122             return get_option(cr, option_name, default_value);
123     }
124 
125 // ----------------------------------------------------------------------------------------
126 
127     template <typename parser_type, typename cr_type, typename T>
get_option(const cr_type & cr,const parser_type & parser,const std::string & option_name,T default_value)128     typename disable_if<is_config_reader<parser_type>,T>::type get_option (
129         const cr_type& cr,
130         const parser_type& parser,
131         const std::string& option_name,
132         T default_value
133     )
134     {
135         // make sure requires clause is not broken
136         DLIB_ASSERT( parser.option_is_defined(option_name) == true &&
137                      parser.option(option_name).number_of_arguments() == 1,
138             "\t T get_option()"
139             << "\n\t option_name: " << option_name
140             << "\n\t parser.option_is_defined(option_name):            " << parser.option_is_defined(option_name)
141             << "\n\t parser.option(option_name).number_of_arguments(): " << parser.option(option_name).number_of_arguments()
142             );
143 
144         if (parser.option(option_name))
145             return get_option(parser, option_name, default_value);
146         else
147             return get_option(cr, option_name, default_value);
148     }
149 
150 // ----------------------------------------------------------------------------------------
151 // ----------------------------------------------------------------------------------------
152 
153     template <typename T>
get_option(const T & cr,const std::string & option_name,const char * default_value)154     inline std::string get_option (
155         const T& cr,
156         const std::string& option_name,
157         const char* default_value
158     )
159     {
160         return get_option(cr, option_name, std::string(default_value));
161     }
162 
163 // ----------------------------------------------------------------------------------------
164 
165     template <typename T, typename U>
get_option(const T & parser,const U & cr,const std::string & option_name,const char * default_value)166     inline std::string get_option (
167         const T& parser,
168         const U& cr,
169         const std::string& option_name,
170         const char* default_value
171     )
172     {
173         return get_option(parser, cr, option_name, std::string(default_value));
174     }
175 
176 // ----------------------------------------------------------------------------------------
177 
178 }
179 
180 #endif // DLIB_GET_OPTiON_Hh_
181 
182