profiler  0.0
WeakSingleton.h
1 #ifndef PROFILER_SRC_MOLPRO_PROFILER_TREE_SINGLE_H
2 #define PROFILER_SRC_MOLPRO_PROFILER_TREE_SINGLE_H
3 #include <algorithm>
4 #include <cassert>
5 #include <list>
6 #include <memory>
7 #include <string>
8 
9 namespace molpro {
10 namespace profiler {
11  std::shared_ptr<Profiler> s_saver;
12 
13 // FIXME improve description
17 template <class Object>
18 struct WeakSingleton {
19 
20  using key_t = std::tuple<std::string, std::weak_ptr<Object>, Object*>;
21 
26  template <typename... T>
27  static std::shared_ptr<Object> single(const std::string& key, T&&... constructor_args) {
28  std::shared_ptr<Object> result = nullptr;
29  auto it =
30  std::find_if(begin(m_register), end(m_register), [&key](const key_t& el) { return std::get<0>(el) == key; });
31  if (it != m_register.end())
32  result = std::get<1>(*it).lock();
33  if (!result) {
34  result = std::make_shared<Object>(std::forward<T>(constructor_args)...);
35  m_register.emplace_back(key_t{key, result, result.get()});
36  }
37  return result;
38  }
39 
41  static std::shared_ptr<Object> single() {
42  if (m_register.empty() or not std::get<1>(m_register.back()).lock()) { // default zero-depth instance
43  auto result = Profiler::single("default");
44  result->set_max_depth(0);
45  return result;
46  }
47  assert(!m_register.empty() && "First must make a call to single(key, ...) to create an object");
48  std::shared_ptr<Object> result = std::get<1>(m_register.back()).lock();
49  assert(result && "The last registered object was deallocated");
50  return result;
51  }
52 
54  static void erase(Object* obj) {
55  auto it =
56  std::find_if(begin(m_register), end(m_register), [obj](const key_t& el) { return std::get<2>(el) == obj; });
57  if (it != m_register.end())
58  m_register.erase(it);
59  }
60 
62  static void erase(const std::string& key) {
63  auto it =
64  std::find_if(begin(m_register), end(m_register), [&key](const key_t& el) { return std::get<0>(el) == key; });
65  if (it != m_register.end())
66  m_register.erase(it);
67  }
68 
70  static void clear() { m_register.clear(); }
71 
72  static std::list<key_t> m_register;
73 };
74 
75 } // namespace profiler
76 } // namespace molpro
77 #endif // PROFILER_SRC_MOLPRO_PROFILER_TREE_SINGLE_H
static std::shared_ptr< Profiler > single()
Access the last registered Profiler.
Definition: Profiler.cpp:31
std::shared_ptr< Profiler > s_saver
Definition: WeakSingleton.h:11
Definition: Profiler.h:5
Implements the mechanism for the weak singleton pattern.
Definition: WeakSingleton.h:18
static void erase(Object *obj)
Remove object from the register. This should be called in the destructor of class that exposes this p...
Definition: WeakSingleton.h:54
static std::list< key_t > m_register
stores all objects created by a call to single
Definition: WeakSingleton.h:72
static void erase(const std::string &key)
Remove object registered under the name key.
Definition: WeakSingleton.h:62
std::tuple< std::string, std::weak_ptr< Object >, Object * > key_t
Definition: WeakSingleton.h:20
static std::shared_ptr< Object > single(const std::string &key, T &&... constructor_args)
Creates an instance of Object or returns an already registered instance.
Definition: WeakSingleton.h:27
static void clear()
Remove all registered objects.
Definition: WeakSingleton.h:70
static std::shared_ptr< Object > single()
Access the last registered object.
Definition: WeakSingleton.h:41