Pool.h
1 /*
2  * MoMEMta: a modular implementation of the Matrix Element Method
3  * Copyright (C) 2016 Universite catholique de Louvain (UCL), Belgium
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 #pragma once
21 
22 #include <momemta/Pool.h>
23 
24 #include <assert.h>
25 #include <memory>
26 #include <unordered_map>
27 
28 #include <momemta/any.h>
29 #include <momemta/Logging.h>
30 #include <momemta/Utils.h>
31 #include <momemta/Value.h>
32 #include <momemta/impl/ValueProxy.h>
33 
34 // A simple memory pool
35 
36 template <typename T> Value<T> Pool::get(const InputTag& tag) const {
37 
38  auto it = m_storage.find(tag);
39  if (it == m_storage.end()) {
40  if (tag.isIndexed()) {
41  it = create<std::vector<T>>(tag, false);
42  } else {
43  it = create<T>(tag, false);
44  }
45  }
46 
47  Value<T> value(ValueProxy<const T>::create(this, tag));
48 
49  return value;
50 }
51 
52 template <typename T> std::shared_ptr<const T> Pool::raw_get(const InputTag& tag) const {
53 
54  auto it = m_storage.find(tag);
55  if (it == m_storage.end())
56  throw tag_not_found_error("No such tag in pool: " + tag.toString());
57 
58  PoolContent& v = it->second;
59 
60  try {
61  std::shared_ptr<T>& ptr = momemta::any_cast<std::shared_ptr<T>&>(v.ptr);
62 
63  return std::const_pointer_cast<const T>(ptr);
64  } catch (const momemta::bad_any_cast& e) {
65  LOG(fatal) << "Exception while trying to get pool content for '" << tag.toString() << "'. Requested a '"
66  << demangle(typeid(std::shared_ptr<T>).name())
67  << "' while parameter is a '"
68  << demangle(v.ptr.type().name())
69  << "'";
70  throw e;
71  }
72 }
73 
74 template <typename T, typename... Args> std::shared_ptr<T> Pool::put(const InputTag& tag, Args&&... args) {
75  auto it = m_storage.find(tag);
76  if (it != m_storage.end()) {
77  if (it->second.valid)
78  throw duplicated_tag_error("A module already produced the tag '" + tag.toString() + "'");
79 
80  // A module already requested this block in read-mode. This will only work if the block does not require a non-trivial constructor:
81  if (sizeof...(Args))
82  throw constructor_tag_error("A module already requested the tag '" + tag.toString()
83  + "' which seems to require a constructor call. This is currently not supported.");
84  // Since the memory is allocated, simply consider the block as valid.
85  it->second.valid = true;
86 
87  // If the block is empty, it's a delayed instantiation. Simply flag the block as valid, and allocate memory for it
88  if (it->second.ptr.empty()) {
89  auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
90  it->second.ptr = momemta::any(ptr);
91  }
92 
93  } else {
94  it = create<T, Args ...>(tag, true, std::forward<Args>(args)...);
95  }
96 
97  return momemta::any_cast<std::shared_ptr<T>>(it->second.ptr);
98 }
99 
100 template <typename T, typename... Args> Pool::PoolStorage::iterator Pool::create(
101  const InputTag& tag, bool valid/* = true*/, Args&&... args) const {
102 
103  auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
104  PoolContent content = {momemta::any(ptr), valid};
105 
106  return m_storage.emplace(tag, content).first;
107 }
bool isIndexed() const
Definition: InputTag.cc:93
An identifier of a module&#39;s output.
Definition: InputTag_fwd.h:37
std::shared_ptr< T > put(const InputTag &tag, Args &&... args)
Allocate a new block in the memory pool.
Definition: Pool.h:74
A class representing a value produced by a module.
Definition: Value.h:30
std::string toString() const
Convert the InputTag in its string representation.
Definition: InputTag.cc:89