HEVC Test Model (HM)  HM-16.3
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-2015, 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 
66  void doHelp(std::ostream& out, Options& opts, unsigned columns = 80);
67  unsigned parseGNU(Options& opts, unsigned argc, const char* argv[]);
68  unsigned parseSHORT(Options& opts, unsigned argc, const char* argv[]);
69  std::list<const char*> scanArgv(Options& opts, unsigned argc, const char* argv[]);
70  void scanLine(Options& opts, std::string& line);
71  void scanFile(Options& opts, std::istream& in);
72  void setDefaults(Options& opts);
73  void parseConfigFile(Options& opts, const std::string& filename);
74  bool storePair(Options& opts, const std::string& name, const std::string& value);
75 
79  struct OptionBase
80  {
81  OptionBase(const std::string& name, const std::string& desc)
82  : opt_string(name), opt_desc(desc)
83  {};
84 
85  virtual ~OptionBase() {}
86 
87  /* parse argument arg, to obtain a value for the option */
88  virtual void parse(const std::string& arg) = 0;
89  /* set the argument to the default value */
90  virtual void setDefault() = 0;
91 
92  std::string opt_string;
93  std::string opt_desc;
94  };
95 
97  template<typename T>
98  struct Option : public OptionBase
99  {
100  Option(const std::string& name, T& storage, T default_val, const std::string& desc)
101  : OptionBase(name, desc), opt_storage(storage), opt_default_val(default_val)
102  {}
103 
104  void parse(const std::string& arg);
105 
106  void setDefault()
107  {
109  }
110 
113  };
114 
115  /* Generic parsing */
116  template<typename T>
117  inline void
118  Option<T>::parse(const std::string& arg)
119  {
120  std::istringstream arg_ss (arg,std::istringstream::in);
121  arg_ss.exceptions(std::ios::failbit);
122  try
123  {
124  arg_ss >> opt_storage;
125  }
126  catch (...)
127  {
128  throw ParseFailure(opt_string, arg);
129  }
130  }
131 
132  /* string parsing is specialized -- copy the whole string, not just the
133  * first word */
134  template<>
135  inline void
136  Option<std::string>::parse(const std::string& arg)
137  {
138  opt_storage = arg;
139  }
140 
142  struct OptionFunc : public OptionBase
143  {
144  typedef void (Func)(Options&, const std::string&);
145 
146  OptionFunc(const std::string& name, Options& parent_, Func *func_, const std::string& desc)
147  : OptionBase(name, desc), parent(parent_), func(func_)
148  {}
149 
150  void parse(const std::string& arg)
151  {
152  func(parent, arg);
153  }
154 
155  void setDefault()
156  {
157  return;
158  }
159 
160  private:
161  Options& parent;
162  void (*func)(Options&, const std::string&);
163  };
164 
165  class OptionSpecific;
166  struct Options
167  {
168  ~Options();
169 
171 
172  struct Names
173  {
174  Names() : opt(0) {};
176  {
177  if (opt)
178  {
179  delete opt;
180  }
181  }
182  std::list<std::string> opt_long;
183  std::list<std::string> opt_short;
185  };
186 
187  void addOption(OptionBase *opt);
188 
189  typedef std::list<Names*> NamesPtrList;
190  NamesPtrList opt_list;
191 
192  typedef std::map<std::string, NamesPtrList> NamesMap;
193  NamesMap opt_long_map;
194  NamesMap opt_short_map;
195  };
196 
197  /* Class with templated overloaded operator(), for use by Options::addOptions() */
199  {
200  public:
201  OptionSpecific(Options& parent_) : parent(parent_) {}
202 
209  template<typename T>
211  operator()(const std::string& name, T& storage, T default_val, const std::string& desc = "")
212  {
213  parent.addOption(new Option<T>(name, storage, default_val, desc));
214  return *this;
215  }
216 
225  operator()(const std::string& name, OptionFunc::Func *func, const std::string& desc = "")
226  {
227  parent.addOption(new OptionFunc(name, parent, func, desc));
228  return *this;
229  }
230  private:
232  };
233 
234  } /* namespace: program_options_lite */
235 } /* namespace: df */
236 
238 
239 #endif
Option(const std::string &name, T &storage, T default_val, const std::string &desc)
void parseConfigFile(Options &opts, const string &filename)
void doHelp(ostream &out, Options &opts, unsigned columns)
void parse(const std::string &arg)
void scanLine(Options &opts, string &line)
void parse(const std::string &arg)
OptionBase(const std::string &name, const std::string &desc)
ParseFailure(std::string arg0, std::string val0)
OptionSpecific & operator()(const std::string &name, OptionFunc::Func *func, const std::string &desc="")
unsigned parseGNU(Options &opts, unsigned argc, const char *argv[])
unsigned parseSHORT(Options &opts, unsigned argc, const char *argv[])
OptionFunc(const std::string &name, Options &parent_, Func *func_, const std::string &desc)
bool storePair(Options &opts, bool allow_long, bool allow_short, const string &name, const string &value)
list< const char * > scanArgv(Options &opts, unsigned argc, const char *argv[])
void(* func)(Options &, const std::string &)
void scanFile(Options &opts, istream &in)
std::map< std::string, NamesPtrList > NamesMap
OptionSpecific & operator()(const std::string &name, T &storage, T default_val, const std::string &desc="")
virtual void parse(const std::string &arg)=0
void( Func)(Options &, const std::string &)