HEVC Test Model (HM)  HM-16.18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
program_options_lite.h
Go to the documentation of this file.
1 /* The copyright in this software is being made available under the BSD
2  * License, included below. This software may be subject to other third party
3  * and contributor rights, including patent rights, and no such rights are
4  * granted under this license.
5  *
6  * Copyright (c) 2010-2017, ITU/ISO/IEC
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18  * be used to endorse or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 #include <iostream>
34 #include <sstream>
35 #include <string>
36 #include <list>
37 #include <map>
38 
39 #ifndef __PROGRAM_OPTIONS_LITE__
40 #define __PROGRAM_OPTIONS_LITE__
41 
44 
45 
46 namespace df
47 {
48  namespace program_options_lite
49  {
50  struct Options;
51 
52  struct ParseFailure : public std::exception
53  {
54  ParseFailure(std::string arg0, std::string val0) throw()
55  : arg(arg0), val(val0)
56  {}
57 
58  ~ParseFailure() throw() {};
59 
60  std::string arg;
61  std::string val;
62 
63  const char* what() const throw() { return "Option Parse Failure"; }
64  };
65 
67  {
69  virtual ~ErrorReporter() {}
70  virtual std::ostream& error(const std::string& where);
71  virtual std::ostream& warn(const std::string& where);
72  bool is_errored;
73  };
74 
76 
77  void doHelp(std::ostream& out, Options& opts, unsigned columns = 80);
78  std::list<const char*> scanArgv(Options& opts, unsigned argc, const char* argv[], ErrorReporter& error_reporter = default_error_reporter);
79  void setDefaults(Options& opts);
80  void parseConfigFile(Options& opts, const std::string& filename, ErrorReporter& error_reporter = default_error_reporter);
81 
85  struct OptionBase
86  {
87  OptionBase(const std::string& name, const std::string& desc)
88  : opt_string(name), opt_desc(desc)
89  {};
90 
91  virtual ~OptionBase() {}
92 
93  /* parse argument arg, to obtain a value for the option */
94  virtual void parse(const std::string& arg, ErrorReporter&) = 0;
95  /* set the argument to the default value */
96  virtual void setDefault() = 0;
97 
98  std::string opt_string;
99  std::string opt_desc;
100  };
101 
103  template<typename T>
104  struct Option : public OptionBase
105  {
106  Option(const std::string& name, T& storage, T default_val, const std::string& desc)
107  : OptionBase(name, desc), opt_storage(storage), opt_default_val(default_val)
108  {}
109 
110  void parse(const std::string& arg, ErrorReporter&);
111 
112  void setDefault()
113  {
115  }
116 
119  };
120 
121  /* Generic parsing */
122  template<typename T>
123  inline void
124  Option<T>::parse(const std::string& arg, ErrorReporter&)
125  {
126  std::istringstream arg_ss (arg,std::istringstream::in);
127  arg_ss.exceptions(std::ios::failbit);
128  try
129  {
130  arg_ss >> opt_storage;
131  }
132  catch (...)
133  {
134  throw ParseFailure(opt_string, arg);
135  }
136  }
137 
138  /* string parsing is specialized -- copy the whole string, not just the
139  * first word */
140  template<>
141  inline void
142  Option<std::string>::parse(const std::string& arg, ErrorReporter&)
143  {
144  opt_storage = arg;
145  }
146 
148  struct OptionFunc : public OptionBase
149  {
150  typedef void (Func)(Options&, const std::string&, ErrorReporter&);
151 
152  OptionFunc(const std::string& name, Options& parent_, Func *func_, const std::string& desc)
153  : OptionBase(name, desc), parent(parent_), func(func_)
154  {}
155 
156  void parse(const std::string& arg, ErrorReporter& error_reporter)
157  {
158  func(parent, arg, error_reporter);
159  }
160 
161  void setDefault()
162  {
163  return;
164  }
165 
166  private:
169  };
170 
171  class OptionSpecific;
172  struct Options
173  {
174  ~Options();
175 
177 
178  struct Names
179  {
180  Names() : opt(0) {};
182  {
183  if (opt)
184  {
185  delete opt;
186  }
187  }
188  std::list<std::string> opt_long;
189  std::list<std::string> opt_short;
191  };
192 
193  void addOption(OptionBase *opt);
194 
195  typedef std::list<Names*> NamesPtrList;
197 
198  typedef std::map<std::string, NamesPtrList> NamesMap;
201  };
202 
203  /* Class with templated overloaded operator(), for use by Options::addOptions() */
205  {
206  public:
207  OptionSpecific(Options& parent_) : parent(parent_) {}
208 
215  template<typename T>
217  operator()(const std::string& name, T& storage, T default_val, const std::string& desc = "")
218  {
219  parent.addOption(new Option<T>(name, storage, default_val, desc));
220  return *this;
221  }
222 
231  operator()(const std::string& name, OptionFunc::Func *func, const std::string& desc = "")
232  {
233  parent.addOption(new OptionFunc(name, parent, func, desc));
234  return *this;
235  }
236  private:
238  };
239 
240  } /* namespace: program_options_lite */
241 } /* namespace: df */
242 
244 
245 #endif
Option(const std::string &name, T &storage, T default_val, const std::string &desc)
void doHelp(ostream &out, Options &opts, unsigned columns)
void( Func)(Options &, const std::string &, ErrorReporter &)
void parse(const std::string &arg, ErrorReporter &error_reporter)
virtual std::ostream & warn(const std::string &where)
OptionBase(const std::string &name, const std::string &desc)
list< const char * > scanArgv(Options &opts, unsigned argc, const char *argv[], ErrorReporter &error_reporter)
virtual void parse(const std::string &arg, ErrorReporter &)=0
ParseFailure(std::string arg0, std::string val0)
OptionSpecific & operator()(const std::string &name, OptionFunc::Func *func, const std::string &desc="")
OptionFunc(const std::string &name, Options &parent_, Func *func_, const std::string &desc)
void parseConfigFile(Options &opts, const string &filename, ErrorReporter &error_reporter)
std::map< std::string, NamesPtrList > NamesMap
OptionSpecific & operator()(const std::string &name, T &storage, T default_val, const std::string &desc="")
virtual std::ostream & error(const std::string &where)
void parse(const std::string &arg, ErrorReporter &)