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>2021-03-21 17:33:30 +0300
committerJacques Lucke <jacques@blender.org>2021-03-21 17:33:30 +0300
commit2ddbb2c64f00f1ba357fe41813523088a9215326 (patch)
treeab1e86876906856bbcd0ee3a91dc06ef6facd834 /source/blender/functions/FN_cpp_type_make.hh
parent9e437aabdb3d14c32584afb4bfa9e6eb35f06e51 (diff)
Functions: move CPPType creation related code to separate header
This does not need to be included everywhere, because it is only needed in very few translation units that actually define CPPType's.
Diffstat (limited to 'source/blender/functions/FN_cpp_type_make.hh')
-rw-r--r--source/blender/functions/FN_cpp_type_make.hh287
1 files changed, 287 insertions, 0 deletions
diff --git a/source/blender/functions/FN_cpp_type_make.hh b/source/blender/functions/FN_cpp_type_make.hh
new file mode 100644
index 00000000000..342161d01b6
--- /dev/null
+++ b/source/blender/functions/FN_cpp_type_make.hh
@@ -0,0 +1,287 @@
+/*
+ * 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 "FN_cpp_type.hh"
+
+namespace blender::fn::cpp_type_util {
+
+template<typename T> void construct_default_cb(void *ptr)
+{
+ new (ptr) T;
+}
+template<typename T> void construct_default_n_cb(void *ptr, int64_t n)
+{
+ blender::default_construct_n(static_cast<T *>(ptr), n);
+}
+template<typename T> void construct_default_indices_cb(void *ptr, IndexMask mask)
+{
+ mask.foreach_index([&](int64_t i) { new (static_cast<T *>(ptr) + i) T; });
+}
+
+template<typename T> void destruct_cb(void *ptr)
+{
+ (static_cast<T *>(ptr))->~T();
+}
+template<typename T> void destruct_n_cb(void *ptr, int64_t n)
+{
+ blender::destruct_n(static_cast<T *>(ptr), n);
+}
+template<typename T> void destruct_indices_cb(void *ptr, IndexMask mask)
+{
+ T *ptr_ = static_cast<T *>(ptr);
+ mask.foreach_index([&](int64_t i) { ptr_[i].~T(); });
+}
+
+template<typename T> void copy_to_initialized_cb(const void *src, void *dst)
+{
+ *static_cast<T *>(dst) = *static_cast<const T *>(src);
+}
+template<typename T> void copy_to_initialized_n_cb(const void *src, void *dst, int64_t n)
+{
+ const T *src_ = static_cast<const T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ for (int64_t i = 0; i < n; i++) {
+ dst_[i] = src_[i];
+ }
+}
+template<typename T>
+void copy_to_initialized_indices_cb(const void *src, void *dst, IndexMask mask)
+{
+ const T *src_ = static_cast<const T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ mask.foreach_index([&](int64_t i) { dst_[i] = src_[i]; });
+}
+
+template<typename T> void copy_to_uninitialized_cb(const void *src, void *dst)
+{
+ blender::uninitialized_copy_n(static_cast<const T *>(src), 1, static_cast<T *>(dst));
+}
+template<typename T> void copy_to_uninitialized_n_cb(const void *src, void *dst, int64_t n)
+{
+ blender::uninitialized_copy_n(static_cast<const T *>(src), n, static_cast<T *>(dst));
+}
+template<typename T>
+void copy_to_uninitialized_indices_cb(const void *src, void *dst, IndexMask mask)
+{
+ const T *src_ = static_cast<const T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ mask.foreach_index([&](int64_t i) { new (dst_ + i) T(src_[i]); });
+}
+
+template<typename T> void move_to_initialized_cb(void *src, void *dst)
+{
+ blender::initialized_move_n(static_cast<T *>(src), 1, static_cast<T *>(dst));
+}
+template<typename T> void move_to_initialized_n_cb(void *src, void *dst, int64_t n)
+{
+ blender::initialized_move_n(static_cast<T *>(src), n, static_cast<T *>(dst));
+}
+template<typename T> void move_to_initialized_indices_cb(void *src, void *dst, IndexMask mask)
+{
+ T *src_ = static_cast<T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ mask.foreach_index([&](int64_t i) { dst_[i] = std::move(src_[i]); });
+}
+
+template<typename T> void move_to_uninitialized_cb(void *src, void *dst)
+{
+ blender::uninitialized_move_n(static_cast<T *>(src), 1, static_cast<T *>(dst));
+}
+template<typename T> void move_to_uninitialized_n_cb(void *src, void *dst, int64_t n)
+{
+ blender::uninitialized_move_n(static_cast<T *>(src), n, static_cast<T *>(dst));
+}
+template<typename T> void move_to_uninitialized_indices_cb(void *src, void *dst, IndexMask mask)
+{
+ T *src_ = static_cast<T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ mask.foreach_index([&](int64_t i) { new (dst_ + i) T(std::move(src_[i])); });
+}
+
+template<typename T> void relocate_to_initialized_cb(void *src, void *dst)
+{
+ T *src_ = static_cast<T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ *dst_ = std::move(*src_);
+ src_->~T();
+}
+template<typename T> void relocate_to_initialized_n_cb(void *src, void *dst, int64_t n)
+{
+ blender::initialized_relocate_n(static_cast<T *>(src), n, static_cast<T *>(dst));
+}
+template<typename T> void relocate_to_initialized_indices_cb(void *src, void *dst, IndexMask mask)
+{
+ T *src_ = static_cast<T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ mask.foreach_index([&](int64_t i) {
+ dst_[i] = std::move(src_[i]);
+ src_[i].~T();
+ });
+}
+
+template<typename T> void relocate_to_uninitialized_cb(void *src, void *dst)
+{
+ T *src_ = static_cast<T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ new (dst_) T(std::move(*src_));
+ src_->~T();
+}
+template<typename T> void relocate_to_uninitialized_n_cb(void *src, void *dst, int64_t n)
+{
+ blender::uninitialized_relocate_n(static_cast<T *>(src), n, static_cast<T *>(dst));
+}
+template<typename T>
+void relocate_to_uninitialized_indices_cb(void *src, void *dst, IndexMask mask)
+{
+ T *src_ = static_cast<T *>(src);
+ T *dst_ = static_cast<T *>(dst);
+
+ mask.foreach_index([&](int64_t i) {
+ new (dst_ + i) T(std::move(src_[i]));
+ src_[i].~T();
+ });
+}
+
+template<typename T> void fill_initialized_cb(const void *value, void *dst, int64_t n)
+{
+ const T &value_ = *static_cast<const T *>(value);
+ T *dst_ = static_cast<T *>(dst);
+
+ for (int64_t i = 0; i < n; i++) {
+ dst_[i] = value_;
+ }
+}
+template<typename T> void fill_initialized_indices_cb(const void *value, void *dst, IndexMask mask)
+{
+ const T &value_ = *static_cast<const T *>(value);
+ T *dst_ = static_cast<T *>(dst);
+
+ mask.foreach_index([&](int64_t i) { dst_[i] = value_; });
+}
+
+template<typename T> void fill_uninitialized_cb(const void *value, void *dst, int64_t n)
+{
+ const T &value_ = *static_cast<const T *>(value);
+ T *dst_ = static_cast<T *>(dst);
+
+ for (int64_t i = 0; i < n; i++) {
+ new (dst_ + i) T(value_);
+ }
+}
+template<typename T>
+void fill_uninitialized_indices_cb(const void *value, void *dst, IndexMask mask)
+{
+ const T &value_ = *static_cast<const T *>(value);
+ T *dst_ = static_cast<T *>(dst);
+
+ mask.foreach_index([&](int64_t i) { new (dst_ + i) T(value_); });
+}
+
+template<typename T> void debug_print_cb(const void *value, std::stringstream &ss)
+{
+ const T &value_ = *static_cast<const T *>(value);
+ ss << value_;
+}
+
+template<typename T> bool is_equal_cb(const void *a, const void *b)
+{
+ const T &a_ = *static_cast<const T *>(a);
+ const T &b_ = *static_cast<const T *>(b);
+ return a_ == b_;
+}
+
+template<typename T> uint64_t hash_cb(const void *value)
+{
+ const T &value_ = *static_cast<const T *>(value);
+ return DefaultHash<T>{}(value_);
+}
+
+} // namespace blender::fn::cpp_type_util
+
+namespace blender::fn {
+
+template<typename T>
+inline std::unique_ptr<const CPPType> create_cpp_type(StringRef name, const T &default_value)
+{
+ using namespace cpp_type_util;
+ const CPPType *type = new CPPType(name,
+ sizeof(T),
+ alignof(T),
+ std::is_trivially_destructible_v<T>,
+ construct_default_cb<T>,
+ construct_default_n_cb<T>,
+ construct_default_indices_cb<T>,
+ destruct_cb<T>,
+ destruct_n_cb<T>,
+ destruct_indices_cb<T>,
+ copy_to_initialized_cb<T>,
+ copy_to_initialized_n_cb<T>,
+ copy_to_initialized_indices_cb<T>,
+ copy_to_uninitialized_cb<T>,
+ copy_to_uninitialized_n_cb<T>,
+ copy_to_uninitialized_indices_cb<T>,
+ move_to_initialized_cb<T>,
+ move_to_initialized_n_cb<T>,
+ move_to_initialized_indices_cb<T>,
+ move_to_uninitialized_cb<T>,
+ move_to_uninitialized_n_cb<T>,
+ move_to_uninitialized_indices_cb<T>,
+ relocate_to_initialized_cb<T>,
+ relocate_to_initialized_n_cb<T>,
+ relocate_to_initialized_indices_cb<T>,
+ relocate_to_uninitialized_cb<T>,
+ relocate_to_uninitialized_n_cb<T>,
+ relocate_to_uninitialized_indices_cb<T>,
+ fill_initialized_cb<T>,
+ fill_initialized_indices_cb<T>,
+ fill_uninitialized_cb<T>,
+ fill_uninitialized_indices_cb<T>,
+ debug_print_cb<T>,
+ is_equal_cb<T>,
+ hash_cb<T>,
+ static_cast<const void *>(&default_value));
+ return std::unique_ptr<const CPPType>(type);
+}
+
+} // namespace blender::fn
+
+#define MAKE_CPP_TYPE(IDENTIFIER, TYPE_NAME) \
+ template<> const blender::fn::CPPType &blender::fn::CPPType::get<TYPE_NAME>() \
+ { \
+ static TYPE_NAME default_value; \
+ static std::unique_ptr<const CPPType> cpp_type = blender::fn::create_cpp_type<TYPE_NAME>( \
+ STRINGIFY(IDENTIFIER), default_value); \
+ return *cpp_type; \
+ } \
+ /* Support using `CPPType::get<const T>()`. Otherwise the caller would have to remove const. */ \
+ template<> const blender::fn::CPPType &blender::fn::CPPType::get<const TYPE_NAME>() \
+ { \
+ return blender::fn::CPPType::get<TYPE_NAME>(); \
+ }