diff --git a/CMakeLists.txt b/CMakeLists.txt index 6543d4d0..815fe385 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,9 +37,10 @@ else() CACHE INTERNAL "") add_library(foonathan_memory ${src}) - add_executable(foonathan_memory_example ${src} example/main.cpp) + add_executable(foonathan_memory_example_allocator ${src} example/allocator.cpp) + add_executable(foonathan_memory_example_smart_ptr ${src} example/smart_ptr.cpp) - set(targets foonathan_memory foonathan_memory_example CACHE INTERNAL "") + set(targets foonathan_memory foonathan_memory_example_allocator foonathan_memory_example_smart_ptr CACHE INTERNAL "") set_target_properties(${targets} PROPERTIES CXX_STANDARD 11) set_target_properties(${targets} PROPERTIES CXX_STANDARD_REQUIRED ON) diff --git a/detail/block_list.hpp b/detail/block_list.hpp index fcc424bc..1231a565 100644 --- a/detail/block_list.hpp +++ b/detail/block_list.hpp @@ -96,10 +96,12 @@ namespace foonathan { namespace memory { auto memory = get_allocator(). allocate_node(cur_block_size_, alignof(std::max_align_t)); + ++size_; auto size = cur_block_size_ - used_.push(memory, cur_block_size_); cur_block_size_ *= growth_factor; return {memory, size}; } + ++size_; // already block cached in free list return used_.push(free_); } @@ -108,6 +110,7 @@ namespace foonathan { namespace memory // does not free memory, caches the block for future use void deallocate() noexcept { + --size_; free_.push(used_); } @@ -128,9 +131,14 @@ namespace foonathan { namespace memory return cur_block_size_ - block_list_impl::impl_offset(); } + std::size_t size() const noexcept + { + return size_; + } + private: block_list_impl used_, free_; - std::size_t cur_block_size_; + std::size_t size_, cur_block_size_; }; } // namespace detail }} // namespace foonathan::memory diff --git a/example/main.cpp b/example/allocator.cpp similarity index 100% rename from example/main.cpp rename to example/allocator.cpp diff --git a/example/smart_ptr.cpp b/example/smart_ptr.cpp new file mode 100644 index 00000000..33977114 --- /dev/null +++ b/example/smart_ptr.cpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#include + +#include "../smart_ptr.hpp" // raw_allocate_unique/shared +#include "../stack_allocator.hpp" // memory_stack + +using namespace foonathan; + +void func(const std::shared_ptr &ptr) +{ + std::cout << *ptr << '\n'; + *ptr = 10; +} + +int main() +{ + // create a memory stack initially 4KB big + memory::memory_stack<> stack(4096); + + // create a shared pointer + // special deleter takes care of deallocation + auto sptr = memory::raw_allocate_shared(stack, 5); + func(sptr); + + // create marker for stack unwinding + auto m = stack.top(); + for (auto i = 0u; i != 10; ++i) + { + // free all memory from previous iteration + stack.unwind(m); + + // create a unique pointer to a single int + // when ptr goes out of scope, its special deleter will call the appropriate deallocate function + // this is a no-op for memory_stack but for other allocator types it works + auto ptr = memory::raw_allocate_unique(stack, i); + std::cout << *ptr << '\n'; + + // create a unique pointer for an array of size 3 + auto array = memory::raw_allocate_unique(stack, 3); + array[2] = 5; + } +} diff --git a/stack_allocator.hpp b/stack_allocator.hpp index d0796012..e7c3a6a2 100644 --- a/stack_allocator.hpp +++ b/stack_allocator.hpp @@ -67,6 +67,8 @@ namespace foonathan { namespace memory marker(std::size_t i, detail::fixed_memory_stack stack) noexcept : index(i), stack(stack) {} + + friend memory_stack; }; /// \brief Returns a marker to the current top of the stack.