www.mooseframework.org
SharedPool.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 // System Includes
13 #include <stack>
14 #include <memory>
15 
16 namespace MooseUtils
17 {
18 
19 template <class T, typename... Args>
20 auto
21 reset(int, T & obj, Args... args) -> decltype(obj.reset(args...), void())
22 {
23  obj.reset(std::forward<Args>(args)...);
24 }
25 
26 template <class T, typename... Args>
27 void
28 reset(double, T & /*obj*/, Args... /*args*/)
29 {
30 }
31 
41 template <class T>
43 {
44 private:
46  {
47  explicit ExternalDeleter(std::weak_ptr<SharedPool<T> *> pool) : _pool(pool) {}
48 
49  void operator()(T * ptr)
50  {
51  if (auto _poolptr = _pool.lock())
52  {
53  try
54  {
55  (*_poolptr.get())->add(std::unique_ptr<T>{ptr});
56  return;
57  }
58  catch (...)
59  {
60  }
61  }
62  std::default_delete<T>{}(ptr);
63  }
64 
65  private:
66  std::weak_ptr<SharedPool<T> *> _pool;
67  };
68 
69 public:
70  using ptr_type = std::unique_ptr<T, ExternalDeleter>;
71 
72  SharedPool() : _this_ptr(new SharedPool<T> *(this)) {}
73  virtual ~SharedPool() {}
74 
75  void add(std::unique_ptr<T> t) { _pool.push(std::move(t)); }
76 
77  template <typename... Args>
78  ptr_type acquire(Args &&... args)
79  {
80  // if the pool is empty - create one
81  if (_pool.empty())
82  {
83  _num_created++;
84  return std::move(ptr_type(new T(std::forward<Args>(args)...),
85  ExternalDeleter{std::weak_ptr<SharedPool<T> *>{_this_ptr}}));
86  }
87  else
88  {
89  ptr_type tmp(_pool.top().release(),
90  ExternalDeleter{std::weak_ptr<SharedPool<T> *>{_this_ptr}});
91  _pool.pop();
92 
93  reset(1, *tmp, std::forward<Args>(args)...);
94 
95  return std::move(tmp);
96  }
97  }
98 
99  bool empty() const { return _pool.empty(); }
100 
101  size_t size() const { return _pool.size(); }
102 
103  size_t num_created() const { return _num_created; }
104 
105 private:
106  std::shared_ptr<SharedPool<T> *> _this_ptr;
107  std::stack<std::unique_ptr<T>> _pool;
108 
109  size_t _num_created = 0;
110 };
111 }
size_t num_created() const
Definition: SharedPool.h:103
std::stack< std::unique_ptr< T > > _pool
Definition: SharedPool.h:107
auto reset(int, T &obj, Args... args) -> decltype(obj.reset(args...), void())
Definition: SharedPool.h:21
bool empty() const
Definition: SharedPool.h:99
std::unique_ptr< T, ExternalDeleter > ptr_type
Definition: SharedPool.h:70
size_t size() const
Definition: SharedPool.h:101
void add(std::unique_ptr< T > t)
Definition: SharedPool.h:75
ExternalDeleter(std::weak_ptr< SharedPool< T > *> pool)
Definition: SharedPool.h:47
std::shared_ptr< SharedPool< T > * > _this_ptr
Definition: SharedPool.h:106
ptr_type acquire(Args &&... args)
Definition: SharedPool.h:78
std::weak_ptr< SharedPool< T > * > _pool
Definition: SharedPool.h:66
Originally From https://stackoverflow.com/a/27837534/2042320.
Definition: SharedPool.h:42