Flow123d  last_with_con_2.0.0-663-gd0e2296
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),
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.
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  /// Close the Abstract and add its to type repository (see @p TypeRepository::add_type).
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_
169 
170  /**
171  * @brief Finish declaration of the Abstract type.
172  *
173  * Checks if Abstract is closed and completes Abstract (check default descendant, parameters of generic types etc).
174  */
175  FinishStatus finish(FinishStatus finish_type = FinishStatus::regular_) override;
176 
177  /// Returns reference to the inherited Record with given name.
178  const Record &get_descendant(const string& name) const;
179 
180  /**
181  * @brief Returns default descendant.
182  *
183  * Returns only if TYPE key has default value, otherwise returns empty Record.
184  */
185  const Record * get_default_descendant() const;
186 
187  /// Returns reference to Selection type of the implicit key TYPE.
188  const Selection &get_type_selection() const;
189 
190  /// Returns number of descendants in the child_data_.
191  unsigned int child_size() const;
192 
193  /// Implements @p TypeBase::finish_status.
194  virtual FinishStatus finish_status() const override;
195 
196  /// Implements @p TypeBase::is_finished.
197  virtual bool is_finished() const override;
198 
199  /// Returns true if @p data_ is closed.
200  virtual bool is_closed() const override;
201 
202  /**
203  * @brief Implements @p Type::TypeBase::type_name.
204  *
205  * Name corresponds to @p data_->type_name_.
206  */
207  virtual string type_name() const override;
208  /// Override @p Type::TypeBase::class_name.
209  string class_name() const override { return "Abstract"; }
210 
211  /**
212  * @brief Container-like access to the descendants of the Abstract.
213  *
214  * Returns iterator to the first data.
215  */
216  ChildDataIter begin_child_data() const;
217 
218  /**
219  * @brief Container-like access to the descendants of the Abstract.
220  *
221  * Returns iterator to the last data.
222  */
223  ChildDataIter end_child_data() const;
224 
225  /**
226  * @brief Add inherited Record.
227  *
228  * Do not use this method for set Record as descendant! For this case should be used \p Record::derive_from
229  * method in generating function of Record.
230  *
231  * This method is used primarily for registration of Record during its closing.
232  */
233  int add_child(Record &subrec);
234 
235  // Get default value of selection_of_childs
237 
238  // Implements @p TypeBase::make_instance.
240 
241 
242 
243 
244 protected:
245  /// Create deep copy of Abstract (copy all data stored in shared pointers etc.)
246  Abstract deep_copy() const;
247 
248  /// Check if type has set value of default descendants.
249  bool have_default_descendant() const;
250 
251  /// Actual data of the Abstract.
252  std::shared_ptr<ChildData> child_data_;
253 
254  friend class Record;
255 };
256 
257 
258 /** ******************************************************************************************************************************
259  * @brief Class for declaration of polymorphic Record.
260  *
261  * Abstract extends on list of descendants provided immediately
262  * after construction by add_child(). These descendants derive
263  * only keys from common AR. AdHocAR has separate instance for every
264  * key of this type.
265  *
266  * @ingroup input_types
267  */
268 class AdHocAbstract : public Abstract {
269  friend class OutputBase;
270 public:
271  /// Constructor
272  AdHocAbstract(const Abstract &ancestor);
273 
274  /**
275  * @brief Implements @p TypeBase::content_hash.
276  *
277  * Hash is calculated by type name, description and name of ancestor.
278  */
279  TypeHash content_hash() const override;
280 
281  /// Override @p Type::TypeBase::class_name.
282  string class_name() const override { return "AdHocAbstract"; }
283 
284 
285  /**
286  * @brief Finish declaration of the AdHocAbstract type.
287  *
288  * Adds descendants of ancestor Abstract, calls close() and complete keys with non-null
289  * pointers to lazy types.
290  */
291  FinishStatus finish(FinishStatus finish_type = FinishStatus::regular_) override;
292 
293  /// Add inherited Record.
294  AdHocAbstract &add_child(Record &subrec);
295 
296 protected:
297  /// Reference to ancestor Abstract
299 };
300 
301 
302 
303 } // closing namespace Type
304 } // closing namespace Input
305 
306 
307 
308 
309 #endif /* TYPE_ABSTRACT_HH_ */
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:93
virtual bool is_closed() const override
Returns true if data_ is closed.
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.
Abstract()
Default constructor.
virtual MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
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:111
Base abstract class for output description of the Input::Type tree.
Definition: type_output.hh:58
string class_name() const override
Override Type::TypeBase::class_name.
Class for declaration of polymorphic Record.
Actual data of the abstract record.
Abstract & close()
Close the Abstract and add its to type repository (see TypeRepository::add_type). ...
Abstract & add_attribute(std::string key, TypeBase::json_string value)
Frontend to TypeBase::add_attribute_.
FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_) override
Finish declaration of the Abstract type.
virtual bool is_finished() const override
Implements TypeBase::is_finished.
const Abstract & ancestor_
Reference to ancestor Abstract.
bool closed_
If Abstract is closed, we do not allow any further declaration calls.
static constexpr bool value
Definition: json.hpp:87
unsigned int child_size() const
Returns number of descendants in the child_data_.
string class_name() const override
Override Type::TypeBase::class_name.
int add_child(Record &subrec)
Add inherited Record.
Default & get_selection_default() const
TypeHash content_hash() const override
Implements TypeBase::content_hash.
virtual FinishStatus finish_status() const override
Implements TypeBase::finish_status.
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.
FinishStatus finish_status_
Abstract is finished when it has added all descendant records.
const Selection & get_type_selection() const
Returns reference to Selection type of the implicit key TYPE.
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.
const string type_name_
type_name of the whole Abstract type.
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:99
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:96
Template for classes storing finite set of named values.
virtual string type_name() const override
Implements Type::TypeBase::type_name.