Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2015
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.93 KB | None | 0 0
  1. /**
  2.  * mempool.h - memory allocation structure that allocates blocks of memory at a time
  3.  * Copyright (C) 2015 Jonah Schreiber ([email protected])
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18.  */
  19.  
  20. #pragma once
  21.  
  22. #define DEFAULT_POOL_SIZE 10000
  23.  
  24. #include <algorithm>
  25. #include <cassert>
  26. #include <vector>
  27. #include <iterator>
  28.  
  29. template <typename T>
  30. class MemoryPool {
  31. public:
  32.     typedef T              *pointer;
  33.     typedef T              &reference;
  34.     typedef const T        &const_reference;
  35.     typedef size_t          size_type;
  36.     typedef std::ptrdiff_t  difference_type;
  37.  
  38.     template <typename elem_type = T, typename elem_type_nonconst = T, typename pool_type = MemoryPool<elem_type> >
  39.     class mempool_iterator : std::iterator<std::random_access_iterator_tag,
  40.                                            elem_type,
  41.                                            difference_type> {
  42.         friend class mempool_iterator<const T, T, const MemoryPool>;
  43.     public:
  44.         inline mempool_iterator() : mParent(nullptr), mIndex(0) {}
  45.         inline mempool_iterator(pool_type *parent, size_type index) : mParent(parent), mIndex(index) {}
  46.         inline mempool_iterator(const mempool_iterator<T, T, MemoryPool> &other) :
  47.             mParent(other.mParent), mIndex(other.mIndex) {}
  48.         inline elem_type &operator*()  { return (*mParent)[mIndex]; }
  49.         inline elem_type *operator->() { return &(operator*()); }
  50.         inline mempool_iterator &operator++() { ++mIndex; return *this; }
  51.         inline mempool_iterator operator++(int) { mempool_iterator tmp(*this); ++(*this); return tmp; }
  52.         inline mempool_iterator &operator--() { --mIndex; return *this; }
  53.         inline mempool_iterator operator--(int) { mempool_iterator tmp(*this); ++(*this); return tmp; }
  54.         inline mempool_iterator operator+(difference_type n) const { mempool_iterator tmp(*this); tmp += n; return tmp; }
  55.         inline mempool_iterator &operator+=(difference_type n) { mIndex += n; return *this; }
  56.         inline mempool_iterator operator-(difference_type n) const { mempool_iterator tmp(*this); tmp -= n; return tmp; }
  57.         inline mempool_iterator &operator-=(difference_type n) { mIndex -= n; return *this; }
  58.         inline bool operator==(const mempool_iterator &other) const { return mIndex == other.mIndex; }
  59.         inline bool operator!=(const mempool_iterator &other) const { return mIndex != other.mIndex; }
  60.     private:
  61.         pool_type *mParent;
  62.         size_type mIndex;
  63.     };
  64.  
  65.     friend class mempool_iterator<>;
  66.  
  67.     explicit inline MemoryPool(size_type poolSize = DEFAULT_POOL_SIZE) :
  68.         mPoolSize(poolSize), mMemIndex(poolSize), mTotalSize(0) {}
  69.  
  70.     inline MemoryPool(const MemoryPool &other) :
  71.         mPoolSize(other.mPoolSize), mMemIndex(other.mMemIndex), mTotalSize(other.mTotalSize) {
  72.  
  73.         mPools.reserve(mPoolSize);
  74.         for (auto &&pool : other.mPools) {
  75.             T *block = new T[mPoolSize];
  76.             std::copy(pool, pool + mPoolSize, block);
  77.             mPools.push_back(block);
  78.         }
  79.     }
  80.  
  81.     inline MemoryPool(MemoryPool &&other) noexcept :
  82.         mPoolSize(other.mPoolSize), mMemIndex(other.mMemIndex), mTotalSize(other.mTotalSize) {
  83.  
  84.         mPools = other.mPools;
  85.         other.mPools.clear();
  86.     }
  87.  
  88.     inline ~MemoryPool() noexcept {
  89.         for (auto &&pool : mPools) {
  90.             delete[] pool;
  91.         }
  92.     }
  93.  
  94.     inline MemoryPool &operator=(const MemoryPool &other) {
  95.         MemoryPool tmp(other); // re-use copy-constructor
  96.         *this = std::move(tmp); // re-use move-assignment
  97.         return *this;
  98.     }
  99.  
  100.     inline MemoryPool &operator=(MemoryPool &&other) noexcept {
  101.         std::swap(mPools, other.mPools);
  102.         std::swap(mMemIndex, other.mMemIndex);
  103.         std::swap(mPoolSize, other.mPoolSize);
  104.         std::swap(mTotalSize, other.mTotalSize);
  105.         return *this;
  106.     }
  107.  
  108.     inline size_type size() const {
  109.         return mTotalSize;
  110.     }
  111.  
  112.     inline bool empty() const {
  113.         return mTotalSize == 0;
  114.     }
  115.  
  116.     inline reference operator[](size_type n) {
  117.         return (mPools[n / mPoolSize])[n % mPoolSize];
  118.     }
  119.  
  120.     inline const_reference operator[](size_type n) const {
  121.         return (mPools[n / mPoolSize])[n % mPoolSize];
  122.     }
  123.  
  124.     typedef mempool_iterator<T, T, MemoryPool> iterator;
  125.     inline iterator begin() { return iterator(this, 0); }
  126.     inline iterator end()   { return iterator(this, size()); }
  127.  
  128.     typedef mempool_iterator<const T, T, const MemoryPool> const_iterator;
  129.     inline const_iterator begin() const { return const_iterator(this, 0); }
  130.     inline const_iterator end()   const { return const_iterator(this, size()); }
  131.  
  132.     inline pointer allocate() {
  133.         assert(mMemIndex <= mPoolSize);
  134.         if (mMemIndex == mPoolSize) {
  135.             mPools.push_back(new T[mPoolSize]);
  136.             mMemIndex = 0;
  137.         }
  138.         mTotalSize++;
  139.         return &mPools[mPools.size() - 1][mMemIndex++];
  140.     }
  141.  
  142.     template <typename U>
  143.     inline pointer allocate(U &&item) {
  144.         static_assert(std::is_same<T, typename std::decay<U>::type>::value, "item must be of type T");
  145.         assert(mMemIndex <= mPoolSize);
  146.         if (mMemIndex == mPoolSize) {
  147.             mPools.push_back(new T[mPoolSize]);
  148.             mMemIndex = 0;
  149.         }
  150.         mPools[mPools.size() - 1][mMemIndex] = std::forward<U>(item);
  151.         mTotalSize++;
  152.         return &mPools[mPools.size() - 1][mMemIndex++];
  153.     }
  154.  
  155. protected:
  156.     std::vector<T*> mPools;
  157.     size_type mPoolSize, mMemIndex, mTotalSize;
  158. };
  159.  
  160. template <typename T>
  161. class BaseMemoryPool : public MemoryPool<char> {
  162. public:
  163.     explicit inline BaseMemoryPool(size_type poolSize = DEFAULT_POOL_SIZE) : MemoryPool(poolSize) {}
  164.    
  165.     template <typename U>
  166.     inline T *construct(U &&item) {
  167.         static_assert(std::is_base_of<T, typename std::decay<U>::type>::value, "item must be of or derived of type T");
  168.         assert(mMemIndex <= mPoolSize && sizeof(U) <= mPoolSize);
  169.         if (mMemIndex + sizeof(U) > mPoolSize) {
  170.             mPools.push_back(new T[mPoolSize]);
  171.             mMemIndex = 0;
  172.         } // only got so far!
  173.         mPools[mPools.size() - 1][mMemIndex] = std::forward<U>(item);
  174.         mTotalSize++;
  175.         return &mPools[mPools.size() - 1][mMemIndex++];
  176.     }
  177. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement