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