IOption.hpp
1 #pragma once
2 
3 ///=============================================================================
4 /// \file
5 /// \brief Abstract option classes.
6 /// \author WK
7 /// \date 29.02.2020
8 ///=============================================================================
9 
10 #include <opals/fwd.hpp>
11 #include <opals/UsageLevel.hpp>
12 #include <opals/ValueSource.hpp>
13 #include <opals/OptionNames.hpp>
14 #include <type_traits>
15 
16 namespace opals
17 {
18  /// Contains the public interface of OPALS option types.
19  namespace opts
20  {
21 
22  /// Enumerates the main option types.
23  enum struct Nodes
24  {
25  value,
26  feed,
27  group,
28  vector,
29  array
30  };
31 
32  template<Names nam>
33  using NameT = std::integral_constant<Names, nam>;
34 
35  template<Nodes nod>
36  using NodeT = std::integral_constant<Nodes, nod>;
37 
38  /// Base class of all option types.
39  struct IBase
40  {
41  /// The option name as enumerator.
42  virtual Names enumerator() const = 0;
43  /// The option name as string.
44  virtual String name() const = 0;
45  /// The option name as string, preceded by the names of its parents, if any, interspersed with '.'
46  virtual String path() const = 0;
47  /// One-liner that describes this option.
48  virtual String shortDescription() const = 0;
49  /// Longer text that describes this option in more detail.
50  virtual String longDescription() const = 0;
51  /// For a leaf, this is its own usage level. Otherwise, this is the minimum usage level of all descendants: basic < mid < pro
52  virtual UsageLevel minUsageLevel() const = 0;
53  /// The node type of this option.
54  virtual Nodes node() const = 0;
55  };
56 
57  /// A leaf that holds a value
58  /** \tparam nam The value name.
59  \tparam cnst If true, then the value may not be changed.
60  \tparam T The value type. */
61  template<Names nam, bool cnst, class T>
62  struct IValue :
63  IBase
64  {
65  using Name = NameT<nam>;
66  using Node = NodeT<Nodes::value>;
67 
68  /// Frequency / expected skills of users that access this leaf.
69  virtual UsageLevel usageLevel() const = 0;
70  /// The context in which the value has been set.
71  virtual ValueSource valueSource() const = 0;
72  /// If its value has not been set, a leaf is considered empty.
73  /** Accessing its value then raises an exception. */
74  virtual bool empty() const = 0;
75  /// Returns !empty()
76  virtual explicit operator bool() const = 0;
77 
78  /// Get the value.
79  virtual const T& get() const = 0;
80  /// Get the value or default_ if empty.
81  virtual T getOr(T&& default_) const = 0;
82  virtual const T& getOr(const T& default_) const = 0;
83 
84  };
85 
86  /// A leaf that holds a read-write value
87  /** \tparam nam The value name.
88  \tparam T The value type. */
89  template<Names nam, class T>
90  struct IValue<nam, false, T> :
91  IValue<nam, true, T>
92  {
93  /// Set the value.
94  virtual void set(const T& value) = 0;
95  };
96 
97  /// A leaf that feeds values to its targets.
98  /** \tparam nam The feed name.
99  \tparam cnst If true, then no values can actually be fed.
100  \tparam T The value type. */
101  template<Names nam, bool cnst, class T>
102  struct IFeed :
103  IBase
104  {
105  using Name = NameT<nam>;
106  using Node = NodeT<Nodes::feed>;
107 
108  virtual Vector<T> get() const = 0;
109 
110  };
111 
112  /// A leaf that actually feeds values to its targets.
113  /** \tparam nam The feed name.
114  \tparam T The value type. */
115  template<Names nam, class T>
116  struct IFeed<nam, false, T> :
117  IFeed<nam, true, T>
118  {
119  /// Feed the values.
120  virtual void set(const Vector<T>& values) = 0;
121  };
122  }
123 }
124 
125 #include <opals/IAccess.hpp>
126 
127 namespace opals
128 {
129  namespace opts
130  {
131 
132  /// A group of options
133  /** \tparam nam The group name.
134  \tparam Opts The group members. */
135  template<Names nam, class... Opts>
136  struct IGroup :
137  IAcc<Opts...>
138  {
139  using Name = NameT<nam>;
140  using Node = NodeT<Nodes::group>;
141  };
142 
143  template<Names, bool, class...>
144  struct IVector;
145 
146  template<Names, size_t, class...>
147  struct IArray;
148 
149  namespace ifeed
150  {
151  template<class>
152  struct TypeT;
153 
154  template<class T>
155  using Type = typename TypeT<T>::Typ;
156 
157  template<Names nam, bool cnst, class T>
159  {
160  using Typ = IFeed<nam, cnst, T>;
161  };
162 
163  template<Names nam, bool cnst, class T>
164  struct TypeT<IFeed<nam, cnst, T>>
165  {
166  using Typ = IFeed<nam, cnst, T>;
167  };
168 
169  template<Names nam, class... Opts>
170  struct TypeT<IGroup<nam, Opts...>>
171  {
172  using Typ = IGroup<nam, Type<Opts>...>;
173  };
174 
175  template<Names nam, bool cnst, class... Opts>
176  struct TypeT<IVector<nam, cnst, Opts...>>
177  {
179  };
180 
181  template<Names nam, size_t n, class... Opts>
182  struct TypeT<IArray<nam, n, Opts...>>
183  {
184  using Typ = IArray<nam, n, Type<Opts>...>;
185  };
186  }
187 
188  template<class Cont>
189  class Iterator
190  {
191  Cont* cont_;
192  size_t pos_;
193  using Element_ = typename std::conditional<
194  std::is_const<Cont>::value,
195  typename std::add_const<typename Cont::Element>::type,
196  typename Cont::Element>::type;
197  public:
198  using iterator_category = std::input_iterator_tag;
199  using difference_type = ptrdiff_t;
200  using value_type = Element_;
201  using reference = value_type&;
202  using pointer = value_type*;
203 
204  Iterator(Cont* cont = nullptr, size_t pos = 0) : cont_(cont), pos_(pos) {}
205  operator Iterator<typename std::add_const<Cont>::type>() const { return { cont_, pos_ }; }
206  reference operator* () const { return (*cont_)[pos_]; }
207  pointer operator->() const { return &(*cont_)[pos_]; }
208  Iterator& operator++() { ++pos_; return *this; }
209  Iterator operator++(int) { Iterator res(*this); ++*this; return res; }
210  friend bool operator==(const Iterator& a, const Iterator& b) { return a.cont_ == b.cont_ && a.pos_ == b.pos_; };
211  friend bool operator!=(const Iterator& a, const Iterator& b) { return !(a == b); };
212  };
213 
214  /// A container of options.
215  /** \tparam nam The name of the container and its elements.
216  \tparam Opts The sequence of options that composes each element.
217  Provides access to specific elements by index, to the default-element, and to the feed-element. */
218  template<Names nam, class... Opts>
219  struct IContainer :
220  IBase
221  {
222  using Name = NameT<nam>;
223  using Element = IGroup<nam, Opts...>;
224  using Feed = ifeed::Type<Element>;
225 
226  /// The number of actual elements.
227  virtual size_t size() const = 0;
228  /// Returns size() == 0
229  virtual bool empty() const = 0;
230 
231  /// \name Access an actual element.
232  ///@{
233  virtual const Element& operator[](size_t idx) const = 0;
234  virtual Element& operator[](size_t idx) = 0;
235  ///@}
236 
237  /** \name Access the default element.
238  Changes to it are also applied immediately to all actual elements. */
239  ///@{
240  virtual const Element& all() const = 0;
241  virtual Element& all() = 0;
242  ///@}
243 
244  /** \name Access the feed element.
245  Values set on it are distributed over the actual elements and thereby define their number. */
246  ///@{
247  virtual const Feed& feed() const = 0;
248  virtual Feed& feed() = 0;
249  ///@}
250 
251  /// \name iterator traversal
252  ///@{
253  Iterator<IContainer> begin()
254  {
255  return { this };
256  }
257 
258  Iterator<const IContainer> begin() const
259  {
260  return { this };
261  }
262 
264  {
265  return { this, size() };
266  }
267 
268  Iterator<const IContainer> end() const
269  {
270  return { this, size() };
271  }
272  ///@}
273  };
274 
275  /// A vector of a variable number of options.
276  /** \tparam nam The name of the vector and its elements.
277  \tparam cnst If true, then this vector provides only constant access to its elements.
278  \tparam Opts The sequence of options that composes each element. */
279  template<Names nam, bool cnst, class... Opts>
280  struct IVector :
281  IContainer<nam, Opts...>
282  {
283  using Node = NodeT<Nodes::vector>;
284  };
285 
286  /// A vector of a variable number of read-write options.
287  template<Names nam, class... Opts>
288  struct IVector<nam, false, Opts...> :
289  IContainer<nam, Opts...>
290  {
291  using Node = NodeT<Nodes::vector>;
292  /// Set the number of elements. New elements are initialized with the default element.
293  virtual void resize(size_t size) = 0;
294  };
295 
296  /// An array of N options.
297  /** \tparam nam The name of the array and its elements.
298  \tparam cnst If true, then this array provides only constant access to its elements.
299  \tparam N The number of elements.
300  \tparam Opts The sequence of options that composes each element. */
301  template<Names nam, size_t n, class... Opts>
302  struct IArray :
303  IContainer<nam, Opts...>
304  {
305  using Node = NodeT<Nodes::array>;
306  };
307  }
308 }
virtual UsageLevel minUsageLevel() const =0
For a leaf, this is its own usage level. Otherwise, this is the minimum usage level of all descendant...
virtual ValueSource valueSource() const =0
The context in which the value has been set.
Nodes
Enumerates the main option types.
Definition: IOption.hpp:23
virtual size_t size() const =0
The number of actual elements.
virtual const T & get() const =0
Get the value.
virtual bool empty() const =0
Returns size() == 0.
Definition: IOption.hpp:152
A leaf that feeds values to its targets.
Definition: IOption.hpp:102
A leaf that holds a value.
Definition: IOption.hpp:62
A container of options.
Definition: IOption.hpp:219
virtual UsageLevel usageLevel() const =0
Frequency / expected skills of users that access this leaf.
Definition: IOption.hpp:189
virtual Nodes node() const =0
The node type of this option.
UsageLevel
Frequency of use / needed level of user experience of an option.
Definition: UsageLevel.hpp:8
virtual String shortDescription() const =0
One-liner that describes this option.
Contains the public interface of OPALS.
Definition: AbsValueOrQuantile.hpp:8
virtual T getOr(T &&default_) const =0
Get the value or default_ if empty.
ValueSource
Origin of an option value.
Definition: ValueSource.hpp:8
virtual String longDescription() const =0
Longer text that describes this option in more detail.
virtual bool empty() const =0
If its value has not been set, a leaf is considered empty.
Names
Enumerates all option names.
Definition: OptionNames.hpp:19
virtual String name() const =0
The option name as string.
An array of N options.
Definition: IOption.hpp:147
virtual Names enumerator() const =0
The option name as enumerator.
Mimics std::vector<T>
Definition: fwd.hpp:18
A group of options.
Definition: IOption.hpp:136
@ vector
General vector data file (las, shp, ..)
typename IAcc_< Opts... >::Type IAcc
The specialization of IAcc for the first member of a group.
Definition: IAccess.hpp:3927
virtual String path() const =0
The option name as string, preceded by the names of its parents, if any, interspersed with '....
A dynamic character string whose interface conforms to STL's std::string.
Definition: String.hpp:35
A vector of a variable number of options.
Definition: IOption.hpp:144
Base class of all option types.
Definition: IOption.hpp:39