Program Listing for File linear_allocator.hpp¶
↰ Return to documentation for file (include/ripple/allocation/linear_allocator.hpp)
#ifndef RIPPLE_ALLOCATION_LINEAR_ALLOCATOR_HPP
#define RIPPLE_ALLOCATION_LINEAR_ALLOCATOR_HPP
#include <ripple/utility/memory.hpp>
namespace ripple {
class LinearAllocator {
 public:
  LinearAllocator(void* begin, void* end) noexcept
  : begin_(begin), size_(uintptr_t(end) - uintptr_t(begin)) {}
  template <typename Arena>
  explicit LinearAllocator(const Arena& arena) noexcept
  : LinearAllocator(arena.begin(), arena.end()) {}
  ~LinearAllocator() noexcept {
    if (begin_ != nullptr) {
      begin_   = nullptr;
      current_ = 0;
      size_    = 0;
    }
  };
  LinearAllocator(LinearAllocator&& other) noexcept {
    swap(other);
  }
  auto operator=(LinearAllocator&& other) noexcept -> LinearAllocator& {
    if (this != &other) {
      swap(other);
    }
    return *this;
  }
  // clang-format off
  LinearAllocator(const LinearAllocator&) = delete;
  auto operator=(const LinearAllocator&)  = delete;
  // clang-format on
  /*==--- [interface] ------------------------------------------------------==*/
  auto alloc(size_t size, size_t alignment) noexcept -> void* {
    void* const ptr     = align_ptr(current(), alignment);
    void* const curr    = offset_ptr(ptr, size);
    bool        success = curr <= end();
    set_current(success ? curr : current());
    return success ? ptr : nullptr;
  }
  auto free(void* ptr) noexcept -> void {}
  auto free(void* ptr, size_t size) noexcept -> void {}
  auto capacity() noexcept -> size_t {
    return uintptr_t(offset_ptr(begin_, size_)) - uintptr_t(current_);
  }
  auto reset(void* begin = nullptr, void* end = nullptr) noexcept -> void {
    current_ = 0;
    if (begin != nullptr && end != nullptr) {
      begin_ = begin;
      size_  = uintptr_t(end) - uintptr_t(begin_);
    }
  }
 private:
  void*    begin_   = nullptr;
  uint32_t size_    = 0;
  uint32_t current_ = 0;
  ripple_nodiscard auto current() const noexcept -> void* {
    return offset_ptr(begin_, current_);
  }
  auto set_current(void* current) noexcept -> void {
    current_ = uintptr_t(current) - uintptr_t(begin_);
  }
  ripple_nodiscard auto end() const noexcept -> void* {
    return offset_ptr(begin_, size_);
  }
  auto swap(LinearAllocator& other) noexcept -> void {
    auto swap_impl = [](auto& lhs, auto& rhs) {
      auto tmp(lhs);
      lhs = rhs;
      rhs = tmp;
    };
    swap_impl(begin_, other.begin_);
    swap_impl(size_, other.size_);
    swap_impl(current_, other.current_);
  }
};
} // namespace ripple
#endif // RIPPLE_CORE_MEMORY_LINEAR_ALLOCATOR_HPP