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.
This commit is contained in:
Jacques Lucke 2021-03-21 15:33:30 +01:00
parent 9e437aabdb
commit 2ddbb2c64f
7 changed files with 293 additions and 265 deletions

View File

@ -36,6 +36,7 @@ set(SRC
FN_array_spans.hh
FN_cpp_type.hh
FN_cpp_type_make.hh
FN_generic_pointer.hh
FN_generic_value_map.hh
FN_generic_vector_array.hh

View File

@ -670,272 +670,8 @@ class CPPType : NonCopyable, NonMovable {
}
};
/* --------------------------------------------------------------------
* Utility for creating CPPType instances for C++ types.
*/
namespace 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 cpp_type_util
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>(); \
}
/* Utility for allocating an uninitialized buffer for a single value of the given #CPPType. */
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name) \
blender::DynamicStackBuffer<64, 64> stack_buffer_for_##variable_name(type.size(), \

View File

@ -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>(); \
}

View File

@ -14,7 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "FN_cpp_type.hh"
#include "FN_cpp_type_make.hh"
#include "BLI_color.hh"
#include "BLI_float2.hh"

View File

@ -3,6 +3,7 @@
#include "testing/testing.h"
#include "FN_cpp_type.hh"
#include "FN_cpp_type_make.hh"
namespace blender::fn::tests {

View File

@ -14,6 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "FN_cpp_type_make.hh"
#include "NOD_geometry_exec.hh"
MAKE_CPP_TYPE(GeometrySet, GeometrySet);

View File

@ -47,6 +47,8 @@
#include "NOD_node_tree_multi_function.hh"
#include "NOD_socket.h"
#include "FN_cpp_type_make.hh"
struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree,
struct bNode *node,
struct bNodeSocketTemplate *stemp,