libmoost
|
00001 /* vim:set ts=3 sw=3 sts=3 et: */ 00028 #ifndef FM_LAST_MOOST_SERVICE_STANDARD_OPTIONS_H_ 00029 #define FM_LAST_MOOST_SERVICE_STANDARD_OPTIONS_H_ 00030 00035 #include <string> 00036 00037 #include <boost/algorithm/string.hpp> 00038 #include <boost/program_options.hpp> 00039 #include <boost/noncopyable.hpp> 00040 00041 #include "option_validator.hpp" 00042 00043 namespace moost { namespace service { 00044 00045 class standard_options : public boost::noncopyable 00046 { 00047 private: 00048 class option 00049 { 00050 private: 00051 const char *m_spec; 00052 const char *m_desc; 00053 00054 public: 00055 option(const char *spec, const char *desc) 00056 : m_spec(spec) 00057 , m_desc(desc) 00058 { 00059 } 00060 00061 const char *spec() const 00062 { 00063 return m_spec; 00064 } 00065 00066 const char *desc() const 00067 { 00068 return m_desc; 00069 } 00070 00071 static std::string longname(const char *spec) 00072 { 00073 std::vector<std::string> parts; 00074 boost::split(parts, spec, boost::is_any_of(",")); 00075 return parts[0]; 00076 } 00077 00078 std::string longname() const 00079 { 00080 return longname(m_spec); 00081 } 00082 }; 00083 00084 option opt_config() const 00085 { 00086 return option("config,c", "config file name"); 00087 } 00088 00089 boost::program_options::options_description& m_od; 00090 option_validator& m_val; 00091 00092 template <typename T> 00093 standard_options& add_option(const option& opt, boost::program_options::typed_value<T> *value) 00094 { 00095 m_od.add_options() (opt.spec(), value, opt.desc()); 00096 return *this; 00097 } 00098 00099 template <typename T> 00100 standard_options& add_option(const option& opt, boost::program_options::typed_value<T> *value, boost::shared_ptr<validator::base> validator, bool mandatory = false) 00101 { 00102 validator->set_option(opt.longname(), opt.desc()); 00103 validator->mandatory(mandatory); 00104 m_val.add(validator); 00105 return add_option(opt, value); 00106 } 00107 00108 public: 00109 struct options 00110 { 00111 std::string config_file; 00112 int port; 00113 int pool; 00114 bool verbose; 00115 }; 00116 00117 standard_options(boost::program_options::options_description& od, option_validator& val) 00118 : m_od(od) 00119 , m_val(val) 00120 { 00121 } 00122 00123 standard_options(boost::program_options::options_description& od, option_validator& val, 00124 options& target, int default_port, int default_pool = 8) 00125 : m_od(od) 00126 , m_val(val) 00127 { 00128 config(target.config_file); 00129 port(target.port, default_port); 00130 pool(target.pool, default_pool); 00131 verbose(target.verbose); 00132 } 00133 00134 standard_options& config(std::string& storage, bool mandatory = true) 00135 { 00136 return add_option(opt_config(), 00137 boost::program_options::value<std::string>(&storage), 00138 validator::file(storage), 00139 mandatory); 00140 } 00141 00142 standard_options& config(std::string& storage, const std::string& defval) 00143 { 00144 return add_option(opt_config(), 00145 boost::program_options::value<std::string>(&storage)->default_value(defval), 00146 validator::file(storage)); 00147 } 00148 00149 template <typename T> 00150 standard_options& port(T& storage, const T& defval) 00151 { 00152 return add_option(option("port,p", "listening port of service"), 00153 boost::program_options::value<T>(&storage)->default_value(defval), 00154 validator::number<T>(storage, 1024, 65535)); 00155 } 00156 00157 template <typename T> 00158 standard_options& port(const char *spec, const char *desc, T& storage, bool mandatory = false) 00159 { 00160 return add_option(option(spec, desc), 00161 boost::program_options::value<T>(&storage), 00162 validator::number<T>(storage, 1024, 65535), 00163 mandatory); 00164 } 00165 00166 template <typename T> 00167 standard_options& port(const char *spec, const char *desc, T& storage, const T& defval) 00168 { 00169 return add_option(option(spec, desc), 00170 boost::program_options::value<T>(&storage)->default_value(defval), 00171 validator::number<T>(storage, 1024, 65535)); 00172 } 00173 00174 template <typename T> 00175 standard_options& pool(T& storage, const T& defval = 8) 00176 { 00177 return add_option(option("pool", "pool size"), 00178 boost::program_options::value<T>(&storage)->default_value(defval), 00179 validator::number<T>(storage, 1, std::numeric_limits<T>::max())); 00180 } 00181 00182 standard_options& verbose(bool& storage) 00183 { 00184 return add_option(option("verbose,v", "start with verbose set to 'everything'"), 00185 boost::program_options::value<bool>(&storage)->zero_tokens()->default_value(false)); 00186 } 00187 00188 standard_options& operator()(const char *spec, const char *desc) 00189 { 00190 m_od.add_options() (spec, desc); 00191 return *this; 00192 } 00193 00194 template <class T> 00195 standard_options& operator()(const char *spec, boost::program_options::typed_value<T> *value, const char *desc) 00196 { 00197 return add_option(option(spec, desc), value); 00198 } 00199 00200 template <class T> 00201 standard_options& operator()(const char *spec, boost::program_options::typed_value<T> *value, const char *desc, 00202 boost::shared_ptr<validator::base> validator) 00203 { 00204 return add_option(option(spec, desc), value, validator); 00205 } 00206 }; 00207 00208 } } 00209 00210 #endif