LCOV - code coverage report
Current view: top level - lib/support - PoolWrapper.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 14 18 77.8 %
Date: 2024-02-15 08:20:41 Functions: 20 32 62.5 %

          Line data    Source code
       1             : /*
       2             :  *    Copyright (c) 2021 Project CHIP Authors
       3             :  *    All rights reserved.
       4             :  *
       5             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6             :  *    you may not use this file except in compliance with the License.
       7             :  *    You may obtain a copy of the License at
       8             :  *
       9             :  *        http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  *    Unless required by applicable law or agreed to in writing, software
      12             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  *    See the License for the specific language governing permissions and
      15             :  *    limitations under the License.
      16             :  */
      17             : 
      18             : #pragma once
      19             : 
      20             : #include <tuple>
      21             : 
      22             : #include <lib/support/Pool.h>
      23             : 
      24             : namespace chip {
      25             : 
      26             : /// Provides an interface over a pool implementation which doesn't expose the size and the actual type of the pool.
      27             : template <typename U, typename... ConstructorArguments>
      28             : class PoolInterface
      29             : {
      30             : public:
      31             :     // For convenient use in PoolImpl
      32             :     using Interface = std::tuple<U, ConstructorArguments...>;
      33             : 
      34          29 :     virtual ~PoolInterface() {}
      35             : 
      36             :     virtual U * CreateObject(ConstructorArguments... args) = 0;
      37             :     virtual void ReleaseObject(U * element)                = 0;
      38             :     virtual void ReleaseAll()                              = 0;
      39             : 
      40             :     template <typename Function>
      41          86 :     Loop ForEachActiveObject(Function && function)
      42             :     {
      43             :         static_assert(std::is_same<Loop, decltype(function(std::declval<U *>()))>::value,
      44             :                       "The function must take T* and return Loop");
      45         186 :         auto proxy = [&](U * target) -> Loop { return function(target); };
      46         172 :         return ForEachActiveObjectInner(
      47         186 :             &proxy, [](void * context, U * target) -> Loop { return (*static_cast<decltype(proxy) *>(context))(target); });
      48             :     }
      49             :     template <typename Function>
      50             :     Loop ForEachActiveObject(Function && function) const
      51             :     {
      52             :         static_assert(std::is_same<Loop, decltype(function(std::declval<U *>()))>::value,
      53             :                       "The function must take const T* and return Loop");
      54             :         auto proxy = [&](const U * target) -> Loop { return function(target); };
      55             :         return ForEachActiveObjectInner(
      56             :             &proxy, [](void * context, const U * target) -> Loop { return (*static_cast<decltype(proxy) *>(context))(target); });
      57             :     }
      58             : 
      59             : protected:
      60             :     using Lambda                                                                    = Loop (*)(void *, U *);
      61             :     using LambdaConst                                                               = Loop (*)(void *, const U *);
      62             :     virtual Loop ForEachActiveObjectInner(void * context, Lambda lambda)            = 0;
      63             :     virtual Loop ForEachActiveObjectInner(void * context, LambdaConst lambda) const = 0;
      64             : };
      65             : 
      66             : template <class T, size_t N, ObjectPoolMem M, typename Interface>
      67             : class PoolProxy;
      68             : 
      69             : template <class T, size_t N, ObjectPoolMem M, typename U, typename... ConstructorArguments>
      70             : class PoolProxy<T, N, M, std::tuple<U, ConstructorArguments...>> : public PoolInterface<U, ConstructorArguments...>
      71             : {
      72             : public:
      73             :     static_assert(std::is_base_of<U, T>::value, "Interface type is not derived from Pool type");
      74             : 
      75          30 :     PoolProxy() {}
      76          30 :     ~PoolProxy() override {}
      77             : 
      78          32 :     U * CreateObject(ConstructorArguments... args) override { return Impl().CreateObject(std::move(args)...); }
      79             : 
      80           0 :     void ReleaseObject(U * element) override { Impl().ReleaseObject(static_cast<T *>(element)); }
      81             : 
      82          80 :     void ReleaseAll() override { Impl().ReleaseAll(); }
      83             : 
      84             : protected:
      85          50 :     Loop ForEachActiveObjectInner(void * context, typename PoolInterface<U, ConstructorArguments...>::Lambda lambda) override
      86             :     {
      87         147 :         return Impl().ForEachActiveObject([&](T * target) { return lambda(context, static_cast<U *>(target)); });
      88             :     }
      89           0 :     Loop ForEachActiveObjectInner(void * context,
      90             :                                   typename PoolInterface<U, ConstructorArguments...>::LambdaConst lambda) const override
      91             :     {
      92           0 :         return Impl().ForEachActiveObject([&](const T * target) { return lambda(context, static_cast<const U *>(target)); });
      93             :     }
      94             : 
      95             :     virtual ObjectPool<T, N, M> & Impl()             = 0;
      96             :     virtual const ObjectPool<T, N, M> & Impl() const = 0;
      97             : };
      98             : 
      99             : /*
     100             :  * @brief
     101             :  *   Define a implementation of a pool which derive and expose PoolInterface's.
     102             :  *
     103             :  *  @tparam T          a subclass of element to be allocated.
     104             :  *  @tparam N          a positive integer max number of elements the pool provides.
     105             :  *  @tparam M          an ObjectPoolMem constant selecting static vs heap allocation.
     106             :  *  @tparam Interfaces a list of parameters which defines PoolInterface's. each interface is defined by a
     107             :  *                     std::tuple<U, ConstructorArguments...>. The PoolImpl is derived from every
     108             :  *                     PoolInterface<U, ConstructorArguments...>, the PoolImpl can be converted to the interface type
     109             :  *                     and passed around
     110             :  */
     111             : template <class T, size_t N, ObjectPoolMem M, typename... Interfaces>
     112             : class PoolImpl : public PoolProxy<T, N, M, Interfaces>...
     113             : {
     114             : public:
     115          30 :     PoolImpl() {}
     116          30 :     ~PoolImpl() override {}
     117             : 
     118             : protected:
     119         162 :     ObjectPool<T, N, M> & Impl() override { return mImpl; }
     120           0 :     const ObjectPool<T, N, M> & Impl() const override { return mImpl; }
     121             : 
     122             : private:
     123             :     ObjectPool<T, N, M> mImpl;
     124             : };
     125             : 
     126             : } // namespace chip

Generated by: LCOV version 1.14