ewmscp  ..
OptionsChrono.h
Go to the documentation of this file.
1 #ifndef __OptionsChrono_H__
2 #define __OptionsChrono_H__
3 
4 #ifdef __Options_H__
5 #error When using OptionsChrono.h do not include Options.h, at least not before!
6 #endif
7 
8 #include <iostream>
9 #include <chrono>
10 #include <type_traits>
11 #include <sstream>
12 #include <iomanip>
13 #include <stdexcept>
14 
15 namespace options {
17  namespace internal {
18  std::chrono::duration<double> parseNumberAndUnit(std::stringstream& aStream, int* aMonths = nullptr, int* aYears = nullptr);
19  std::chrono::system_clock::time_point fParseTimePointString(const std::string& aString);
20 
22  template <class Rep, class Period> void parseDurationString(std::chrono::duration<Rep, Period> &aDuration, const std::string& aString, int* aMonths = nullptr, int* aYears = nullptr) {
23  auto between = aString.find("between");
24  if (between != std::string::npos) {
25  auto andpos = aString.find("and");
26  if (andpos != std::string::npos) {
27  auto t0 = fParseTimePointString(aString.substr(between + 8, andpos - 1 - (between + 8) ));
28  auto t1 = fParseTimePointString(aString.substr(andpos + 4));
29  aDuration = std::chrono::duration_cast<typename std::remove_reference<decltype(aDuration)>::type>(t1 - t0);
30  } else {
31  throw std::runtime_error("duration with 'between' without and");
32  }
33  } else {
34  std::stringstream sbuf(aString);
35  aDuration = aDuration.zero();
36  while (!sbuf.eof()) {
37  aDuration += std::chrono::duration_cast<typename std::remove_reference<decltype(aDuration)>::type>(parseNumberAndUnit(sbuf, aMonths, aYears));
38  }
39  }
40  };
41  } // end of namespace internal
42  namespace escapedIO {
43  std::ostream& operator<<(std::ostream& aStream, const std::chrono::system_clock::time_point& aTime);
44  std::istream& operator>>(std::istream& aStream, std::chrono::system_clock::time_point& aTime);
45 
46  template <class Rep, class Period> std::ostream& operator<<(std::ostream& aStream, const std::chrono::duration<Rep, Period>& aDuration) {
47  auto flags(aStream.flags());
48  aStream << std::fixed;
49  aStream << aDuration.count();
50  aStream.flags(flags);
51  return aStream;
52  }
53  template <class Rep, class Period> std::istream& operator>>(std::istream& aStream, std::chrono::duration<Rep, Period>& aDuration) {
54  std::string buf;
55  aStream >> buf;
56  if (!aStream.fail()) {
57  internal::parseDurationString(aDuration, buf);
58  }
59  return aStream;
60  };
61  } // end of namespace escapedIO
62 } // end of namespace options
63 
64 #include "Options.h"
65 
66 
67 namespace options {
68  template <> class single<std::chrono::system_clock::time_point> :
69  public std::chrono::system_clock::time_point,
70  public internal::typed_base<std::chrono::system_clock::time_point>,
71  public originalStringKeeper,
72  public valuePrinter<std::chrono::system_clock::time_point> {
73  public:
75  protected:
76  std::vector<valueType> lRange;
77 
78  public:
79  static void fDefaultValuePrinter(std::ostream& aStream, const valueType& aValue);
80 
81  single(char aShortName, const std::string& aLongName, const std::string& aExplanation, valueType aDefault = valueType::clock::now(), const std::vector<valueType>& aRange = {}, valuePrinterType aValuePrinter = fDefaultValuePrinter);
82  single(char aShortName, const std::string& aLongName, const std::string& aExplanation, const std::string& aDefault, const std::vector<std::string>& aRange = {}, valuePrinterType aValuePrinter = fDefaultValuePrinter);
83 
84 
85  void fAddDefaultFromStream(std::istream& aStream) override;
86  void fWriteRange(std::ostream& aStream) const override;
87  void fWriteValue(std::ostream& aStream) const override;
88  void fSetMe(std::istream& aStream, const internal::sourceItem& aSource) override;
89  void fCheckRange() const override {
90  this->fCheckValueForRange(*this);
91  }
92  };
93 
94 
95 
96 
97 
98 
100  template <class Rep, class Period> class single<std::chrono::duration<Rep, Period>> :
101  public std::chrono::duration<Rep, Period>,
102  public internal::typed_base<std::chrono::duration<Rep, Period>>,
103  public valuePrinter<std::chrono::duration<Rep, Period>>,
104  public originalStringKeeper {
105  public:
106  typedef std::chrono::duration<Rep, Period> valueType; // why does the one in typed_base not work?
107  protected:
108  std::vector<valueType> lRange;
109 
110  public:
111  static void fDefaultValuePrinter(std::ostream& aStream, const valueType& aValue) {
112  using escapedIO::operator<<;
113  aStream << aValue;
114  };
115 
116 
117  single(char aShortName, const std::string& aLongName, const std::string& aExplanation, valueType aDefault = valueType::zero(), const std::vector<valueType>& aRange = {}, typename valuePrinter<valueType>::valuePrinterType aValuePrinter = fDefaultValuePrinter):
118  valueType(aDefault),
119  internal::typed_base<valueType>(aShortName, aLongName, aExplanation, 1),
120  valuePrinter<valueType>(aValuePrinter) {
121  if (!aRange.empty()) {
122  this->fAddToRange(aRange);
123  }
124  }
125  void fAddDefaultFromStream(std::istream& aStream) override {
126  std::getline(aStream, lOriginalString);
127  try {
128  internal::parseDurationString(*this, lOriginalString);
129  } catch (const std::runtime_error& e) {
130  throw internal::optionError(this, e.what());
131  }
132  }
133  void fWriteValue(std::ostream& aStream) const override {
134  this->lValuePrinter(aStream, *this);
135  }
136  void fSetMe(std::istream& aStream, const internal::sourceItem& aSource) override {
137  using escapedIO::operator>>;
138  aStream >> lOriginalString;
139  try {
140  internal::parseDurationString(*this, lOriginalString);
141  } catch (const std::runtime_error& e) {
142  throw internal::optionError(this, e.what());
143  }
144  this->fSetSource(aSource);
145  }
146  void fCheckRange() const override {
147  this->fCheckValueForRange(*this);
148  }
149  };
150 
151 
152 
153 } // end of namespace options
154 
155 
156 #endif
options::single< std::chrono::duration< Rep, Period > >::fDefaultValuePrinter
static void fDefaultValuePrinter(std::ostream &aStream, const valueType &aValue)
Definition: OptionsChrono.h:111
options::single< std::chrono::duration< Rep, Period > >::fCheckRange
void fCheckRange() const override
Definition: OptionsChrono.h:146
options::internal::parseNumberAndUnit
std::chrono::duration< double > parseNumberAndUnit(std::stringstream &aStream, int *aMonths=nullptr, int *aYears=nullptr)
Definition: OptionsChrono.cpp:14
options::single
generic option class with any type that can be used with std::istream and std::ostream
Definition: Options.h:533
options::single< std::chrono::system_clock::time_point >::fCheckRange
void fCheckRange() const override
Definition: OptionsChrono.h:89
options::internal::typed_base< T >::fAddToRange
virtual void fAddToRange(rangeValueType aValue)
add a value to the range of allowed values
Definition: Options.h:458
options::originalStringKeeper
interface class that is used for options where the original string rather than the streamed value is ...
Definition: Options.h:864
options::internal::typed_base< T >::rangeValueType
std::conditional< std::is_same< T, const char * >::value||false, std::string, T >::type rangeValueType
Definition: Options.h:448
options::internal::typed_base< T >::fCheckValueForRange
virtual void fCheckValueForRange(const compareValueType &aValue) const
Definition: Options.h:506
options::single< std::chrono::system_clock::time_point >::lRange
std::vector< valueType > lRange
Definition: OptionsChrono.h:76
options::internal::typed_base
Definition: Options.h:445
options
Definition: Options.h:33
Options.h
options::single< std::chrono::duration< Rep, Period > >::fSetMe
void fSetMe(std::istream &aStream, const internal::sourceItem &aSource) override
function to set the value from a string, remembering the source
Definition: OptionsChrono.h:136
options::internal::fParseTimePointString
std::chrono::system_clock::time_point fParseTimePointString(const std::string &aString)
Definition: OptionsChrono.cpp:183
options::single::fSetMe
void fSetMe(std::istream &aStream, const internal::sourceItem &aSource) override
function to set the value from a string, remembering the source
Definition: Options.h:578
options::escapedIO::operator>>
std::istream & operator>>(std::istream &aStream, const char *&aCstring)
Definition: Options.cpp:435
options::valuePrinter
template interface class for options that provide a value printer
Definition: Options.h:174
options::escapedIO::operator<<
std::ostream & operator<<(std::ostream &aStream, const std::string &aString)
Definition: Options.cpp:447
options::single::fWriteValue
void fWriteValue(std::ostream &aStream) const override
write textual representation of value to a std::ostream
Definition: Options.h:569
options::single::single
single(char aShortName, const std::string &aLongName, const std::string &aExplanation, T aDefault, const std::vector< T > &aRange={})
construct an object of single<T>
Definition: Options.h:546
options::single< std::chrono::duration< Rep, Period > >::lRange
std::vector< valueType > lRange
Definition: OptionsChrono.h:108
options::internal::optionError
Definition: Options.h:279
options::internal::parseDurationString
void parseDurationString(std::chrono::duration< Rep, Period > &aDuration, const std::string &aString, int *aMonths=nullptr, int *aYears=nullptr)
parse a string into a std::chrono::duration, if given set the years and months separately
Definition: OptionsChrono.h:22
options::single< std::chrono::duration< Rep, Period > >::single
single(char aShortName, const std::string &aLongName, const std::string &aExplanation, valueType aDefault=valueType::zero(), const std::vector< valueType > &aRange={}, typename valuePrinter< valueType >::valuePrinterType aValuePrinter=fDefaultValuePrinter)
Definition: OptionsChrono.h:117
options::internal::typed_base< T >::fWriteRange
void fWriteRange(std::ostream &aStream) const override
Definition: Options.h:491
options::internal::sourceItem
class to remember from which line (or item) of a file/line an option was set from
Definition: Options.h:53
options::internal::typed_base< T >::valueType
T valueType
Definition: Options.h:447
options::single< std::chrono::system_clock::time_point >::valueType
rangeValueType valueType
Definition: OptionsChrono.h:74
options::single::fAddDefaultFromStream
void fAddDefaultFromStream(std::istream &aStream) override
special for use in the shellScriptOptionParser
Definition: Options.h:564
options::single< std::chrono::duration< Rep, Period > >::fWriteValue
void fWriteValue(std::ostream &aStream) const override
write textual representation of value to a std::ostream
Definition: OptionsChrono.h:133
options::base::fSetSource
virtual void fSetSource(const internal::sourceItem &aSource)
remember the source that provided the value, e.g. commandline or a config file
Definition: Options.cpp:561
options::single< std::chrono::duration< Rep, Period > >::fAddDefaultFromStream
void fAddDefaultFromStream(std::istream &aStream) override
special for use in the shellScriptOptionParser
Definition: OptionsChrono.h:125
options::single< std::chrono::duration< Rep, Period > >::valueType
std::chrono::duration< Rep, Period > valueType
Definition: OptionsChrono.h:106