Matter SDK Coverage Report
Current view: top level - lib/support - PoolWrapper.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 77.8 % 18 14
Test Date: 2025-01-17 19:00:11 Functions: 55.1 % 49 27

            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           64 :     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           87 :     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          175 :         auto proxy = [&](U * target) -> Loop { return function(target); };
      46          174 :         return ForEachActiveObjectInner(
      47          175 :             &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           65 :     PoolProxy() {}
      76           65 :     ~PoolProxy() override {}
      77              : 
      78           26 :     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          106 :     void ReleaseAll() override { Impl().ReleaseAll(); }
      83              : 
      84              : protected:
      85           44 :     Loop ForEachActiveObjectInner(void * context, typename PoolInterface<U, ConstructorArguments...>::Lambda lambda) override
      86              :     {
      87          129 :         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           65 :     PoolImpl() {}
     116           65 :     ~PoolImpl() override {}
     117              : 
     118              : protected:
     119          176 :     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 2.0-1