TAP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
TypedArgument.hpp
Go to the documentation of this file.
1 
25 #pragma once
26 
27 #include <type_traits>
28 
29 namespace TAP {
30 
31 template<typename T, bool multi = false>
33 
35 template<typename T, bool multi>
36 using TypedArgumentCheckFunc = std::function<void(const TypedArgument<T, multi>&, const T& value)>;
37 
47 template<typename T, bool multi>
48 class TypedArgument: public Argument {
49  static_assert(!std::is_void<T>::value, "Cannot make void arguments, use plain Argument");
50  static_assert(!std::is_const<T>::value, "Cannot make const arguments");
51  static_assert(!std::is_volatile<T>::value, "Cannot make volatile arguments");
52  static_assert(!std::is_reference<T>::value, "Cannot make reference arguments");
53  static_assert(!std::is_pointer<T>::value, "Cannot make pointer arguments");
54 
55 protected:
58  using ST = typename std::conditional< !multi, T, std::vector<T> >::type;
59 
61  mutable ST* m_storage;
62 
65 
66 protected:
73  TypedArgument(std::string description, ST* storage) :
74  Argument(std::move(description)), m_storage(storage) {
75  m_max = (multi?0:1);
76  }
77 
86  TypedArgument(std::string description, char flag, ST* storage) :
87  Argument(std::move(description), flag), m_storage(storage) {
88  m_max = (multi?0:1);
89  }
90 
99  TypedArgument(std::string description, const std::string& name, ST* storage) :
100  Argument(std::move(description), name), m_storage(storage) {
101  m_max = (multi?0:1);
102  }
103 
113  TypedArgument(std::string description, char flag, const std::string& name, ST* storage) :
114  Argument(std::move(description), flag, name), m_storage(storage) {
115  m_max = (multi?0:1);
116  }
117 
118 public:
122  void set() const override = 0;
123 
127  bool takes_value() const override = 0;
128 
133  const ST& value() const {
134  return *m_storage;
135  }
136 
141  m_typedCheckFunc = typedCheckFunc;
142  return *this;
143  }
144 
148  std::unique_ptr<BaseArgument> clone() const & override = 0;
149 
153  std::unique_ptr<BaseArgument> clone() && override = 0;
154 
155 protected:
159  template<bool m = multi>
160  typename std::enable_if<!m>::type
161  check() const override {
162  if (m_typedCheckFunc != nullptr) {
163  m_typedCheckFunc(*this, *m_storage );
164  }
165  }
166 
170  template<bool m = multi>
171  typename std::enable_if<m>::type
172  check() const override {
173  if (m_typedCheckFunc != nullptr) {
174  m_typedCheckFunc(*this, (*m_storage)[m_storage->size()-1] );
175  }
176  }
177 };
178 
183 template<typename T, bool multi = false>
184 class VariableArgument : public TypedArgument<T, multi>, public ValueAcceptor {
185  static_assert(!std::is_void<T>::value, "Cannot make void arguments, use Argument");
186 
187 protected:
189  using ST = typename TypedArgument<T, multi>::ST;
190 
192  std::string m_valueName = std::string("value");
193 
194 public:
201  VariableArgument(std::string description, ST* storage) :
202  TypedArgument<T, multi>(std::move(description), storage) {
203  }
204 
213  VariableArgument(std::string description, char flag, ST* storage) :
214  TypedArgument<T, multi>(std::move(description), flag, storage) {
215  }
216 
225  VariableArgument(std::string description, const std::string& name, ST* storage) :
226  TypedArgument<T, multi>(std::move(description), name, storage) {
227  }
228 
238  VariableArgument(std::string description, char flag, const std::string& name, ST* storage) :
239  TypedArgument<T, multi>(std::move(description), flag, name, storage) {
240  }
241 
248  VariableArgument(std::string description, ST& storage) :
249  TypedArgument<T, multi>(std::move(description), &storage) {
250  }
251 
260  VariableArgument(std::string description, char flag, ST& storage) :
261  TypedArgument<T, multi>(std::move(description), flag, &storage) {
262  }
263 
272  VariableArgument(std::string description, const std::string& name, ST& storage) :
273  TypedArgument<T, multi>(std::move(description), name, &storage) {
274  }
275 
285  VariableArgument(std::string description, char flag, const std::string& name, ST& storage) :
286  TypedArgument<T, multi>(std::move(description), flag, name, &storage) {
287  }
288 
292  virtual ~VariableArgument() = default;
293 
297  VariableArgument(const VariableArgument&) = default;
298 
302  VariableArgument(VariableArgument&&) = default;
303 
307  VariableArgument& operator=(const VariableArgument&) = default;
308 
313 
317  std::unique_ptr<BaseArgument> clone() const & override {
318  return std::unique_ptr<BaseArgument>(new VariableArgument(*this));
319  }
320 
324  std::unique_ptr<BaseArgument> clone() && override {
325  return std::unique_ptr<BaseArgument>(new VariableArgument(std::move(*this)));
326  }
327 
334  VariableArgument& valuename(const std::string& valueName) {
335  m_valueName = valueName;
336  return *this;
337  }
338 
344  const std::string& valuename() {
345  return m_valueName;
346  }
347 
351  bool takes_value() const override {
352  return !std::is_same<bool, T>::value;
353  }
354 
358  void set() const override;
359 
363  void set(const std::string& value) const override;
364 
368  std::string usage() const override;
369 
373  std::string ident() const override;
374 };
375 
381 template<typename T>
383 
388 template<typename T, bool multi = false>
389 class ValueArgument : public VariableArgument<T, multi> {
390 protected:
393 
395  std::shared_ptr<ST> m_ownStorage;
396 
397 public:
404  template<typename... U, typename = typename std::enable_if< std::is_constructible<ST, U...>::value >::type >
405  ValueArgument(std::string description, U&&... params) :
406  VariableArgument<T, multi>(std::move(description), new ST(std::forward<U>(params)...)),
408  {
409  }
410 
419  template<typename... U, typename = typename std::enable_if< std::is_constructible<ST, U...>::value >::type>
420  ValueArgument(std::string description, char flag, U&&... params) :
421  VariableArgument<T, multi>(std::move(description), flag, new ST(std::forward<U>(params)...)),
423  {
424  }
425 
434  template<typename... U, typename = typename std::enable_if< std::is_constructible<ST, U...>::value >::type >
435  ValueArgument(std::string description, const std::string& name, U&&... params) :
436  VariableArgument<T, multi>(std::move(description), name, new ST(std::forward<U>(params)...)),
438  {
439  }
440 
450  template<typename... U, typename = typename std::enable_if< std::is_constructible<ST, U...>::value >::type >
451  ValueArgument(std::string description, char flag, const std::string& name, U&&... params) :
452  VariableArgument<T, multi>(std::move(description), flag, name, new ST(std::forward<U>(params)...)),
454  {
455  }
456 
460  virtual ~ValueArgument() = default;
461 
465  ValueArgument(const ValueArgument&) = default;
466 
470  ValueArgument(ValueArgument&&) = default;
471 
477  ValueArgument& operator=(const ValueArgument&) = default;
478 
482  ValueArgument& operator=(ValueArgument&&) = default;
483 
487  std::unique_ptr<BaseArgument> clone() const & override {
488  return std::unique_ptr<BaseArgument>(new ValueArgument(*this));
489  }
490 
494  std::unique_ptr<BaseArgument> clone() && override {
495  return std::unique_ptr<BaseArgument>(new ValueArgument(std::move(*this)));
496  }
497 };
498 
504 template<typename T>
506 
512 template<typename T>
514 protected:
517 
518 public:
519 #ifdef TAP_AUTOFLAG
520 
528  ConstArgument(std::string description, T& storage, const T& value) :
529  TypedArgument<T, false>(std::move(description), &storage), m_value(value) {
530  }
531 #endif
532 
541  ConstArgument(std::string description, char flag, T& storage, const T& value) :
542  TypedArgument<T, false>(std::move(description), flag, &storage), m_value(value) {
543  }
544 
553  ConstArgument(std::string description, const std::string& name, T& storage, const T& value) :
554  TypedArgument<T, false>(std::move(description), name, &storage), m_value(value) {
555  }
556 
566  ConstArgument(std::string description, char flag, const std::string& name, T& storage, const T& value) :
567  TypedArgument<T, false>(std::move(description), flag, name, &storage), m_value(value) {
568  }
569 
573  ConstArgument(const ConstArgument&) = default;
577  ConstArgument(ConstArgument&&) = default;
578 
582  virtual ~ConstArgument() {
583  }
584 
588  ConstArgument& operator=(const ConstArgument& other) = default;
589 
593  ConstArgument& operator=(ConstArgument&& other) = default;
594 
598  bool takes_value() const override {
599  return false;
600  }
601 
605  void set() const override {
606  Argument::set();
608  }
609 
613  std::unique_ptr<BaseArgument> clone() const & override {
614  return std::unique_ptr<BaseArgument>(new ConstArgument(*this));
615  }
616 
620  std::unique_ptr<BaseArgument> clone() && override {
621  return std::unique_ptr<BaseArgument>(new ConstArgument(std::move(*this)));
622  }
623 };
624 
632 protected:
634  std::shared_ptr<bool> m_ownStorage;
635 
636 public:
638  // Constructors for storing value externally
640 #ifdef TAP_AUTOFLAG
641 
648  SwitchArgument(std::string description, bool& storage) :
649  TypedArgument<bool, false>(std::move(description), &storage) {
650  }
651 #endif
652 
660  SwitchArgument(std::string description, char flag, bool& storage) :
661  TypedArgument<bool, false>(std::move(description), flag, &storage) {
662  }
663 
671  SwitchArgument(std::string description, const std::string& name, bool& storage) :
672  TypedArgument<bool, false>(std::move(description), name, &storage) {
673  }
674 
683  SwitchArgument(std::string description, char flag, const std::string& name, bool& storage) :
684  TypedArgument<bool, false>(std::move(description), flag, name, &storage) {
685  }
686 
688  // Constructors for storing value internally
690 #ifdef TAP_AUTOFLAG
691 
697  SwitchArgument(std::string description) :
698  TypedArgument<bool, false>(std::move(description), new bool()) {
699  }
700 #endif
701 
708  SwitchArgument(std::string description, char flag) :
709  TypedArgument<bool, false>(std::move(description), flag, new bool()),
710  m_ownStorage(TypedArgument<bool, false>::m_storage) {
711  }
712 
719  SwitchArgument(std::string description, const std::string& name) :
720  TypedArgument<bool, false>(std::move(description), name, new bool()),
721  m_ownStorage(TypedArgument<bool, false>::m_storage) {
722  }
723 
731  SwitchArgument(std::string description, char flag, const std::string& name) :
732  TypedArgument<bool, false>(std::move(description), flag, name, new bool()),
733  m_ownStorage(TypedArgument<bool, false>::m_storage) {
734  }
735 
739  SwitchArgument(const SwitchArgument&) = default;
740 
744  SwitchArgument(SwitchArgument&&) = default;
745 
749  virtual ~SwitchArgument() {}
750 
754  SwitchArgument& operator=(const SwitchArgument& other) = default;
755 
759  SwitchArgument& operator=(SwitchArgument&& other) = default;
760 
764  bool takes_value() const override {
765  return false;
766  }
767 
771  void set() const override {
772  Argument::set();
774  }
775 
779  std::unique_ptr<BaseArgument> clone() const & override {
780  return std::unique_ptr<BaseArgument>(new SwitchArgument(*this));
781  }
782 
786  std::unique_ptr<BaseArgument> clone() && override {
787  return std::unique_ptr<BaseArgument>(new SwitchArgument(std::move(*this)));
788  }
789 };
790 
791 
792 }
793 
794 
bool takes_value() const override
See Argument::takes_value()
Definition: TypedArgument.hpp:764
VariableArgument(std::string description, char flag, const std::string &name, ST *storage)
Create a VariableArgument with given description and storage pointer, aliased to the given flag and n...
Definition: TypedArgument.hpp:238
SwitchArgument(std::string description)
Create a switch argument with aliases defined by the description, using an internal variable to store...
Definition: TypedArgument.hpp:697
const std::string & valuename()
Return a human readable description for the value, used when describing the argument.
Definition: TypedArgument.hpp:344
VariableArgument(std::string description, const std::string &name, ST *storage)
Create a VariableArgument with given description and storage pointer, aliased to the given name...
Definition: TypedArgument.hpp:225
TypedArgument(std::string description, const std::string &name, ST *storage)
Create a TypedArgument with given description and storage pointer, aliased to the given name...
Definition: TypedArgument.hpp:99
virtual TypedArgument & check(TypedArgumentCheckFunc< T, multi > typedCheckFunc)
See Argument::check()
Definition: TypedArgument.hpp:140
ConstArgument(std::string description, const std::string &name, T &storage, const T &value)
Create a constant argument that is identified by a name, using an external variable to store a predef...
Definition: TypedArgument.hpp:553
virtual ~ValueArgument()=default
ValueArgument destructor.
virtual ~ConstArgument()
ConstArgument destructor.
Definition: TypedArgument.hpp:582
bool takes_value() const override=0
See Argument::takes_value()
TypedArgument(std::string description, ST *storage)
Create a TypedArgument with given description and storage pointer.
Definition: TypedArgument.hpp:73
ValueArgument(std::string description, U &&...params)
Create a positional ValueArgument using an internal variable to store the value.
Definition: TypedArgument.hpp:405
std::enable_if< m >::type check() const override
See Argument::check()
Definition: TypedArgument.hpp:172
VariableArgument(std::string description, char flag, const std::string &name, ST &storage)
Create a VariableArgument with given description and storage reference, aliased to the given flag and...
Definition: TypedArgument.hpp:285
std::string ident() const override
See Argument::ident()
std::unique_ptr< BaseArgument > clone() const &override=0
See BaseArgument::clone().
SwitchArgument(std::string description, char flag, bool &storage)
Create a switch argument that is identified by a flag, using an external variable to store the value...
Definition: TypedArgument.hpp:660
std::shared_ptr< ST > m_ownStorage
If the ValueArgument owns the variable storage, it is stored here.
Definition: TypedArgument.hpp:395
std::unique_ptr< BaseArgument > clone() const &override
See BaseArgument::clone().
Definition: TypedArgument.hpp:317
VariableArgument(std::string description, ST *storage)
Create a VariableArgument with given description and storage pointer.
Definition: TypedArgument.hpp:201
VariableArgument(std::string description, char flag, ST &storage)
Create a VariableArgument with given description and storage reference, aliased to the given flag...
Definition: TypedArgument.hpp:260
ValueArgument(std::string description, const std::string &name, U &&...params)
Create a ValueArgument using an internal variable to store the value, aliased to the given flag...
Definition: TypedArgument.hpp:435
Base argument class, used both by actual Argument classes and constraints (ArgumentConstraint).
Definition: BaseArgument.hpp:40
std::unique_ptr< BaseArgument > clone()&&override
See BaseArgument::clone().
Definition: TypedArgument.hpp:620
ST * m_storage
Pointer to value storage.
Definition: TypedArgument.hpp:61
SwitchArgument(std::string description, char flag)
Create a switch argument that is identified by a flag, using an external variable to store the value...
Definition: TypedArgument.hpp:708
std::unique_ptr< BaseArgument > clone() const &override
See BaseArgument::clone().
Definition: TypedArgument.hpp:779
Simple argument class.
Definition: Argument.hpp:48
unsigned int m_max
Maximum number of occurrences.
Definition: Argument.hpp:64
typename VariableArgument< T, multi >::ST ST
Make TypedArgument::ST accessible.
Definition: TypedArgument.hpp:392
SwitchArgument(std::string description, const std::string &name, bool &storage)
Create a switch argument that is identified by a name, using an external variable to store the value...
Definition: TypedArgument.hpp:671
TypedArgument(std::string description, char flag, const std::string &name, ST *storage)
Create a TypedArgument with given description and storage pointer, aliased to the given flag and name...
Definition: TypedArgument.hpp:113
SwitchArgument(std::string description, char flag, const std::string &name)
Create a switch argument that is identified by both a flag and a name, using an external variable to ...
Definition: TypedArgument.hpp:731
std::unique_ptr< BaseArgument > clone()&&override
See BaseArgument::clone().
Definition: TypedArgument.hpp:786
std::function< void(const TypedArgument< T, multi > &, const T &value)> TypedArgumentCheckFunc
Function pointer that is used by ValueArgument::check()
Definition: TypedArgument.hpp:36
VariableArgument & valuename(const std::string &valueName)
Assign a human readable description for the value, used when describing the argument.
Definition: TypedArgument.hpp:334
bool takes_value() const override
See Argument::takes_value()
Definition: TypedArgument.hpp:598
std::shared_ptr< bool > m_ownStorage
If the SwitchArgument owns the variable storage, it is stored here.
Definition: TypedArgument.hpp:634
std::enable_if<!m >::type check() const override
See Argument::check()
Definition: TypedArgument.hpp:161
T m_value
Constant to store.
Definition: TypedArgument.hpp:516
ConstArgument(std::string description, char flag, T &storage, const T &value)
Create a constant argument that is identified by a flag, using an external variable to store a predef...
Definition: TypedArgument.hpp:541
void set() const override=0
See Argument::set()
const ST & value() const
Returns the value of this argument.
Definition: TypedArgument.hpp:133
Interface class for arguments that accept a value when takes_value() is true.
Definition: Argument.hpp:535
std::string m_valueName
Name of the accepted value, used in the identifier.
Definition: TypedArgument.hpp:192
bool takes_value() const override
See Argument::takes_value()
Definition: TypedArgument.hpp:351
virtual ~VariableArgument()=default
VariableArgument destructor.
std::unique_ptr< BaseArgument > clone()&&override
See BaseArgument::clone().
Definition: TypedArgument.hpp:494
ValueArgument(std::string description, char flag, const std::string &name, U &&...params)
Create a ValueArgument using an internal variable to store the value, aliased to the given flag and n...
Definition: TypedArgument.hpp:451
const std::string & description() const
Returns the description of this argument.
Definition: Argument.hpp:208
typename TypedArgument< T, multi >::ST ST
Make TypedArgument::ST accessible.
Definition: TypedArgument.hpp:189
Base class for arguments that hold a typed value.
Definition: TypedArgument.hpp:32
std::unique_ptr< BaseArgument > clone()&&override
See BaseArgument::clone().
Definition: TypedArgument.hpp:324
virtual ~SwitchArgument()
SwitchArgument destructor.
Definition: TypedArgument.hpp:749
std::unique_ptr< BaseArgument > clone() const &override
See BaseArgument::clone().
Definition: TypedArgument.hpp:487
std::string usage() const override
See Argument::usage()
VariableArgument(std::string description, char flag, ST *storage)
Create a VariableArgument with given description and storage pointer, aliased to the given flag...
Definition: TypedArgument.hpp:213
Concrete implementation of TypedArgument.
Definition: TypedArgument.hpp:184
TypedArgumentCheckFunc< T, multi > m_typedCheckFunc
Callback for typed check.
Definition: TypedArgument.hpp:64
VariableArgument(std::string description, const std::string &name, ST &storage)
Create a VariableArgument with given description and storage reference, aliased to the given name...
Definition: TypedArgument.hpp:272
std::unique_ptr< BaseArgument > clone() const &override
See BaseArgument::clone().
Definition: TypedArgument.hpp:613
ConstArgument(std::string description, T &storage, const T &value)
Create a constant argument with aliases defined by the description, using an external variable to sto...
Definition: TypedArgument.hpp:528
SwitchArgument(std::string description, bool &storage)
Create a switch argument with aliases defined by the description, using an external variable to store...
Definition: TypedArgument.hpp:648
SwitchArgument(std::string description, const std::string &name)
Create a switch argument that is identified by a name, using an external variable to store the value...
Definition: TypedArgument.hpp:719
ValueArgument(std::string description, char flag, U &&...params)
Create a ValueArgument using an internal variable to store the value, aliased to the given flag...
Definition: TypedArgument.hpp:420
VariableArgument & operator=(const VariableArgument &)=default
VariableArgument copy assignment operator.
SwitchArgument(std::string description, char flag, const std::string &name, bool &storage)
Create a switch argument that is identified by both a flag and a name, using an external variable to ...
Definition: TypedArgument.hpp:683
ValueArgument & operator=(const ValueArgument &)=default
ValueArgument copy assignment operator.
typename std::conditional< !multi, T, std::vector< T > >::type ST
Alias for the storage type (which is a vector for MultiValueArgument types)
Definition: TypedArgument.hpp:58
TypedArgument(std::string description, char flag, ST *storage)
Create a TypedArgument with given description and storage pointer, aliased to the given flag...
Definition: TypedArgument.hpp:86
Specialization of TypedArgument that acts as a switch on the command line, but stores an arbitrary co...
Definition: TypedArgument.hpp:513
VariableArgument(std::string description, ST &storage)
Create a VariableArgument with given description and storage reference.
Definition: TypedArgument.hpp:248
Implementation of TypedArgument that stores a value by itself, based on VariableArgument.
Definition: TypedArgument.hpp:389
void set() const override
See Argument::set()
Definition: TypedArgument.hpp:605
SwitchArgument is a specialization for TypedArgument, which does not accept values (it switches)...
Definition: TypedArgument.hpp:631
ConstArgument(std::string description, char flag, const std::string &name, T &storage, const T &value)
Create a constant argument that is identified by both a flag and a name, using an external variable t...
Definition: TypedArgument.hpp:566
virtual void set() const
Set the argument (mark as occurred).
Definition: Argument.hpp:370
void set() const override
Calling this function is an error, call set(std::string) instead.
void set() const override
See Argument::set()
Definition: TypedArgument.hpp:771