Flow123d  last_with_con_2.0.0-4-g42e6930
type_abstract.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file type_abstract.hh
15  * @brief
16  */
17 
18 #ifndef TYPE_ABSTRACT_HH_
19 #define TYPE_ABSTRACT_HH_
20 
21 #include "system/exceptions.hh"
22 
23 #include "type_base.hh"
24 #include "type_selection.hh"
25 
26 
27 namespace Input {
28 namespace Type {
29 
30 
31 
32 /**
33  * @brief Class for declaration of polymorphic Record.
34  *
35  * Like the Record class this is only proxy class. It allows add Record as descendants, but
36  * further there is method \p no_more_descendants to close adding them. After this
37  * you can not derive any Record from this Abstract.
38  *
39  *
40  *
41  * A static method (typically part of an abstract class) for construction of an AbstractType can look like:
42  *
43  @code
44  static Input::Type::Abstract &SomeAbstractClass::get_input_type() {
45  using namespace Input::Type;
46  return Abstract("Function", "Input for generic time-space function.")
47  .close();
48  }
49  @endcode
50  *
51  * @ingroup input_types
52  */
53 class Abstract : public TypeBase {
54  friend class OutputBase;
55  //friend class Record;
56  friend class AdHocAbstract;
57 
58 protected:
59 
60  /**
61  * @brief Actual data of the abstract record.
62  */
63  class ChildData {
64  public:
65  /// Constructor
66  ChildData(const string &name, const string &description)
67  : selection_of_childs( std::make_shared<Selection> (name + "_TYPE_selection") ),
68  description_(description),
69  type_name_(name),
70  finished_(false),
71  closed_(false),
72  selection_default_(Default::obligatory())
73  {}
74 
75  /**
76  * @brief Selection composed from names of derived Records.
77  *
78  * Indices are according to the order of derivation (starting from zero).
79  */
80  std::shared_ptr< Selection> selection_of_childs;
81 
82  /// Vector of derived Records (proxies) in order of derivation.
84 
85  /// Description of the whole Abstract type.
86  const string description_;
87 
88  /// type_name of the whole Abstract type.
89  const string type_name_;
90 
91  /// Abstract is finished when it has added all descendant records.
92  bool finished_;
93 
94  /// If Abstract is closed, we do not allow any further declaration calls.
95  bool closed_;
96 
97  /**
98  * @brief Default value of selection_of_childs (used for automatic conversion).
99  *
100  * If default value isn't set, selection_default_ is set to obligatory.
101  */
103 
104  /**
105  * Allow store hash of part of generic subtree.
106  *
107  * This hash can be typically used if descendants of Abstract contains different
108  * structure of parameter location.
109  * For example we have have Records with key represents generic part of subtree:
110  * - in first descendant this key is of the type Parameter
111  * - in second descendant this key is of the type Array of Parameter
112  * - in third descendant this key is of the type Array of Parameter with fixed size
113  * etc.
114  */
115  //TypeHash generic_content_hash_;
116 
117  };
118 
119 public:
120  /// Public typedef of constant iterator into array of keys.
122 
123  /// Default constructor.
124  Abstract();
125 
126  /**
127  * @brief Copy constructor.
128  *
129  * We check that other is non empty.
130  */
131  Abstract(const Abstract& other);
132 
133 
134  /**
135  * @brief Basic constructor.
136  *
137  * You has to provide \p type_name of the new declared Abstract type and its \p description.
138  */
139  Abstract(const string & type_name_in, const string & description);
140 
141  /**
142  * @brief Implements @p TypeBase::content_hash.
143  *
144  * Hash is calculated by type name, description and hash of attributes.
145  */
146  TypeHash content_hash() const override;
147 
148  /**
149  * @brief Allows shorter input of the Abstract providing the default value to the "TYPE" key.
150  *
151  * If the input reader come across the Abstract in the declaration tree and the input
152  * is not 'record-like' with specified value for TYPE, it tries to use the descendant Record specified by
153  * @p type_default parameter of this method. Further auto conversion of such Record may be possible.
154  */
155  Abstract &allow_auto_conversion(const string &type_default);
156 
157  /// Can be used to close the Abstract for further declarations of keys.
158  Abstract &close();
159 
160  /**
161  * Mark the type to be root of a generic subtree.
162  * Such type can not appear in IST directly but only as the internal type
163  * of the Instance auxiliary object.
164  */
166 
167  /// Frontend to TypeBase::add_attribute_
168  Abstract &add_attribute(std::string key, TypeBase::json_string value);
169 
170  /**
171  * @brief Finish declaration of the Abstract type.
172  *
173  * Set Abstract as parent of derived Records (for mechanism of
174  * set parent and descendant see \p Record::derive_from)
175  */
176  bool finish(bool is_generic = false) override;
177 
178  /// Returns reference to the inherited Record with given name.
179  const Record &get_descendant(const string& name) const;
180 
181  /**
182  * @brief Returns default descendant.
183  *
184  * Returns only if TYPE key has default value, otherwise returns empty Record.
185  */
186  const Record * get_default_descendant() const;
187 
188  /// Returns reference to Selection type of the implicit key TYPE.
189  const Selection &get_type_selection() const;
190 
191  /// Returns number of descendants in the child_data_.
192  unsigned int child_size() const;
193 
194  /// Implements @p TypeBase::is_finished.
195  virtual bool is_finished() const override;
196 
197  /// Returns true if @p data_ is closed.
198  virtual bool is_closed() const override;
199 
200  /**
201  * @brief Implements @p Type::TypeBase::type_name.
202  *
203  * Name corresponds to @p data_->type_name_.
204  */
205  virtual string type_name() const override;
206  /// Override @p Type::TypeBase::class_name.
207  string class_name() const override { return "Abstract"; }
208 
209  /**
210  * @brief Container-like access to the descendants of the Abstract.
211  *
212  * Returns iterator to the first data.
213  */
214  ChildDataIter begin_child_data() const;
215 
216  /**
217  * @brief Container-like access to the descendants of the Abstract.
218  *
219  * Returns iterator to the last data.
220  */
221  ChildDataIter end_child_data() const;
222 
223  /**
224  * @brief Add inherited Record.
225  *
226  * This method is used primarily in combination with registration variable. @see Input::Factory
227  *
228  * Example of usage:
229  @code
230  class SomeBase
231  {
232  public:
233  /// the specification of input abstract record
234  static const Input::Type::Abstract & get_input_type();
235  ...
236  }
237 
238  class SomeDescendant : public SomeBase
239  {
240  public:
241  /// the specification of input record
242  static const Input::Type::Record & get_input_type();
243  ...
244  private:
245  /// registers class to factory
246  static const int reg;
247  }
248 
249  /// implementation of registration variable
250  const int SomeDescendant::reg =
251  Input::register_class< SomeDescendant >("SomeDescendant") +
252  SomeBase::get_input_type().add_child(SomeDescendant::get_input_type());
253  @endcode
254  */
255  int add_child(const Record &subrec);
256 
257  // Get default value of selection_of_childs
259 
260  // Implements @p TypeBase::make_instance.
262 
263 
264 
265 
266 protected:
267  /// Create deep copy of Abstract (copy all data stored in shared pointers etc.)
268  Abstract deep_copy() const;
269 
270  /// Check if type has set value of default descendants.
271  bool have_default_descendant() const;
272 
273  /// Actual data of the Abstract.
274  std::shared_ptr<ChildData> child_data_;
275 
276  friend class Record;
277 };
278 
279 
280 /** ******************************************************************************************************************************
281  * @brief Class for declaration of polymorphic Record.
282  *
283  * Abstract extends on list of descendants provided immediately
284  * after construction by add_child(). These descendants derive
285  * only keys from common AR. AdHocAR has separate instance for every
286  * key of this type.
287  *
288  * @ingroup input_types
289  */
290 class AdHocAbstract : public Abstract {
291  friend class OutputBase;
292 public:
293  /// Constructor
294  AdHocAbstract(const Abstract &ancestor);
295 
296  /**
297  * @brief Implements @p TypeBase::content_hash.
298  *
299  * Hash is calculated by type name, description and name of ancestor.
300  */
301  TypeHash content_hash() const override;
302 
303  /// Override @p Type::TypeBase::class_name.
304  string class_name() const override { return "AdHocAbstract"; }
305 
306 
307  /**
308  * @brief Finish declaration of the AdHocAbstract type.
309  *
310  * Adds descendants of ancestor Abstract, calls close() and complete keys with non-null
311  * pointers to lazy types.
312  */
313  bool finish(bool is_generic = false) override;
314 
315  /// Add inherited Record.
316  AdHocAbstract &add_child(const Record &subrec);
317 
318 protected:
319  /// Reference to ancestor Abstract
321 };
322 
323 
324 
325 } // closing namespace Type
326 } // closing namespace Input
327 
328 
329 
330 
331 #endif /* TYPE_ABSTRACT_HH_ */
virtual bool is_finished() const override
Implements TypeBase::is_finished.
const string description_
Description of the whole Abstract type.
const Record & get_descendant(const string &name) const
Returns reference to the inherited Record with given name.
Base of classes for declaring structure of the input data.
Definition: type_base.hh:79
Abstract & allow_auto_conversion(const string &type_default)
Allows shorter input of the Abstract providing the default value to the "TYPE" key.
Abstract deep_copy() const
Create deep copy of Abstract (copy all data stored in shared pointers etc.)
std::vector< Record >::const_iterator ChildDataIter
Public typedef of constant iterator into array of keys.
string class_name() const override
Override Type::TypeBase::class_name.
Abstract()
Default constructor.
virtual MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:50
std::pair< std::shared_ptr< TypeBase >, ParameterMap > MakeInstanceReturnType
Return type of make_instance methods, contains instance of generic type and map of used parameters...
Definition: type_base.hh:97
Base abstract class for output description of the Input::Type tree.
Definition: type_output.hh:58
virtual string type_name() const override
Implements Type::TypeBase::type_name.
Class for declaration of polymorphic Record.
Actual data of the abstract record.
Abstract & close()
Can be used to close the Abstract for further declarations of keys.
Abstract & add_attribute(std::string key, TypeBase::json_string value)
Frontend to TypeBase::add_attribute_.
virtual bool is_closed() const override
Returns true if data_ is closed.
const Abstract & ancestor_
Reference to ancestor Abstract.
bool closed_
If Abstract is closed, we do not allow any further declaration calls.
unsigned int child_size() const
Returns number of descendants in the child_data_.
Default & get_selection_default() const
bool finish(bool is_generic=false) override
Finish declaration of the Abstract type.
vector< Record > list_of_childs
Vector of derived Records (proxies) in order of derivation.
const Record * get_default_descendant() const
Returns default descendant.
Class for declaration of polymorphic Record.
ChildDataIter begin_child_data() const
Container-like access to the descendants of the Abstract.
const Selection & get_type_selection() const
Returns reference to Selection type of the implicit key TYPE.
int add_child(const Record &subrec)
Add inherited Record.
Abstract & root_of_generic_subtree()
bool have_default_descendant() const
Check if type has set value of default descendants.
Default selection_default_
Default value of selection_of_childs (used for automatic conversion).
ChildData(const string &name, const string &description)
Constructor.
string class_name() const override
Override Type::TypeBase::class_name.
const string type_name_
type_name of the whole Abstract type.
bool finished_
Abstract is finished when it has added all descendant records.
ChildDataIter end_child_data() const
Container-like access to the descendants of the Abstract.
std::string json_string
String stored in JSON format.
Definition: type_base.hh:85
friend class AdHocAbstract
Record type proxy class.
Definition: type_record.hh:171
std::shared_ptr< ChildData > child_data_
Actual data of the Abstract.
std::shared_ptr< Selection > selection_of_childs
Selection composed from names of derived Records.
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:82
Template for classes storing finite set of named values.