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

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

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