• Docs >
  • Program Listing for File allocator.hpp
Shortcuts

Program Listing for File allocator.hpp

Return to documentation for file (include/ripple/allocation/allocator.hpp)

#ifndef RIPPLE_ALLOCATION_ALLOCATOR_HPP
#define RIPPLE_ALLOCATION_ALLOCATOR_HPP

#include "aligned_heap_allocator.hpp"
#include "arena.hpp"
#include "pool_allocator.hpp"
#include <mutex>

namespace ripple {

struct VoidLock {
  auto lock() noexcept -> void {}

  auto unlock() noexcept -> void {}
};

/*==--- [forward declarations & aliases] -----------------------------------==*/

template <
  typename PrimaryAllocator,
  typename Arena             = HeapArena,
  typename FallbackAllocator = AlignedHeapAllocator,
  typename LockingPolicy     = VoidLock>
class Allocator;

template <
  typename T,
  typename LockingPolicy = VoidLock,
  typename Arena         = HeapArena>
using ObjectPoolAllocator = Allocator<
  PoolAllocator<sizeof(T), std::max(alignof(T), alignof(Freelist)), Freelist>,
  Arena,
  AlignedHeapAllocator,
  LockingPolicy>;

template <typename T, typename Arena = HeapArena>
using ThreadSafeObjectPoolAllocator = Allocator<
  PoolAllocator<
    sizeof(T),
    std::max(alignof(T), alignof(ThreadSafeFreelist)),
    ThreadSafeFreelist>,
  Arena,
  AlignedHeapAllocator,
  VoidLock>;

/*==--- [implementation] ---------------------------------------------------==*/

template <
  typename PrimaryAllocator,
  typename Arena,
  typename FallbackAllocator,
  typename LockingPolicy>
class Allocator {
  static_assert(
    std::is_trivially_constructible_v<FallbackAllocator>,
    "Fallback allocator must be trivially constructible!");

 public:
  static constexpr bool contexpr_arena_size = Arena::constexpr_size;

  using Guard = std::lock_guard<LockingPolicy>;

  /*==--- [construction] ---------------------------------------------------==*/

  template <typename... Args>
  Allocator(size_t size, Args&&... args)
  : arena_(size), primary_(arena_, ripple_forward(args)...) {}

  ~Allocator() noexcept = default;

  // clang-format off
  Allocator(Allocator&& other) noexcept                    = default;
  auto operator=(Allocator&& other) noexcept -> Allocator& = default;

  /*==--- [deleted] --------------------------------------------------------==*/

  Allocator(const Allocator&)      = delete;
  auto operator=(const Allocator&) = delete;
  // clang-format on

  /*==--- [alloc/free interface] -------------------------------------------==*/

  auto alloc(size_t size, size_t alignment = alignof(std::max_align_t)) noexcept
    -> void* {
    Guard g(lock_);
    void* ptr = primary_.alloc(size, alignment);
    if (!ptr) {
      ptr = fallback_.alloc(size, alignment);
    }
    return ptr;
  }

  auto free(void* ptr) noexcept -> void {
    if (!ptr) {
      return;
    }

    Guard g(lock_);
    if (primary_.owns(ptr)) {
      primary_.free(ptr);
      return;
    }

    fallback_.free(ptr);
  }

  auto free(void* ptr, size_t size) noexcept -> void {
    if (!ptr) {
      return;
    }

    Guard g(lock_);
    if (primary_.owns(ptr)) {
      primary_.free(ptr, size);
      return;
    }
    fallback_.free(ptr, size);
  }

  auto reset() noexcept -> void {
    Guard g(lock_);
    primary_.reset();
  }

  /*==--- [create/destroy interface] ---------------------------------------==*/

  template <typename T, typename... Args>
  auto create(Args&&... args) noexcept -> T* {
    constexpr size_t size      = sizeof(T);
    constexpr size_t alignment = alignof(T);
    void* const      ptr       = alloc(size, alignment);

    return ptr ? new (ptr) T(ripple_forward(args)...) : nullptr;
  }

  template <typename T>
  auto recycle(T* ptr) noexcept -> void {
    if (!ptr) {
      return;
    }

    constexpr size_t size = sizeof(T);
    ptr->~T();
    free(static_cast<void*>(ptr), size);
  }

 private:
  Arena             arena_;
  PrimaryAllocator  primary_;
  FallbackAllocator fallback_;
  LockingPolicy     lock_;
};

} // namespace ripple

#endif // RIPPLE_ALLOCATION_ALLOCATOR_HP

Docs

Access comprehensive developer documentation for Ripple

View Docs

Tutorials

Get tutorials to help with understand all features

View Tutorials

Examples

Find examples to help get started

View Examples