boost poolとsmart pointer

boost poolを調査中です。
私の場合、クリティカルな速度よりもメモリの断片化が怖いのだけなので、単純な使い方を見ているだけですがヽ(;´Д`)ノ

色々と調べてみて分かったのですが、boost poolでは、使ったメモリは自分でプールに戻さないと(´・д・`) ダメなようです。
スマートポインタに慣れきっている私には、チトきつ過ぎる(ノД`)シクシク
という分けて、スマートポインタのdeleterを使って自動的に解放してくれる便利関数を作成しました。

まず、今回作成した便利関数群は以下となります。
まぁ、削除子を追加しただけですがヽ(;´Д`)ノ

//! object pool を使いやすくする関数群
namespace pool_utility
{
  namespace
  {
    //! object 解放子
    template< typename OBJECT_TYPE , typename POOL_TYPE >
    struct singleton_pool_deleter
    {
      void operator () ( OBJECT_TYPE * p ) const
      {
        POOL_TYPE::free(p);
      }
    };
  }

  //! object poolからメモリを借りる
  template < typename POOL_TYPE >
  inline std::unique_ptr< typename  POOL_TYPE::tag::OBJECT_TYPE ,
                          singleton_pool_deleter< typename POOL_TYPE::tag::OBJECT_TYPE , POOL_TYPE >  > borrow_unique_object( void )
  {
    typedef typename POOL_TYPE::tag::OBJECT_TYPE OBJECT_TYPE;
    return std::unique_ptr< OBJECT_TYPE ,  singleton_pool_deleter< OBJECT_TYPE  , POOL_TYPE >  >
      ( ( OBJECT_TYPE * )POOL_TYPE::malloc() , singleton_pool_deleter< OBJECT_TYPE , POOL_TYPE >() );
  }

  //! object poolからメモリを借りる
  template < typename POOL_TYPE >
  inline std::shared_ptr< typename  POOL_TYPE::tag::OBJECT_TYPE  > borrow_shared_object( void )
  {
    typedef typename POOL_TYPE::tag::OBJECT_TYPE OBJECT_TYPE;
    return std::shared_ptr< OBJECT_TYPE  >
      ( ( OBJECT_TYPE * )POOL_TYPE::malloc() , singleton_pool_deleter< OBJECT_TYPE , POOL_TYPE >() );
  }

}

使い方は以下となります。
注意が必要な箇所としては、poll識別用のtagに「OBJECT_TYPE」というメンバ型が必要な事です。
この型を使って、プールが確保している型情報を取得しています。

#include <future>
#include <boost/pool/singleton_pool.hpp>

namespace
{

  //! pool対象となるオブジェクト
  struct Hoge
  {
    char data[1024];
    int i = 0;
  };

  //! poolを識別するためのタグ
  struct Hoge_Tag
  {
    //! プールが保持しているデータの型を取得
    typedef Hoge OBJECT_TYPE;
  };

  //! オブジェクトプールを生成
  typedef boost::singleton_pool< Hoge_Tag , sizeof( Hoge_Tag::OBJECT_TYPE ) > my_pool;

  //! 負荷関数
  void unique_test( void )
  {
    while(true)
      {
        for (int i = 0; i < 10000; ++i)
          {
            auto t = pool_utility::borrow_unique_object< my_pool >();
            std::fill( t->data , t->data + 1024 , '0');
            t->i = i;
          }
      }
  }

  //! 負荷関数
  void unique_test( void )
  {
    while(true)
      {
        for (int i = 0; i < 10000; ++i)
          {
            auto t = pool_utility::borrow_unique_object< my_pool >();
            std::fill( t->data , t->data + 1024 , '0');
            t->i = i;
          }
      }
  }

  //! 負荷関数
  void shared_test( void )
  {
    while(true)
      {
        for (int i = 0; i < 10000; ++i)
          {
            auto t = pool_utility::borrow_shared_object< my_pool >();
            std::fill( t->data , t->data + 1024 , '0');
            t->i = i;
          }
      }
  }
}

int main()
{
  auto f1 = std::async( std::launch::async , unique_test );
  auto f2 = std::async( std::launch::async , shared_test );

  f1.get();
  f2.get();
}