diff --git a/include/blt/std/allocator.h b/include/blt/std/allocator.h index 53eb2cc..38ffe47 100644 --- a/include/blt/std/allocator.h +++ b/include/blt/std/allocator.h @@ -26,6 +26,40 @@ namespace blt { + + template + class allocator_base + { + public: + template + inline void construct(U* p, Args&& ... args) + { + ::new((void*) p) U(std::forward(args)...); + } + + template + inline void destroy(U* p) + { + if (p != nullptr) + p->~U(); + } + + [[nodiscard]] inline size_t max_size() const + { + return std::numeric_limits::max(); + } + + inline const_pointer address(const value_type& val) + { + return std::addressof(val); + } + + inline pointer address(value_type& val) + { + return std::addressof(val); + } + }; + template class area_allocator { @@ -47,6 +81,7 @@ namespace blt { typedef blt::area_allocator other; }; + using allocator_base::allocator_base; private: /** * Stores a view to a region of memory that has been deallocated @@ -225,6 +260,129 @@ namespace blt } } + ~area_allocator() + { + for (auto*& blk : blocks) + { + free(blk->data); + delete blk; + } + } + + private: + std::vector blocks; + }; + + template + class bump_allocator + { + public: + using value = T; + using type = T; + using value_type = type; + using pointer = type*; + using const_pointer = const type*; + using void_pointer = void*; + using const_void_pointer = const void*; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = size_t; + using difference_type = size_t; + using propagate_on_container_move_assignment = std::false_type; + template + struct rebind + { + typedef blt::bump_allocator other; + }; + using allocator_base::allocator_base; + private: + pointer buffer_; + blt::size_t offset_; + blt::size_t size_; + public: + explicit bump_allocator(blt::size_t size): buffer_(malloc(size * sizeof(T))), size_(size), offset_(0) + {} + + template + explicit bump_allocator(blt::size_t size, Args&& ... defaults): buffer_(malloc(size * sizeof(type))), size_(size), offset_(0) + { + for (blt::size_t i = 0; i < size_; i++) + ::new(&buffer_[i]) T(std::forward(defaults)...); + } + + bump_allocator(pointer buffer, blt::size_t size): buffer_(buffer), size_(size), offset_(0) + {} + + bump_allocator(const bump_allocator& copy) = delete; + + bump_allocator(bump_allocator&& move) noexcept + { + buffer_ = move.buffer_; + size_ = move.size_; + offset_ = move.offset_; + } + + bump_allocator& operator=(const bump_allocator& copy) = delete; + + bump_allocator& operator=(bump_allocator&& move) noexcept + { + std::swap(move.buffer_, buffer_); + std::swap(move.size_, size_); + std::swap(move.offset_, offset_); + } + + pointer allocate(blt::size_t n) + { + auto nv = offset_ + n; + if (nv > size_) + throw std::bad_alloc(); + pointer b = &buffer_[offset_]; + offset_ = nv; + return b; + } + + void deallocate(pointer, blt::size_t) + {} + + ~bump_allocator() + { + free(buffer_); + } + }; + + class multi_type_area_allocator + { + private: + struct pointer_view + { + blt::u8* p; + size_t n; + }; + + blt::u8* buffer_; + blt::u8* offset_; + blt::size_t size_; + public: + + template + [[nodiscard]] T* allocate() + { + size_t remaining_num_bytes = size_ - static_cast(buffer_ - offset_); + auto pointer = static_cast(offset_); + const auto aligned_address = std::align(alignof(T), sizeof(T), pointer, remaining_num_bytes); + if (aligned_address == nullptr) + throw std::bad_alloc{}; + offset_ = static_cast(aligned_address) + sizeof(T); + return static_cast(aligned_address); + } + + template + [[nodiscard]] T* emplace(Args&& ... args) + { + const auto allocated_memory = allocate(); + return new(allocated_memory) T{std::forward(args)...}; + } + template inline void construct(U* p, Args&& ... args) { @@ -238,32 +396,10 @@ namespace blt p->~U(); } - [[nodiscard]] inline size_t max_size() const + ~multi_type_area_allocator() { - return std::numeric_limits::max(); + delete[] buffer_; } - - inline const_pointer address(const value_type& val) - { - return std::addressof(val); - } - - inline pointer address(value_type& val) - { - return std::addressof(val); - } - - ~area_allocator() - { - for (auto*& blk : blocks) - { - free(blk->data); - delete blk; - } - } - - private: - std::vector blocks; }; } diff --git a/include/blt/std/simd.h b/include/blt/std/simd.h new file mode 100644 index 0000000..f4fd4ba --- /dev/null +++ b/include/blt/std/simd.h @@ -0,0 +1,26 @@ +/* + * + * Copyright (C) 2024 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BLT_SIMD_H +#define BLT_SIMD_H + +#include + + + +#endif // BLT_SIMD_H