MLPACK  1.0.7
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 
53 #define PROGRAM_INFO(NAME, DESC) static mlpack::util::ProgramDoc \
54  io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, DESC);
55 
73 #define PARAM_FLAG(ID, DESC, ALIAS) \
74  PARAM_FLAG_INTERNAL(ID, DESC, ALIAS);
75 
97 #define PARAM_INT(ID, DESC, ALIAS, DEF) \
98  PARAM(int, ID, DESC, ALIAS, DEF, false)
99 
121 #define PARAM_FLOAT(ID, DESC, ALIAS, DEF) \
122  PARAM(float, ID, DESC, ALIAS, DEF, false)
123 
145 #define PARAM_DOUBLE(ID, DESC, ALIAS, DEF) \
146  PARAM(double, ID, DESC, ALIAS, DEF, false)
147 
170 #define PARAM_STRING(ID, DESC, ALIAS, DEF) \
171  PARAM(std::string, ID, DESC, ALIAS, DEF, false)
172 
194 #define PARAM_VECTOR(T, ID, DESC, ALIAS) \
195  PARAM(std::vector<T>, ID, DESC, ALIAS, std::vector<T>(), false)
196 
197 // A required flag doesn't make sense and isn't given here.
198 
219 #define PARAM_INT_REQ(ID, DESC, ALIAS) PARAM(int, ID, DESC, ALIAS, 0, true)
220 
243 #define PARAM_FLOAT_REQ(ID, DESC, ALIAS) PARAM(float, ID, DESC, ALIAS, 0.0f, \
244  true)
245 
266 #define PARAM_DOUBLE_REQ(ID, DESC, ALIAS) PARAM(double, ID, DESC, ALIAS, \
267  0.0f, true)
268 
289 #define PARAM_STRING_REQ(ID, DESC, ALIAS) PARAM(std::string, ID, DESC, \
290  ALIAS, "", true);
291 
312 #define PARAM_VECTOR_REQ(T, ID, DESC, ALIAS) PARAM(std::vector<T>, ID, DESC, \
313  ALIAS, std::vector<T>(), true);
314 
320 // These are ugly, but necessary utility functions we must use to generate a
321 // unique identifier inside of the PARAM() module.
322 #define JOIN(x, y) JOIN_AGAIN(x, y)
323 #define JOIN_AGAIN(x, y) x ## y
324 
340 #ifdef __COUNTER__
341  #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option<T> \
342  JOIN(io_option_dummy_object_, __COUNTER__) \
343  (false, DEF, ID, DESC, ALIAS, REQ);
344 
346  #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \
347  mlpack::util::Option<bool> JOIN(__io_option_flag_object_, __COUNTER__) \
348  (ID, DESC, ALIAS);
349 
351 #else
352  // We have to do some really bizarre stuff since __COUNTER__ isn't defined. I
353  // don't think we can absolutely guarantee success, but it should be "good
354  // enough". We use the __LINE__ macro and the type of the parameter to try
355  // and get a good guess at something unique.
356  #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option<T> \
357  JOIN(JOIN(io_option_dummy_object_, __LINE__), opt) (false, DEF, ID, \
358  DESC, ALIAS, REQ);
359 
361  #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \
362  mlpack::util::Option<bool> JOIN(__io_option_flag_object_, __LINE__) \
363  (ID, DESC, ALIAS);
364 
366 #endif
367 
371 #define TYPENAME(x) (std::string(typeid(x).name()))
372 
373 namespace po = boost::program_options;
374 
375 namespace mlpack {
376 
377 namespace util {
378 
379 // Externally defined in option.hpp, this class holds information about the
380 // program being run.
381 class ProgramDoc;
382 
383 }; // namespace util
384 
389 struct ParamData
390 {
392  std::string name;
394  std::string desc;
396  std::string tname;
398  boost::any value;
400  bool wasPassed;
402  bool isFlag;
403 };
404 
530 class CLI
531 {
532  public:
544  static void Add(const std::string& path,
545  const std::string& description,
546  const std::string& alias = "",
547  bool required = false);
548 
560  template<class T>
561  static void Add(const std::string& identifier,
562  const std::string& description,
563  const std::string& alias = "",
564  bool required = false);
565 
573  static void AddFlag(const std::string& identifier,
574  const std::string& description,
575  const std::string& alias = "");
576 
581  static void DefaultMessages();
582 
588  static void Destroy();
589 
596  template<typename T>
597  static T& GetParam(const std::string& identifier);
598 
605  static std::string GetDescription(const std::string& identifier);
606 
619  static CLI& GetSingleton();
620 
626  static bool HasParam(const std::string& identifier);
627 
635  static std::string HyphenateString(const std::string& str, int padding);
636 
643  static void ParseCommandLine(int argc, char** argv);
644 
650  static void RemoveDuplicateFlags(po::basic_parsed_options<char>& bpo);
651 
657  static void ParseStream(std::istream& stream);
658 
662  static void Print();
663 
667  static void PrintHelp(const std::string& param = "");
668 
677 
681  ~CLI();
682 
683  private:
685  po::options_description desc;
686 
688  po::variables_map vmap;
689 
691  std::list<std::string> requiredOptions;
692 
694  typedef std::map<std::string, ParamData> gmap_t;
696 
698  typedef std::map<std::string, std::string> amap_t;
700 
702  static CLI* singleton;
703 
705  bool didParse;
706 
709 
711  friend class Timer;
712 
713  public:
716 
717  private:
724  static void AddAlias(const std::string& alias, const std::string& original);
725 
733  static std::string AliasReverseLookup(const std::string& value);
734 
735 #ifdef _WIN32
736 
741  void FileTimeToTimeVal(timeval* tv);
742 #endif
743 
749  static void RequiredOptions();
750 
758  static std::string SanitizeString(const std::string& str);
759 
763  static void UpdateGmap();
764 
768  CLI();
769 
775  CLI(const std::string& optionsName);
776 
778  CLI(const CLI& other);
779 };
780 
781 }; // namespace mlpack
782 
783 // Include the actual definitions of templated methods
784 #include "cli_impl.hpp"
785 
786 #endif