MLPACK  1.0.11
cli.hpp
Go to the documentation of this file.
1 
24 #ifndef __MLPACK_CORE_UTIL_CLI_HPP
25 #define __MLPACK_CORE_UTIL_CLI_HPP
26 
27 #include <list>
28 #include <iostream>
29 #include <map>
30 #include <string>
31 
32 #include <boost/any.hpp>
33 #include <boost/program_options.hpp>
34 
35 #include "timers.hpp"
36 #include "cli_deleter.hpp" // To make sure we can delete the singleton.
37 #include "version.hpp"
38 
54 #define PROGRAM_INFO(NAME, DESC) static mlpack::util::ProgramDoc \
55  io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, DESC);
56 
74 #define PARAM_FLAG(ID, DESC, ALIAS) \
75  PARAM_FLAG_INTERNAL(ID, DESC, ALIAS);
76 
98 #define PARAM_INT(ID, DESC, ALIAS, DEF) \
99  PARAM(int, ID, DESC, ALIAS, DEF, false)
100 
122 #define PARAM_FLOAT(ID, DESC, ALIAS, DEF) \
123  PARAM(float, ID, DESC, ALIAS, DEF, false)
124 
146 #define PARAM_DOUBLE(ID, DESC, ALIAS, DEF) \
147  PARAM(double, ID, DESC, ALIAS, DEF, false)
148 
171 #define PARAM_STRING(ID, DESC, ALIAS, DEF) \
172  PARAM(std::string, ID, DESC, ALIAS, DEF, false)
173 
195 #define PARAM_VECTOR(T, ID, DESC, ALIAS) \
196  PARAM(std::vector<T>, ID, DESC, ALIAS, std::vector<T>(), false)
197 
198 // A required flag doesn't make sense and isn't given here.
199 
220 #define PARAM_INT_REQ(ID, DESC, ALIAS) PARAM(int, ID, DESC, ALIAS, 0, true)
221 
244 #define PARAM_FLOAT_REQ(ID, DESC, ALIAS) PARAM(float, ID, DESC, ALIAS, 0.0f, \
245  true)
246 
267 #define PARAM_DOUBLE_REQ(ID, DESC, ALIAS) PARAM(double, ID, DESC, ALIAS, \
268  0.0f, true)
269 
290 #define PARAM_STRING_REQ(ID, DESC, ALIAS) PARAM(std::string, ID, DESC, \
291  ALIAS, "", true);
292 
313 #define PARAM_VECTOR_REQ(T, ID, DESC, ALIAS) PARAM(std::vector<T>, ID, DESC, \
314  ALIAS, std::vector<T>(), true);
315 
321 // These are ugly, but necessary utility functions we must use to generate a
322 // unique identifier inside of the PARAM() module.
323 #define JOIN(x, y) JOIN_AGAIN(x, y)
324 #define JOIN_AGAIN(x, y) x ## y
325 
341 #ifdef __COUNTER__
342  #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option<T> \
343  JOIN(io_option_dummy_object_, __COUNTER__) \
344  (false, DEF, ID, DESC, ALIAS, REQ);
345 
347  #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \
348  mlpack::util::Option<bool> JOIN(__io_option_flag_object_, __COUNTER__) \
349  (ID, DESC, ALIAS);
350 
352 #else
353  // We have to do some really bizarre stuff since __COUNTER__ isn't defined. I
354  // don't think we can absolutely guarantee success, but it should be "good
355  // enough". We use the __LINE__ macro and the type of the parameter to try
356  // and get a good guess at something unique.
357  #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option<T> \
358  JOIN(JOIN(io_option_dummy_object_, __LINE__), opt) (false, DEF, ID, \
359  DESC, ALIAS, REQ);
360 
362  #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \
363  mlpack::util::Option<bool> JOIN(__io_option_flag_object_, __LINE__) \
364  (ID, DESC, ALIAS);
365 
367 #endif
368 
372 #define TYPENAME(x) (std::string(typeid(x).name()))
373 
374 namespace po = boost::program_options;
375 
376 namespace mlpack {
377 
378 namespace util {
379 
380 // Externally defined in option.hpp, this class holds information about the
381 // program being run.
382 class ProgramDoc;
383 
384 }; // namespace util
385 
390 struct ParamData
391 {
393  std::string name;
395  std::string desc;
397  std::string tname;
399  boost::any value;
401  bool wasPassed;
403  bool isFlag;
404 };
405 
531 class CLI
532 {
533  public:
545  static void Add(const std::string& path,
546  const std::string& description,
547  const std::string& alias = "",
548  bool required = false);
549 
561  template<class T>
562  static void Add(const std::string& identifier,
563  const std::string& description,
564  const std::string& alias = "",
565  bool required = false);
566 
574  static void AddFlag(const std::string& identifier,
575  const std::string& description,
576  const std::string& alias = "");
577 
582  static void DefaultMessages();
583 
589  static void Destroy();
590 
597  template<typename T>
598  static T& GetParam(const std::string& identifier);
599 
606  static std::string GetDescription(const std::string& identifier);
607 
620  static CLI& GetSingleton();
621 
627  static bool HasParam(const std::string& identifier);
628 
636  static std::string HyphenateString(const std::string& str, int padding);
637 
644  static void ParseCommandLine(int argc, char** argv);
645 
651  static void RemoveDuplicateFlags(po::basic_parsed_options<char>& bpo);
652 
658  static void ParseStream(std::istream& stream);
659 
663  static void Print();
664 
668  static void PrintHelp(const std::string& param = "");
669 
678 
682  ~CLI();
683 
684  private:
686  po::options_description desc;
687 
689  po::variables_map vmap;
690 
692  std::list<std::string> requiredOptions;
693 
695  typedef std::map<std::string, ParamData> gmap_t;
697 
699  typedef std::map<std::string, std::string> amap_t;
701 
703  static CLI* singleton;
704 
706  bool didParse;
707 
709  std::string programName;
710 
713 
715  friend class Timer;
716 
717  public:
720 
721  private:
728  static void AddAlias(const std::string& alias, const std::string& original);
729 
737  static std::string AliasReverseLookup(const std::string& value);
738 
739 #ifdef _WIN32
740 
745  void FileTimeToTimeVal(timeval* tv);
746 #endif
747 
753  static void RequiredOptions();
754 
762  static std::string SanitizeString(const std::string& str);
763 
767  static void UpdateGmap();
768 
772  CLI();
773 
779  CLI(const std::string& optionsName);
780 
782  CLI(const CLI& other);
783 };
784 
785 }; // namespace mlpack
786 
787 // Include the actual definitions of templated methods
788 #include "cli_impl.hpp"
789 
790 #endif