00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifndef MORE_IO_CMDLINE_H
00051 #define MORE_IO_CMDLINE_H
00052
00053
00054 #include <iostream>
00055 #include <functional>
00056 #include <map>
00057 #include <list>
00058 #include <more/gen/closure.h>
00059 #include <stdexcept>
00060 #include <string>
00061 #include <cstdlib>
00062
00063
00064 namespace more {
00065 namespace io {
00066
00067 template<typename T>
00068 struct cmdline_arg_parser
00069 : std::unary_function<std::istream&, void>
00070 {
00071 cmdline_arg_parser(T& x, bool& ntf)
00072 : m_x(x), m_notify(ntf) {}
00073
00074 void operator()(std::istream& is)
00075 {
00076 if (is >> m_x)
00077 m_notify = true;
00078 }
00079
00080 private:
00081 T& m_x;
00082 bool& m_notify;
00083 };
00084
00085 template<>
00086 struct cmdline_arg_parser<std::string>
00087 : std::unary_function<std::istream&, void>
00088 {
00089 cmdline_arg_parser(std::string& x, bool& f)
00090 : m_x(x), m_notify(f) {}
00091 void operator()(std::istream& is);
00092
00093 private:
00094 std::string& m_x;
00095 bool& m_notify;
00096 };
00097
00098 template<typename T>
00099 struct cmdline_setter : std::unary_function<std::istream&, void>
00100 {
00101 cmdline_setter(T& x, T const& v) : ref(x), value(v) {}
00102 void operator()(std::istream& is) { ref = value; }
00103
00104 private:
00105 T& ref;
00106 T value;
00107 };
00108
00109 template<typename T, typename OutputIterator>
00110 struct cmdline_copier : std::unary_function<std::istream&, void>
00111 {
00112 cmdline_copier(OutputIterator it) : m_it(it) {}
00113
00114 void operator()(std::istream& is)
00115 {
00116 T x;
00117 is >> x;
00118 *m_it = x;
00119 ++m_it;
00120 }
00121
00122 private:
00123 OutputIterator m_it;
00124 };
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 struct cmdline
00148 {
00149 typedef std::size_t size_type;
00150 typedef gen::unary_closure<std::istream&, void> closure_type;
00151
00152 typedef unsigned int flag_type;
00153 static flag_type const enable_assignment_style = 1;
00154 static flag_type const disable_assignment_style = 2;
00155
00156 private:
00157 typedef std::map<std::string, closure_type> opt_map_type;
00158 typedef std::list<closure_type> arg_list_type;
00159 typedef std::list< std::pair<std::string, std::string> > opt_doc_type;
00160 typedef std::list< std::string > arg_doc_type;
00161
00162 public:
00163
00164
00165
00166 struct failure : std::runtime_error
00167 {
00168 failure(std::string const& what_)
00169 : std::runtime_error(what_+" (Try `--help'.)") {}
00170 };
00171
00172
00173
00174
00175
00176 struct relax : std::exception
00177 {
00178 relax(std::string const& what_) : msg(what_) {}
00179 virtual ~relax() throw() {}
00180 virtual const char* what() const throw() {
00181 return msg.c_str();
00182 }
00183 private:
00184 std::string msg;
00185 };
00186
00187
00188 explicit cmdline(flag_type fl = 0);
00189
00190
00191
00192 template<typename UnaryFunction>
00193 void insert_functional(std::string const& opt,
00194 std::string const& doc, UnaryFunction f)
00195 {
00196 priv_insert(opt, doc, closure_type(f));
00197 }
00198
00199
00200 template<typename T>
00201 void insert_reference(std::string const& opt,
00202 std::string const& doc, T& x,
00203 bool& notify = null_notify)
00204 {
00205 notify = false;
00206 priv_insert(opt, doc,
00207 closure_type(cmdline_arg_parser<T>(x, notify)));
00208 }
00209
00210
00211
00212 template<typename T>
00213 void insert_setter(std::string const& opt,
00214 std::string const& doc, T& x, T const& v)
00215 {
00216 priv_insert(opt, doc, closure_type(cmdline_setter<T>(x, v)));
00217 }
00218
00219
00220
00221 template<typename T, typename OutputIterator>
00222 void insert_copier(std::string const& opt,
00223 std::string const& doc, OutputIterator it)
00224 {
00225 priv_insert(opt, doc,
00226 closure_type(cmdline_copier<T, OutputIterator>(it)));
00227 }
00228
00229
00230 void optional()
00231 {
00232 n_required = arg_list.size();
00233 }
00234
00235
00236 void parse(int argc, char** argv);
00237
00238
00239
00240
00241 void print_help(std::ostream&) const;
00242
00243
00244 static std::string const& program_name() { return prgname; }
00245
00246 private:
00247 void priv_insert(std::string const&, std::string const&,
00248 closure_type);
00249 opt_map_type opt_map;
00250 arg_list_type arg_list;
00251 opt_doc_type opt_doc;
00252 arg_doc_type arg_doc;
00253 int n_required;
00254 flag_type m_flags;
00255
00256 static bool null_notify;
00257 static std::string prgname;
00258
00259
00260 public:
00261 static int verbose() { return s_opt_verb; }
00262 static int debug() { return s_opt_debug; }
00263 private:
00264 static int s_opt_verb;
00265 static int s_opt_debug;
00266 };
00267
00268 }}
00269
00270
00271 #endif
00272
00273
00274
00275