Flow123d  last_with_con_2.0.0-2-g938dee8
type_repository.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_repository.hh
15  * @brief
16  */
17 
18 #ifndef TYPE_REPOSITORY_HH_
19 #define TYPE_REPOSITORY_HH_
20 
21 
22 #include <map>
23 #include "type_base.hh"
24 
25 
26 namespace Input {
27 
28 
29 /**
30  * @brief The Singleton class TypeRepository serves for handling the lazy-evaluated input types, derived from the base class
31  * Type::TypeBase.
32  *
33  * When all static variables are initialized, the method TypeRepository::instance().finish() can be called
34  * in order to finish initialization of lazy types such as Records, Abstracts, Arrays and Selections.
35  * Selections have to be finished after all other types since they are used by Abstracts to register all
36  * derived types. For this reason TypeRepository contains two arrays - one for Selections, one for the rest.
37  *
38  * This is list of unique instances that may contain raw pointers to possibly not yet constructed
39  * (static) objects. Unique instance is the instance that creates unique instance of the data class in pimpl idiom.
40  * These has to be completed/finished before use.
41  *
42  */
43 template <class T>
45 public:
46  /// Template parameter can be only descendant of TypeBase class.
47  static_assert(std::is_base_of<Type::TypeBase, T>::value,
48  "T must be a descendant of Input::Type::TypeBase"
49  );
50 
51  /// Type stored objects of input types.
53 
54  /// Public typedef of constant iterator into map of stored type.
55  typedef typename TypeRepositoryMap::const_iterator TypeRepositoryMapIter;
56 
57  /// Return singleton instance of class.
59  static TypeRepository instance;
60  return instance;
61  };
62 
63  /// Add @p type to TypeRepository if doesn't exist there or get existing type with same TypeHash
64  boost::shared_ptr<T> add_type(const T & type);
65 
66  /**
67  * @brief Finish all stored types.
68  *
69  * Iterate through all types stored in TypeRepository
70  * and call finish if flag @p root_of_generic_subtree_
71  * has same value as @param is_root_of_generic_subtree.
72  *
73  * We need call finish in two steps for correct
74  * functionality of generic types. In first step all
75  * types marked as "root_of_generic_subtree" are
76  * finished and then in second step can be finished
77  * other types.
78  */
79  void finish(bool is_root_of_generic_subtree = false);
80 
81  /// Container-like access to the data stored in TypeRepository. Returns iterator to the first data.
82  TypeRepositoryMapIter begin() const {
83  return type_repository_map_.begin();
84  }
85 
86  /// Container-like access to the data stored in TypeRepository. Returns iterator to the last data.
87  TypeRepositoryMapIter end() const {
88  return type_repository_map_.end();
89  }
90 private:
91  /// Default constructor.
93 
94  /// Stores input type objects.
95  TypeRepositoryMap type_repository_map_;
96 };
97 
98 
99 template <class T>
100 boost::shared_ptr<T> TypeRepository<T>::add_type(const T & type) {
101  Type::TypeBase::TypeHash hash = type.content_hash();
102 
103  auto search = type_repository_map_.find(hash);
104  if (search != type_repository_map_.end()) {
105  return search->second;
106  } else {
107  auto type_ptr = boost::make_shared<T>( type );
108  type_repository_map_.insert( std::pair<Type::TypeBase::TypeHash, boost::shared_ptr<T>>(hash,type_ptr) );
109  return type_ptr;
110  }
111 }
112 
113 template <class T>
114 void TypeRepository<T>::finish(bool is_root_of_generic_subtree) {
115  // We need reverse iterating for correct finish of generic types.
116  for (typename TypeRepositoryMap::reverse_iterator it = type_repository_map_.rbegin(); it != type_repository_map_.rend(); ++it) {
117  if (is_root_of_generic_subtree == it->second->is_root_of_generic_subtree()) {
118  if (is_root_of_generic_subtree) {
119  //ASSERT(it->second->is_finished())(it->second->type_name()).warning("Unused root of generic subtree.");
120  it->second->finish(true);
121  } else {
122  it->second->finish();
123  }
124  }
125  }
126 }
127 
128 } // namespace Input
129 
130 
131 #endif /* TYPE_REPOSITORY_HH_ */
TypeRepositoryMap::const_iterator TypeRepositoryMapIter
Public typedef of constant iterator into map of stored type.
TypeRepositoryMap type_repository_map_
Stores input type objects.
void finish(bool is_root_of_generic_subtree=false)
Finish all stored types.
static TypeRepository & get_instance()
Return singleton instance of class.
std::map< Type::TypeBase::TypeHash, boost::shared_ptr< T > > TypeRepositoryMap
Template parameter can be only descendant of TypeBase class.
TypeRepositoryMapIter end() const
Container-like access to the data stored in TypeRepository. Returns iterator to the last data...
The Singleton class TypeRepository serves for handling the lazy-evaluated input types, derived from the base class Type::TypeBase.
TypeRepositoryMapIter begin() const
Container-like access to the data stored in TypeRepository. Returns iterator to the first data...
boost::shared_ptr< T > add_type(const T &type)
Add type to TypeRepository if doesn&#39;t exist there or get existing type with same TypeHash.
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:82
TypeRepository()
Default constructor.