Changeset View
Changeset View
Standalone View
Standalone View
source/blender/functions/FN_generic_array.hh
- This file was added.
| /* | |||||
| * 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 2 | |||||
| * 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, write to the Free Software Foundation, | |||||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||||
| */ | |||||
| #pragma once | |||||
| /** \file | |||||
| * \ingroup fn | |||||
| */ | |||||
| #include "BLI_array.hh" | |||||
| #include "FN_cpp_type.hh" | |||||
| #include "FN_generic_span.hh" | |||||
| namespace blender::fn { | |||||
| template< | |||||
JacquesLucke: Not sure if this comment really belongs here, seems unrelated to the entire file. | |||||
| /** | |||||
| * The allocator used by this array. Should rarely be changed, except when you don't want that | |||||
| * MEM_* functions are used internally. | |||||
| */ | |||||
| typename Allocator = GuardedAllocator> | |||||
| class GArray { | |||||
| protected: | |||||
| const CPPType *type_; | |||||
| void *data_; | |||||
| int64_t size_; | |||||
| Allocator allocator_; | |||||
| public: | |||||
| GArray(const CPPType &type, void *buffer, int64_t size) | |||||
| : type_(&type), data_(buffer), size_(size) | |||||
| { | |||||
| BLI_assert(size >= 0); | |||||
| BLI_assert(buffer != nullptr || size == 0); | |||||
| BLI_assert(type.pointer_has_valid_alignment(buffer)); | |||||
| } | |||||
| GArray(const CPPType &type, int64_t size) : type_(&type) | |||||
| { | |||||
| BLI_assert(size >= 0); | |||||
| this->get_buffer_for_size(size); | |||||
| } | |||||
| GArray(const CPPType &type) : GArray(type, nullptr, 0) | |||||
| { | |||||
| } | |||||
| // template<typename T> | |||||
| // GArray(Array<T> &&array) : GArray(CPPType::get<T>(), nullptr, 0), | |||||
| // allocator_(array.allocator()) | |||||
| // { | |||||
| // if (array.size() < array.inline_buffer_capacity()) { | |||||
| // type_->relocate_to_initialized_n(array.data(), data_, array.size()); | |||||
| // } | |||||
| // else { | |||||
| // data_ = array.data(); | |||||
| // } | |||||
| // size_ = array.size(); | |||||
| // array.clear_without_destruct(); | |||||
| // } | |||||
| ~GArray() | |||||
| { | |||||
| if (data_ != nullptr) { | |||||
| type_->destruct_n(data_, size_); | |||||
| this->deallocate(data_); | |||||
| } | |||||
| } | |||||
| const CPPType &type() const | |||||
| { | |||||
| return *type_; | |||||
| } | |||||
| bool is_empty() const | |||||
| { | |||||
| return size_ == 0; | |||||
| } | |||||
| int64_t size() const | |||||
| { | |||||
| return size_; | |||||
| } | |||||
| const void *data() const | |||||
| { | |||||
| return data_; | |||||
| } | |||||
| const void *operator[](int64_t index) const | |||||
| { | |||||
| BLI_assert(index < size_); | |||||
| return POINTER_OFFSET(data_, type_->size() * index); | |||||
| } | |||||
| void *operator[](int64_t index) | |||||
| { | |||||
| BLI_assert(index < size_); | |||||
| return POINTER_OFFSET(data_, type_->size() * index); | |||||
| } | |||||
| operator GSpan() const | |||||
| { | |||||
| return GSpan(*type_, data_, size_); | |||||
| } | |||||
| operator GMutableSpan() | |||||
| { | |||||
| return GMutableSpan(*type_, data_, size_); | |||||
| } | |||||
| GSpan as_span() const | |||||
| { | |||||
| return *this; | |||||
| } | |||||
| GMutableSpan as_mutable_span() | |||||
| { | |||||
| return *this; | |||||
| } | |||||
| /** | |||||
| * Access the allocator used by this array. | |||||
| */ | |||||
| Allocator &allocator() | |||||
| { | |||||
| return allocator_; | |||||
| } | |||||
| const Allocator &allocator() const | |||||
| { | |||||
| return allocator_; | |||||
| } | |||||
| /** | |||||
Done Inline ActionsThis expects that there is a NoExceptConstructor constructor. JacquesLucke: This expects that there is a `NoExceptConstructor` constructor. | |||||
| * Destruct values and create a new array of the given size. The values in the new array are | |||||
| * default constructed. | |||||
| */ | |||||
| void reinitialize(const int64_t new_size) | |||||
| { | |||||
| BLI_assert(new_size >= 0); | |||||
| int64_t old_size = size_; | |||||
| type_->destruct_n(data_, size_); | |||||
| size_ = 0; | |||||
| if (new_size <= old_size) { | |||||
| type_->construct_default_n(data_, new_size); | |||||
| } | |||||
| else { | |||||
| void *new_data = this->get_buffer_for_size(new_size); | |||||
| try { | |||||
| type_->construct_default_n(new_data, new_size); | |||||
| } | |||||
| catch (...) { | |||||
| this->deallocate(new_data); | |||||
| throw; | |||||
| } | |||||
| this->deallocate(data_); | |||||
| data_ = new_data; | |||||
| } | |||||
| size_ = new_size; | |||||
| } | |||||
| private: | |||||
| void *get_buffer_for_size(int64_t size) | |||||
| { | |||||
| return this->allocate(size); | |||||
| } | |||||
| void *allocate(int64_t size) | |||||
| { | |||||
| const int64_t item_size = type_->size(); | |||||
| const int64_t alignment = type_->alignment(); | |||||
| return allocator_.allocate(static_cast<size_t>(size) * item_size, alignment, AT); | |||||
| } | |||||
| void deallocate(void *ptr) | |||||
| { | |||||
| allocator_.deallocate(ptr); | |||||
| } | |||||
| }; | |||||
| } // namespace blender::fn | |||||
| No newline at end of file | |||||
Not sure if this comment really belongs here, seems unrelated to the entire file.