Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2022-03-19 10:26:29 +0300
committerJacques Lucke <jacques@blender.org>2022-03-19 10:26:29 +0300
commit3e16f3b3ef4b8f385b30fe4a1e00860620f610ee (patch)
treecea8e2a3ea8a8a7dbce98263d166b4782d83721b /source/blender/blenlib/BLI_generic_pointer.hh
parentc655146b87fe20853e52b87991b46732a04d749e (diff)
BLI: move generic data structures to blenlib
This is a follow up to rB2252bc6a5527cd7360d1ccfe7a2d1bc640a8dfa6.
Diffstat (limited to 'source/blender/blenlib/BLI_generic_pointer.hh')
-rw-r--r--source/blender/blenlib/BLI_generic_pointer.hh123
1 files changed, 123 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_generic_pointer.hh b/source/blender/blenlib/BLI_generic_pointer.hh
new file mode 100644
index 00000000000..226f76c3d33
--- /dev/null
+++ b/source/blender/blenlib/BLI_generic_pointer.hh
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_cpp_type.hh"
+
+namespace blender {
+
+/**
+ * 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<typename T> GMutablePointer(T *data) : GMutablePointer(&CPPType::get<T>(), data)
+ {
+ }
+
+ void *get() const
+ {
+ return data_;
+ }
+
+ const CPPType *type() const
+ {
+ return type_;
+ }
+
+ template<typename T> T *get() const
+ {
+ BLI_assert(this->is_type<T>());
+ return static_cast<T *>(data_);
+ }
+
+ template<typename T> bool is_type() const
+ {
+ return type_ != nullptr && type_->is<T>();
+ }
+
+ template<typename T> T relocate_out()
+ {
+ BLI_assert(this->is_type<T>());
+ 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<typename T> GPointer(T *data) : GPointer(&CPPType::get<T>(), data)
+ {
+ }
+
+ const void *get() const
+ {
+ return data_;
+ }
+
+ const CPPType *type() const
+ {
+ return type_;
+ }
+
+ template<typename T> const T *get() const
+ {
+ BLI_assert(this->is_type<T>());
+ return static_cast<const T *>(data_);
+ }
+
+ template<typename T> bool is_type() const
+ {
+ return type_ != nullptr && type_->is<T>();
+ }
+};
+
+} // namespace blender