LCOV - code coverage report
Current view: top level - include/utils - SharedPool.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 26 28 92.9 %
Date: 2025-07-17 01:28:37 Functions: 19 21 90.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       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           2 : reset(int, T & obj, Args... args) -> decltype(obj.reset(args...), void())
      22             : {
      23           2 :   obj.reset(std::forward<Args>(args)...);
      24           2 : }
      25             : 
      26             : template <class T, typename... Args>
      27             : void
      28           2 : reset(double, T & /*obj*/, Args... /*args*/)
      29             : {
      30           2 : }
      31             : 
      32             : /**
      33             :  *
      34             :  * Originally From https://stackoverflow.com/a/27837534/2042320
      35             :  *
      36             :  * friedmud added variadic templated perfect forwarding to acquire()
      37             :  *
      38             :  * For an object to be resetable it needs to define a reset() function
      39             :  * that takes the same arguments as its constructor.
      40             :  */
      41             : template <class T>
      42             : class SharedPool
      43             : {
      44             : private:
      45             :   struct ExternalDeleter
      46             :   {
      47          10 :     explicit ExternalDeleter(std::weak_ptr<SharedPool<T> *> pool) : _pool(pool) {}
      48             : 
      49          10 :     void operator()(T * ptr)
      50             :     {
      51          20 :       if (auto _poolptr = _pool.lock())
      52             :       {
      53             :         try
      54             :         {
      55          10 :           (*_poolptr.get())->add(std::unique_ptr<T>{ptr});
      56          10 :           return;
      57             :         }
      58           0 :         catch (...)
      59             :         {
      60             :         }
      61             :       }
      62           0 :       std::default_delete<T>{}(ptr);
      63             :     }
      64             : 
      65             :   private:
      66             :     std::weak_ptr<SharedPool<T> *> _pool;
      67             :   };
      68             : 
      69             : public:
      70             :   typedef typename std::unique_ptr<T, ExternalDeleter> PtrType;
      71             : 
      72           2 :   SharedPool() : _this_ptr(new SharedPool<T> *(this)) {}
      73           2 :   virtual ~SharedPool() {}
      74             : 
      75          10 :   void add(std::unique_ptr<T> t) { _pool.push(std::move(t)); }
      76             : 
      77             :   template <typename... Args>
      78          10 :   PtrType acquire(Args &&... args)
      79             :   {
      80             :     // if the pool is empty - create one
      81          10 :     if (_pool.empty())
      82             :     {
      83           6 :       _num_created++;
      84          17 :       return PtrType(new T(std::forward<Args>(args)...),
      85          17 :                      ExternalDeleter{std::weak_ptr<SharedPool<T> *>{_this_ptr}});
      86             :     }
      87             :     else
      88             :     {
      89           4 :       PtrType tmp(_pool.top().release(),
      90           4 :                   ExternalDeleter{std::weak_ptr<SharedPool<T> *>{_this_ptr}});
      91           4 :       _pool.pop();
      92             : 
      93           4 :       reset(1, *tmp, std::forward<Args>(args)...);
      94             : 
      95           4 :       return tmp;
      96           4 :     }
      97             :   }
      98             : 
      99             :   bool empty() const { return _pool.empty(); }
     100             : 
     101           4 :   size_t size() const { return _pool.size(); }
     102             : 
     103           4 :   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             : }

Generated by: LCOV version 1.14