/* SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "FN_cpp_type.hh" namespace blender::fn { /** * A generic non-const pointer whose type is only known at runtime. */ class GMutablePointer { private: const CPPType *type_ = nullptr; void *data_ = nullptr; public: GMutablePointer() = default; GMutablePointer(const CPPType *type, void *data = nullptr) : type_(type), data_(data) { /* If there is data, there has to be a type. */ BLI_assert(data_ == nullptr || type_ != nullptr); } GMutablePointer(const CPPType &type, void *data = nullptr) : GMutablePointer(&type, data) { } template GMutablePointer(T *data) : GMutablePointer(&CPPType::get(), data) { } void *get() const { return data_; } const CPPType *type() const { return type_; } template T *get() const { BLI_assert(this->is_type()); return static_cast(data_); } template bool is_type() const { return type_ != nullptr && type_->is(); } template T relocate_out() { BLI_assert(this->is_type()); T value; type_->relocate_assign(data_, &value); data_ = nullptr; type_ = nullptr; return value; } void destruct() { BLI_assert(data_ != nullptr); type_->destruct(data_); } }; /** * A generic const pointer whose type is only known at runtime. */ class GPointer { private: const CPPType *type_ = nullptr; const void *data_ = nullptr; public: GPointer() = default; GPointer(GMutablePointer ptr) : type_(ptr.type()), data_(ptr.get()) { } GPointer(const CPPType *type, const void *data = nullptr) : type_(type), data_(data) { /* If there is data, there has to be a type. */ BLI_assert(data_ == nullptr || type_ != nullptr); } GPointer(const CPPType &type, const void *data = nullptr) : type_(&type), data_(data) { } template GPointer(T *data) : GPointer(&CPPType::get(), data) { } const void *get() const { return data_; } const CPPType *type() const { return type_; } template const T *get() const { BLI_assert(this->is_type()); return static_cast(data_); } template bool is_type() const { return type_ != nullptr && type_->is(); } }; } // namespace blender::fn