Flow123d  release_3.0.0-1117-gaafa50c
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 <memory>
24 #include "type_base.hh"
25 
26 
27 namespace Input {
28 
29 
30 /**
31  * @brief The Singleton class TypeRepository serves for handling the lazy-evaluated input types, derived from the base class
32  * Type::TypeBase.
33  *
34  * When all static variables are initialized, the method TypeRepository::instance().finish() can be called
35  * in order to finish initialization of lazy types such as Records, Abstracts, Arrays and Selections.
36  * Selections have to be finished after all other types since they are used by Abstracts to register all
37  * derived types. For this reason TypeRepository contains two arrays - one for Selections, one for the rest.
38  *
39  * This is list of unique instances that may contain raw pointers to possibly not yet constructed
40  * (static) objects. Unique instance is the instance that creates unique instance of the data class in pimpl idiom.
41  * These has to be completed/finished before use.
42  *
43  */
44 template <class T>
46 public:
47  /// Template parameter can be only descendant of TypeBase class.
49  "T must be a descendant of Input::Type::TypeBase"
50  );
51 
52  /// Type stored objects of input types.
54 
55  /// Public typedef of constant iterator into map of stored type.
56  typedef typename TypeRepositoryMap::const_iterator TypeRepositoryMapIter;
57 
58  /// Return singleton instance of class.
60  static TypeRepository instance;
61  return instance;
62  };
63 
64  /// Add @p type to TypeRepository if doesn't exist there or get existing type with same TypeHash
65  std::shared_ptr<T> add_type(const T & type);
66 
67  std::shared_ptr<T> find_hash(Type::TypeBase::TypeHash hash);
68 
69  /**
70  * @brief Finish all stored types.
71  *
72  * Iterate through all types stored in TypeRepository
73  * and call finish with given status.
74  *
75  * Note: This method is meant to be used only with
76  * FinishType::delete.
77  */
78  void finish(Type::FinishStatus finish_type);
79 
80  /**
81  * @brief Reset and remove types marked as deleted during finish.
82  *
83  * Iterate through all types stored in TypeRepository and -
84  * - check count of usage of shared pointer to type (must be one)
85  * - reset this shared pointer
86  * - remove type from repository
87  */
88  void reset_deleted_types();
89 
90  /// Container-like access to the data stored in TypeRepository. Returns iterator to the first data.
91  TypeRepositoryMapIter begin() const {
92  return type_repository_map_.begin();
93  }
94 
95  /// Container-like access to the data stored in TypeRepository. Returns iterator to the last data.
96  TypeRepositoryMapIter end() const {
97  return type_repository_map_.end();
98  }
99 private:
100  /// Default constructor.
102 
103  /// Stores input type objects.
104  TypeRepositoryMap type_repository_map_;
105 };
106 
107 
108 template <class T>
109 std::shared_ptr<T> TypeRepository<T>::add_type(const T & type) {
110  Type::TypeBase::TypeHash hash = type.content_hash();
111 
112  auto search = find_hash(hash);
113  if (search) {
114  return search;
115  } else {
116  auto type_ptr = std::make_shared<T>( type );
117  type_repository_map_.insert( std::pair<Type::TypeBase::TypeHash, std::shared_ptr<T>>(hash,type_ptr) );
118  return type_ptr;
119  }
120 }
121 
122 
123 template <class T>
125  auto search = type_repository_map_.find(hash);
126  if (search != type_repository_map_.end()) {
127  return search->second;
128  } else {
129  return std::shared_ptr<T>();
130  }
131 }
132 
133 template <class T>
135  for (typename TypeRepositoryMap::iterator it = type_repository_map_.begin(); it != type_repository_map_.end(); ++it) {
136  it->second->finish(finish_type);
137  }
138 }
139 
140 template <class T>
143  for (typename TypeRepositoryMap::iterator it = type_repository_map_.begin(); it != type_repository_map_.end(); ++it) {
144  if (it->second->finish_status() == Type::FinishStatus::delete_) {
145  ASSERT(it->second.use_count() == 1)(it->second.use_count()).error();
146  it->second.reset();
147  deleted_hashes.push_back(it->first);
148  }
149  }
150 
151  for (auto deleted_hash : deleted_hashes) {
152  type_repository_map_.erase(deleted_hash);
153  }
154 }
155 
156 } // namespace Input
157 
158 
159 #endif /* TYPE_REPOSITORY_HH_ */
std::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.
TypeRepositoryMap::const_iterator TypeRepositoryMapIter
Public typedef of constant iterator into map of stored type.
std::map< Type::TypeBase::TypeHash, std::shared_ptr< T > > TypeRepositoryMap
Template parameter can be only descendant of TypeBase class.
Abstract linear system class.
Definition: balance.hh:35
TypeRepositoryMap type_repository_map_
Stores input type objects.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
static constexpr bool value
Definition: json.hpp:87
static TypeRepository & get_instance()
Return singleton instance of class.
void reset_deleted_types()
Reset and remove types marked as deleted during finish.
std::shared_ptr< T > find_hash(Type::TypeBase::TypeHash hash)
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...
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:102
void finish(Type::FinishStatus finish_type)
Finish all stored types.
TypeRepository()
Default constructor.