| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 | 
							- #ifndef MANDEL_ARENA_H
 
- #define MANDEL_ARENA_H
 
- #include <vector>
 
- #include <array>
 
- #include <utility>
 
- #include <memory>
 
- #include <functional>
 
- namespace mnd
 
- {
 
-     namespace util
 
-     {
 
-         //!
 
-         //! \brief Arena-allocator for a generic type
 
-         //!
 
-         //! The arena allocator provides an allocate function to allocate
 
-         //! and construct objects of type T. All allocated objects live as
 
-         //! long as the Arena lives and are destructed in the inverse order.
 
-         //! 
 
-         //! \tparam T the type for the Arena to allocate
 
-         //! \tparam chunkSize the Arena allocates objects in chunks of this size
 
-         //!
 
-         template <typename T, int chunkSize = 64>
 
-         class Arena
 
-         {
 
-             struct Chunk
 
-             {
 
-                 char data[sizeof(T) * chunkSize];
 
-                 int used = 0;
 
-                 bool full(void) const { return used == chunkSize; }
 
-                 template<typename... Args>
 
-                 T* allocate(Args&&... args)
 
-                 {
 
-                     return new(reinterpret_cast<T*>(&data[(used++) * sizeof(T)])) T(std::forward<Args>(args)...);
 
-                 }
 
-                 T& at(int index)
 
-                 {
 
-                     return *reinterpret_cast<T*>(&data[index * sizeof(T)]);
 
-                 }
 
-                 ~Chunk(void)
 
-                 {
 
-                     for (int i = used - 1; i >= 0; i--) {
 
-                         reinterpret_cast<T*>(&data[i * sizeof(T)])->~T();
 
-                     }
 
-                 }
 
-             };
 
-             std::vector<std::unique_ptr<Chunk>> chunks;
 
-             Chunk& lastChunk(void) { return *chunks[chunks.size() - 1]; }
 
-         public:
 
-             Arena(void) = default;
 
-             Arena(const Arena&) = delete;
 
-             Arena(Arena&&) = default;
 
-             ~Arena(void)
 
-             {
 
-                 for (auto it = chunks.rbegin(); it != chunks.rend(); ++it) {
 
-                     *it = nullptr;
 
-                 }
 
-             }
 
-             Arena& operator=(const Arena&) = delete;
 
-             Arena& operator=(Arena&&) = default;
 
-             //!
 
-             //! \brief construct one object whose lifetime is managed by
 
-             //!        the arena.
 
-             //!
 
-             template<typename... Args>
 
-             T* allocate(Args&&... args)
 
-             {
 
-                 if (chunks.empty() || lastChunk().full()) {
 
-                     chunks.push_back(std::make_unique<Chunk>());
 
-                 }
 
-                 return lastChunk().allocate(std::forward<Args>(args)...);
 
-             }
 
-             void forAll(std::function<void(T&)> f)
 
-             {
 
-                 for (auto& chunk : chunks) {
 
-                     for (int i = 0; i < chunk->used; i++) {
 
-                         f(chunk->at(i));
 
-                     }
 
-                 }
 
-             }
 
-         };
 
-     }
 
- }
 
- #endif // MANDEL_ARENA_H
 
 
  |