Compare commits
12 Commits
cycles_pat
...
temp-cpp-t
Author | SHA1 | Date | |
---|---|---|---|
3bf9843f48 | |||
b6cb04cd0f | |||
89ebdfdb83 | |||
3dfee3c0b1 | |||
93641b7866 | |||
a7f3b1a3ef | |||
8cd16b4014 | |||
739056418e | |||
2bf84b9410 | |||
b4956ad6e0 | |||
c55061f539 | |||
25c1f9cd08 |
@@ -280,8 +280,6 @@ struct GeometrySet {
|
||||
void compute_boundbox_without_instances(blender::float3 *r_min, blender::float3 *r_max) const;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);
|
||||
friend bool operator==(const GeometrySet &a, const GeometrySet &b);
|
||||
uint64_t hash() const;
|
||||
|
||||
void clear();
|
||||
|
||||
|
@@ -1197,7 +1197,7 @@ static blender::bke::OutputAttribute create_output_attribute(
|
||||
cpp_type->size() * domain_size, cpp_type->alignment(), __func__);
|
||||
if (ignore_old_values) {
|
||||
/* This does nothing for trivially constructible types, but is necessary for correctness. */
|
||||
cpp_type->construct_default_n(data, domain);
|
||||
cpp_type->default_construct_n(data, domain);
|
||||
}
|
||||
else {
|
||||
/* Fill the temporary array with values from the existing attribute. */
|
||||
|
@@ -199,20 +199,6 @@ std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set)
|
||||
return stream;
|
||||
}
|
||||
|
||||
/* This generally should not be used. It is necessary currently, so that GeometrySet can by used by
|
||||
* the CPPType system. */
|
||||
bool operator==(const GeometrySet &UNUSED(a), const GeometrySet &UNUSED(b))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This generally should not be used. It is necessary currently, so that GeometrySet can by used by
|
||||
* the CPPType system. */
|
||||
uint64_t GeometrySet::hash() const
|
||||
{
|
||||
return reinterpret_cast<uint64_t>(this);
|
||||
}
|
||||
|
||||
/* Remove all geometry components from the geometry set. */
|
||||
void GeometrySet::clear()
|
||||
{
|
||||
|
@@ -535,7 +535,7 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
|
||||
const void *src_buffer = src_span.data();
|
||||
for (const int UNUSED(i) : set_group.transforms.index_range()) {
|
||||
void *dst_buffer = dst_span[offset];
|
||||
cpp_type->copy_to_initialized_n(src_buffer, dst_buffer, domain_size);
|
||||
cpp_type->copy_assign_n(src_buffer, dst_buffer, domain_size);
|
||||
offset += domain_size;
|
||||
}
|
||||
}
|
||||
|
@@ -788,23 +788,24 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size);
|
||||
extern "C++" { \
|
||||
inline constexpr _enum_type operator|(_enum_type a, _enum_type b) \
|
||||
{ \
|
||||
return static_cast<_enum_type>(static_cast<int>(a) | b); \
|
||||
return static_cast<_enum_type>(static_cast<uint64_t>(a) | static_cast<uint64_t>(b)); \
|
||||
} \
|
||||
inline constexpr _enum_type operator&(_enum_type a, _enum_type b) \
|
||||
{ \
|
||||
return static_cast<_enum_type>(static_cast<int>(a) & b); \
|
||||
return static_cast<_enum_type>(static_cast<uint64_t>(a) & static_cast<uint64_t>(b)); \
|
||||
} \
|
||||
inline constexpr _enum_type operator~(_enum_type a) \
|
||||
{ \
|
||||
return static_cast<_enum_type>(~static_cast<int>(a) & (2 * _max_enum_value - 1)); \
|
||||
return static_cast<_enum_type>(~static_cast<uint64_t>(a) & \
|
||||
(2 * static_cast<uint64_t>(_max_enum_value) - 1)); \
|
||||
} \
|
||||
inline _enum_type &operator|=(_enum_type &a, _enum_type b) \
|
||||
{ \
|
||||
return a = static_cast<_enum_type>(static_cast<int>(a) | b); \
|
||||
return a = static_cast<_enum_type>(static_cast<uint64_t>(a) | static_cast<uint64_t>(b)); \
|
||||
} \
|
||||
inline _enum_type &operator&=(_enum_type &a, _enum_type b) \
|
||||
{ \
|
||||
return a = static_cast<_enum_type>(static_cast<int>(a) & b); \
|
||||
return a = static_cast<_enum_type>(static_cast<uint64_t>(a) & static_cast<uint64_t>(b)); \
|
||||
} \
|
||||
} /* extern "C++" */
|
||||
|
||||
|
@@ -19,10 +19,9 @@
|
||||
/** \file
|
||||
* \ingroup fn
|
||||
*
|
||||
* The CPPType class is the core of the runtime-type-system used by the functions system. It can
|
||||
* represent C++ types that are default-constructible, destructible, movable, copyable,
|
||||
* equality comparable and hashable. In the future we might want to make some of these properties
|
||||
* optional.
|
||||
* The `CPPType` class is the core of a runtime-type-system. It allows working with arbitrary C++
|
||||
* types in a generic way. An instance of `CPPType` wraps exactly one type like `int` or
|
||||
* `std::string`.
|
||||
*
|
||||
* Every type has a size and an alignment. Every function dealing with C++ types in a generic way,
|
||||
* has to make sure that alignment rules are followed. The methods provided by a CPPType instance
|
||||
@@ -35,11 +34,11 @@
|
||||
*
|
||||
* A CPPType instance comes with many methods that allow dealing with types in a generic way. Most
|
||||
* methods come in three variants. Using the construct-default methods as example:
|
||||
* - construct_default(void *ptr):
|
||||
* - default_construct(void *ptr):
|
||||
* Constructs a single instance of that type at the given pointer.
|
||||
* - construct_default_n(void *ptr, int64_t n):
|
||||
* - default_construct_n(void *ptr, int64_t n):
|
||||
* Constructs n instances of that type in an array that starts at the given pointer.
|
||||
* - construct_default_indices(void *ptr, IndexMask mask):
|
||||
* - default_construct_indices(void *ptr, IndexMask mask):
|
||||
* Constructs multiple instances of that type in an array that starts at the given pointer.
|
||||
* Only the indices referenced by `mask` will by constructed.
|
||||
*
|
||||
@@ -58,7 +57,7 @@
|
||||
* used now with explicit function pointers to work better. Here are some reasons:
|
||||
* - If CPPType would be inherited once for every used C++ type, we would get a lot of classes
|
||||
* that would only be instanced once each.
|
||||
* - Methods like `construct_default` that operate on a single instance have to be fast. Even this
|
||||
* - Methods like `default_construct` that operate on a single instance have to be fast. Even this
|
||||
* one necessary indirection using function pointers adds a lot of overhead. If all methods were
|
||||
* virtual, there would be a second level of indirection that increases the overhead even more.
|
||||
* - If it becomes necessary, we could pass the function pointers to C functions more easily than
|
||||
@@ -73,177 +72,61 @@
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
struct CPPTypeMembers {
|
||||
int64_t size = 0;
|
||||
int64_t alignment = 0;
|
||||
uintptr_t alignment_mask = 0;
|
||||
bool is_trivially_destructible = false;
|
||||
bool has_special_member_functions = false;
|
||||
|
||||
void (*default_construct)(void *ptr) = nullptr;
|
||||
void (*default_construct_indices)(void *ptr, IndexMask mask) = nullptr;
|
||||
|
||||
void (*destruct)(void *ptr) = nullptr;
|
||||
void (*destruct_indices)(void *ptr, IndexMask mask) = nullptr;
|
||||
|
||||
void (*copy_assign)(const void *src, void *dst) = nullptr;
|
||||
void (*copy_assign_indices)(const void *src, void *dst, IndexMask mask) = nullptr;
|
||||
|
||||
void (*copy_construct)(const void *src, void *dst) = nullptr;
|
||||
void (*copy_construct_indices)(const void *src, void *dst, IndexMask mask) = nullptr;
|
||||
|
||||
void (*move_assign)(void *src, void *dst) = nullptr;
|
||||
void (*move_assign_indices)(void *src, void *dst, IndexMask mask) = nullptr;
|
||||
|
||||
void (*move_construct)(void *src, void *dst) = nullptr;
|
||||
void (*move_construct_indices)(void *src, void *dst, IndexMask mask) = nullptr;
|
||||
|
||||
void (*relocate_assign)(void *src, void *dst) = nullptr;
|
||||
void (*relocate_assign_indices)(void *src, void *dst, IndexMask mask) = nullptr;
|
||||
|
||||
void (*relocate_construct)(void *src, void *dst) = nullptr;
|
||||
void (*relocate_construct_indices)(void *src, void *dst, IndexMask mask) = nullptr;
|
||||
|
||||
void (*fill_assign_indices)(const void *value, void *dst, IndexMask mask) = nullptr;
|
||||
|
||||
void (*fill_construct_indices)(const void *value, void *dst, IndexMask mask) = nullptr;
|
||||
|
||||
void (*print)(const void *value, std::stringstream &ss) = nullptr;
|
||||
bool (*is_equal)(const void *a, const void *b) = nullptr;
|
||||
uint64_t (*hash)(const void *value) = nullptr;
|
||||
|
||||
const void *default_value = nullptr;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class CPPType : NonCopyable, NonMovable {
|
||||
public:
|
||||
using ConstructDefaultF = void (*)(void *ptr);
|
||||
using ConstructDefaultNF = void (*)(void *ptr, int64_t n);
|
||||
using ConstructDefaultIndicesF = void (*)(void *ptr, IndexMask mask);
|
||||
|
||||
using DestructF = void (*)(void *ptr);
|
||||
using DestructNF = void (*)(void *ptr, int64_t n);
|
||||
using DestructIndicesF = void (*)(void *ptr, IndexMask mask);
|
||||
|
||||
using CopyToInitializedF = void (*)(const void *src, void *dst);
|
||||
using CopyToInitializedNF = void (*)(const void *src, void *dst, int64_t n);
|
||||
using CopyToInitializedIndicesF = void (*)(const void *src, void *dst, IndexMask mask);
|
||||
|
||||
using CopyToUninitializedF = void (*)(const void *src, void *dst);
|
||||
using CopyToUninitializedNF = void (*)(const void *src, void *dst, int64_t n);
|
||||
using CopyToUninitializedIndicesF = void (*)(const void *src, void *dst, IndexMask mask);
|
||||
|
||||
using MoveToInitializedF = void (*)(void *src, void *dst);
|
||||
using MoveToInitializedNF = void (*)(void *src, void *dst, int64_t n);
|
||||
using MoveToInitializedIndicesF = void (*)(void *src, void *dst, IndexMask mask);
|
||||
|
||||
using MoveToUninitializedF = void (*)(void *src, void *dst);
|
||||
using MoveToUninitializedNF = void (*)(void *src, void *dst, int64_t n);
|
||||
using MoveToUninitializedIndicesF = void (*)(void *src, void *dst, IndexMask mask);
|
||||
|
||||
using RelocateToInitializedF = void (*)(void *src, void *dst);
|
||||
using RelocateToInitializedNF = void (*)(void *src, void *dst, int64_t n);
|
||||
using RelocateToInitializedIndicesF = void (*)(void *src, void *dst, IndexMask mask);
|
||||
|
||||
using RelocateToUninitializedF = void (*)(void *src, void *dst);
|
||||
using RelocateToUninitializedNF = void (*)(void *src, void *dst, int64_t n);
|
||||
using RelocateToUninitializedIndicesF = void (*)(void *src, void *dst, IndexMask mask);
|
||||
|
||||
using FillInitializedF = void (*)(const void *value, void *dst, int64_t n);
|
||||
using FillInitializedIndicesF = void (*)(const void *value, void *dst, IndexMask mask);
|
||||
|
||||
using FillUninitializedF = void (*)(const void *value, void *dst, int64_t n);
|
||||
using FillUninitializedIndicesF = void (*)(const void *value, void *dst, IndexMask mask);
|
||||
|
||||
using DebugPrintF = void (*)(const void *value, std::stringstream &ss);
|
||||
using IsEqualF = bool (*)(const void *a, const void *b);
|
||||
using HashF = uint64_t (*)(const void *value);
|
||||
|
||||
private:
|
||||
int64_t size_;
|
||||
int64_t alignment_;
|
||||
uintptr_t alignment_mask_;
|
||||
bool is_trivially_destructible_;
|
||||
|
||||
ConstructDefaultF construct_default_;
|
||||
ConstructDefaultNF construct_default_n_;
|
||||
ConstructDefaultIndicesF construct_default_indices_;
|
||||
|
||||
DestructF destruct_;
|
||||
DestructNF destruct_n_;
|
||||
DestructIndicesF destruct_indices_;
|
||||
|
||||
CopyToInitializedF copy_to_initialized_;
|
||||
CopyToInitializedNF copy_to_initialized_n_;
|
||||
CopyToInitializedIndicesF copy_to_initialized_indices_;
|
||||
|
||||
CopyToUninitializedF copy_to_uninitialized_;
|
||||
CopyToUninitializedNF copy_to_uninitialized_n_;
|
||||
CopyToUninitializedIndicesF copy_to_uninitialized_indices_;
|
||||
|
||||
MoveToInitializedF move_to_initialized_;
|
||||
MoveToInitializedNF move_to_initialized_n_;
|
||||
MoveToInitializedIndicesF move_to_initialized_indices_;
|
||||
|
||||
MoveToUninitializedF move_to_uninitialized_;
|
||||
MoveToUninitializedNF move_to_uninitialized_n_;
|
||||
MoveToUninitializedIndicesF move_to_uninitialized_indices_;
|
||||
|
||||
RelocateToInitializedF relocate_to_initialized_;
|
||||
RelocateToInitializedNF relocate_to_initialized_n_;
|
||||
RelocateToInitializedIndicesF relocate_to_initialized_indices_;
|
||||
|
||||
RelocateToUninitializedF relocate_to_uninitialized_;
|
||||
RelocateToUninitializedNF relocate_to_uninitialized_n_;
|
||||
RelocateToUninitializedIndicesF relocate_to_uninitialized_indices_;
|
||||
|
||||
FillInitializedF fill_initialized_;
|
||||
FillInitializedIndicesF fill_initialized_indices_;
|
||||
|
||||
FillUninitializedF fill_uninitialized_;
|
||||
FillUninitializedIndicesF fill_uninitialized_indices_;
|
||||
|
||||
DebugPrintF debug_print_;
|
||||
IsEqualF is_equal_;
|
||||
HashF hash_;
|
||||
|
||||
const void *default_value_;
|
||||
std::string name_;
|
||||
CPPTypeMembers m_;
|
||||
|
||||
public:
|
||||
CPPType(std::string name,
|
||||
int64_t size,
|
||||
int64_t alignment,
|
||||
bool is_trivially_destructible,
|
||||
ConstructDefaultF construct_default,
|
||||
ConstructDefaultNF construct_default_n,
|
||||
ConstructDefaultIndicesF construct_default_indices,
|
||||
DestructF destruct,
|
||||
DestructNF destruct_n,
|
||||
DestructIndicesF destruct_indices,
|
||||
CopyToInitializedF copy_to_initialized,
|
||||
CopyToInitializedNF copy_to_initialized_n,
|
||||
CopyToInitializedIndicesF copy_to_initialized_indices,
|
||||
CopyToUninitializedF copy_to_uninitialized,
|
||||
CopyToUninitializedNF copy_to_uninitialized_n,
|
||||
CopyToUninitializedIndicesF copy_to_uninitialized_indices,
|
||||
MoveToInitializedF move_to_initialized,
|
||||
MoveToInitializedNF move_to_initialized_n,
|
||||
MoveToInitializedIndicesF move_to_initialized_indices,
|
||||
MoveToUninitializedF move_to_uninitialized,
|
||||
MoveToUninitializedNF move_to_uninitialized_n,
|
||||
MoveToUninitializedIndicesF move_to_uninitialized_indices,
|
||||
RelocateToInitializedF relocate_to_initialized,
|
||||
RelocateToInitializedNF relocate_to_initialized_n,
|
||||
RelocateToInitializedIndicesF relocate_to_initialized_indices,
|
||||
RelocateToUninitializedF relocate_to_uninitialized,
|
||||
RelocateToUninitializedNF relocate_to_uninitialized_n,
|
||||
RelocateToUninitializedIndicesF relocate_to_uninitialized_indices,
|
||||
FillInitializedF fill_initialized,
|
||||
FillInitializedIndicesF fill_initialized_indices,
|
||||
FillUninitializedF fill_uninitialized,
|
||||
FillUninitializedIndicesF fill_uninitialized_indices,
|
||||
DebugPrintF debug_print,
|
||||
IsEqualF is_equal,
|
||||
HashF hash,
|
||||
const void *default_value)
|
||||
: size_(size),
|
||||
alignment_(alignment),
|
||||
is_trivially_destructible_(is_trivially_destructible),
|
||||
construct_default_(construct_default),
|
||||
construct_default_n_(construct_default_n),
|
||||
construct_default_indices_(construct_default_indices),
|
||||
destruct_(destruct),
|
||||
destruct_n_(destruct_n),
|
||||
destruct_indices_(destruct_indices),
|
||||
copy_to_initialized_(copy_to_initialized),
|
||||
copy_to_initialized_n_(copy_to_initialized_n),
|
||||
copy_to_initialized_indices_(copy_to_initialized_indices),
|
||||
copy_to_uninitialized_(copy_to_uninitialized),
|
||||
copy_to_uninitialized_n_(copy_to_uninitialized_n),
|
||||
copy_to_uninitialized_indices_(copy_to_uninitialized_indices),
|
||||
move_to_initialized_(move_to_initialized),
|
||||
move_to_initialized_n_(move_to_initialized_n),
|
||||
move_to_initialized_indices_(move_to_initialized_indices),
|
||||
move_to_uninitialized_(move_to_uninitialized),
|
||||
move_to_uninitialized_n_(move_to_uninitialized_n),
|
||||
move_to_uninitialized_indices_(move_to_uninitialized_indices),
|
||||
relocate_to_initialized_(relocate_to_initialized),
|
||||
relocate_to_initialized_n_(relocate_to_initialized_n),
|
||||
relocate_to_initialized_indices_(relocate_to_initialized_indices),
|
||||
relocate_to_uninitialized_(relocate_to_uninitialized),
|
||||
relocate_to_uninitialized_n_(relocate_to_uninitialized_n),
|
||||
relocate_to_uninitialized_indices_(relocate_to_uninitialized_indices),
|
||||
fill_initialized_(fill_initialized),
|
||||
fill_initialized_indices_(fill_initialized_indices),
|
||||
fill_uninitialized_(fill_uninitialized),
|
||||
fill_uninitialized_indices_(fill_uninitialized_indices),
|
||||
debug_print_(debug_print),
|
||||
is_equal_(is_equal),
|
||||
hash_(hash),
|
||||
default_value_(default_value),
|
||||
name_(name)
|
||||
CPPType(CPPTypeMembers members) : m_(std::move(members))
|
||||
{
|
||||
BLI_assert(is_power_of_2_i(alignment_));
|
||||
alignment_mask_ = (uintptr_t)alignment_ - (uintptr_t)1;
|
||||
BLI_assert(is_power_of_2_i(m_.alignment));
|
||||
m_.alignment_mask = (uintptr_t)members.alignment - (uintptr_t)1;
|
||||
m_.has_special_member_functions = (m_.default_construct && m_.copy_construct &&
|
||||
m_.copy_assign && m_.move_construct && m_.move_assign &&
|
||||
m_.destruct);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,7 +156,7 @@ class CPPType : NonCopyable, NonMovable {
|
||||
*/
|
||||
StringRefNull name() const
|
||||
{
|
||||
return name_;
|
||||
return m_.name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,7 +167,7 @@ class CPPType : NonCopyable, NonMovable {
|
||||
*/
|
||||
int64_t size() const
|
||||
{
|
||||
return size_;
|
||||
return m_.size;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,7 +178,7 @@ class CPPType : NonCopyable, NonMovable {
|
||||
*/
|
||||
int64_t alignment() const
|
||||
{
|
||||
return alignment_;
|
||||
return m_.alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,7 +190,66 @@ class CPPType : NonCopyable, NonMovable {
|
||||
*/
|
||||
bool is_trivially_destructible() const
|
||||
{
|
||||
return is_trivially_destructible_;
|
||||
return m_.is_trivially_destructible;
|
||||
}
|
||||
|
||||
bool is_default_constructible() const
|
||||
{
|
||||
return m_.default_construct != nullptr;
|
||||
}
|
||||
|
||||
bool is_copy_constructible() const
|
||||
{
|
||||
return m_.copy_assign != nullptr;
|
||||
}
|
||||
|
||||
bool is_move_constructible() const
|
||||
{
|
||||
return m_.move_assign != nullptr;
|
||||
}
|
||||
|
||||
bool is_destructible() const
|
||||
{
|
||||
return m_.destruct != nullptr;
|
||||
}
|
||||
|
||||
bool is_copy_assignable() const
|
||||
{
|
||||
return m_.copy_assign != nullptr;
|
||||
}
|
||||
|
||||
bool is_move_assignable() const
|
||||
{
|
||||
return m_.copy_construct != nullptr;
|
||||
}
|
||||
|
||||
bool is_printable() const
|
||||
{
|
||||
return m_.print != nullptr;
|
||||
}
|
||||
|
||||
bool is_equality_comparable() const
|
||||
{
|
||||
return m_.is_equal != nullptr;
|
||||
}
|
||||
|
||||
bool is_hashable() const
|
||||
{
|
||||
return m_.hash != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, when the type has the following functions:
|
||||
* - Default constructor.
|
||||
* - Copy constructor.
|
||||
* - Move constructor.
|
||||
* - Copy assignment operator.
|
||||
* - Move assignment operator.
|
||||
* - Destructor.
|
||||
*/
|
||||
bool has_special_member_functions() const
|
||||
{
|
||||
return m_.has_special_member_functions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,7 +257,7 @@ class CPPType : NonCopyable, NonMovable {
|
||||
*/
|
||||
bool pointer_has_valid_alignment(const void *ptr) const
|
||||
{
|
||||
return ((uintptr_t)ptr & alignment_mask_) == 0;
|
||||
return ((uintptr_t)ptr & m_.alignment_mask) == 0;
|
||||
}
|
||||
|
||||
bool pointer_can_point_to_instance(const void *ptr) const
|
||||
@@ -331,25 +273,23 @@ class CPPType : NonCopyable, NonMovable {
|
||||
* C++ equivalent:
|
||||
* new (ptr) T;
|
||||
*/
|
||||
void construct_default(void *ptr) const
|
||||
void default_construct(void *ptr) const
|
||||
{
|
||||
BLI_assert(this->pointer_can_point_to_instance(ptr));
|
||||
|
||||
construct_default_(ptr);
|
||||
m_.default_construct(ptr);
|
||||
}
|
||||
|
||||
void construct_default_n(void *ptr, int64_t n) const
|
||||
void default_construct_n(void *ptr, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(ptr));
|
||||
|
||||
construct_default_n_(ptr, n);
|
||||
this->default_construct_indices(ptr, IndexMask(n));
|
||||
}
|
||||
|
||||
void construct_default_indices(void *ptr, IndexMask mask) const
|
||||
void default_construct_indices(void *ptr, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(ptr));
|
||||
|
||||
construct_default_indices_(ptr, mask);
|
||||
m_.default_construct_indices(ptr, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,26 +304,19 @@ class CPPType : NonCopyable, NonMovable {
|
||||
{
|
||||
BLI_assert(this->pointer_can_point_to_instance(ptr));
|
||||
|
||||
destruct_(ptr);
|
||||
m_.destruct(ptr);
|
||||
}
|
||||
|
||||
void destruct_n(void *ptr, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(ptr));
|
||||
|
||||
destruct_n_(ptr, n);
|
||||
this->destruct_indices(ptr, IndexMask(n));
|
||||
}
|
||||
|
||||
void destruct_indices(void *ptr, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(ptr));
|
||||
|
||||
destruct_indices_(ptr, mask);
|
||||
}
|
||||
|
||||
DestructF destruct_cb() const
|
||||
{
|
||||
return destruct_;
|
||||
m_.destruct_indices(ptr, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,31 +325,27 @@ class CPPType : NonCopyable, NonMovable {
|
||||
* C++ equivalent:
|
||||
* dst = src;
|
||||
*/
|
||||
void copy_to_initialized(const void *src, void *dst) const
|
||||
void copy_assign(const void *src, void *dst) const
|
||||
{
|
||||
BLI_assert(src != dst);
|
||||
BLI_assert(this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(this->pointer_can_point_to_instance(dst));
|
||||
|
||||
copy_to_initialized_(src, dst);
|
||||
m_.copy_assign(src, dst);
|
||||
}
|
||||
|
||||
void copy_to_initialized_n(const void *src, void *dst, int64_t n) const
|
||||
void copy_assign_n(const void *src, void *dst, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || src != dst);
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
copy_to_initialized_n_(src, dst, n);
|
||||
this->copy_assign_indices(src, dst, IndexMask(n));
|
||||
}
|
||||
|
||||
void copy_to_initialized_indices(const void *src, void *dst, IndexMask mask) const
|
||||
void copy_assign_indices(const void *src, void *dst, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || src != dst);
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
copy_to_initialized_indices_(src, dst, mask);
|
||||
m_.copy_assign_indices(src, dst, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,31 +356,27 @@ class CPPType : NonCopyable, NonMovable {
|
||||
* C++ equivalent:
|
||||
* new (dst) T(src);
|
||||
*/
|
||||
void copy_to_uninitialized(const void *src, void *dst) const
|
||||
void copy_construct(const void *src, void *dst) const
|
||||
{
|
||||
BLI_assert(src != dst);
|
||||
BLI_assert(this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(this->pointer_can_point_to_instance(dst));
|
||||
|
||||
copy_to_uninitialized_(src, dst);
|
||||
m_.copy_construct(src, dst);
|
||||
}
|
||||
|
||||
void copy_to_uninitialized_n(const void *src, void *dst, int64_t n) const
|
||||
void copy_construct_n(const void *src, void *dst, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || src != dst);
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
copy_to_uninitialized_n_(src, dst, n);
|
||||
this->copy_construct_indices(src, dst, IndexMask(n));
|
||||
}
|
||||
|
||||
void copy_to_uninitialized_indices(const void *src, void *dst, IndexMask mask) const
|
||||
void copy_construct_indices(const void *src, void *dst, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || src != dst);
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
copy_to_uninitialized_indices_(src, dst, mask);
|
||||
m_.copy_construct_indices(src, dst, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,31 +387,27 @@ class CPPType : NonCopyable, NonMovable {
|
||||
* C++ equivalent:
|
||||
* dst = std::move(src);
|
||||
*/
|
||||
void move_to_initialized(void *src, void *dst) const
|
||||
void move_assign(void *src, void *dst) const
|
||||
{
|
||||
BLI_assert(src != dst);
|
||||
BLI_assert(this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(this->pointer_can_point_to_instance(dst));
|
||||
|
||||
move_to_initialized_(src, dst);
|
||||
m_.move_assign(src, dst);
|
||||
}
|
||||
|
||||
void move_to_initialized_n(void *src, void *dst, int64_t n) const
|
||||
void move_assign_n(void *src, void *dst, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || src != dst);
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
move_to_initialized_n_(src, dst, n);
|
||||
this->move_assign_indices(src, dst, IndexMask(n));
|
||||
}
|
||||
|
||||
void move_to_initialized_indices(void *src, void *dst, IndexMask mask) const
|
||||
void move_assign_indices(void *src, void *dst, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || src != dst);
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
move_to_initialized_indices_(src, dst, mask);
|
||||
m_.move_assign_indices(src, dst, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -497,31 +418,27 @@ class CPPType : NonCopyable, NonMovable {
|
||||
* C++ equivalent:
|
||||
* new (dst) T(std::move(src));
|
||||
*/
|
||||
void move_to_uninitialized(void *src, void *dst) const
|
||||
void move_construct(void *src, void *dst) const
|
||||
{
|
||||
BLI_assert(src != dst);
|
||||
BLI_assert(this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(this->pointer_can_point_to_instance(dst));
|
||||
|
||||
move_to_uninitialized_(src, dst);
|
||||
m_.move_construct(src, dst);
|
||||
}
|
||||
|
||||
void move_to_uninitialized_n(void *src, void *dst, int64_t n) const
|
||||
void move_construct_n(void *src, void *dst, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || src != dst);
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
move_to_uninitialized_n_(src, dst, n);
|
||||
this->move_construct_indices(src, dst, IndexMask(n));
|
||||
}
|
||||
|
||||
void move_to_uninitialized_indices(void *src, void *dst, IndexMask mask) const
|
||||
void move_construct_indices(void *src, void *dst, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || src != dst);
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
move_to_uninitialized_indices_(src, dst, mask);
|
||||
m_.move_construct_indices(src, dst, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -532,31 +449,27 @@ class CPPType : NonCopyable, NonMovable {
|
||||
* dst = std::move(src);
|
||||
* src->~T();
|
||||
*/
|
||||
void relocate_to_initialized(void *src, void *dst) const
|
||||
void relocate_assign(void *src, void *dst) const
|
||||
{
|
||||
BLI_assert(src != dst);
|
||||
BLI_assert(this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(this->pointer_can_point_to_instance(dst));
|
||||
|
||||
relocate_to_initialized_(src, dst);
|
||||
m_.relocate_assign(src, dst);
|
||||
}
|
||||
|
||||
void relocate_to_initialized_n(void *src, void *dst, int64_t n) const
|
||||
void relocate_assign_n(void *src, void *dst, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || src != dst);
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
relocate_to_initialized_n_(src, dst, n);
|
||||
this->relocate_assign_indices(src, dst, IndexMask(n));
|
||||
}
|
||||
|
||||
void relocate_to_initialized_indices(void *src, void *dst, IndexMask mask) const
|
||||
void relocate_assign_indices(void *src, void *dst, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || src != dst);
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
relocate_to_initialized_indices_(src, dst, mask);
|
||||
m_.relocate_assign_indices(src, dst, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -567,31 +480,27 @@ class CPPType : NonCopyable, NonMovable {
|
||||
* new (dst) T(std::move(src))
|
||||
* src->~T();
|
||||
*/
|
||||
void relocate_to_uninitialized(void *src, void *dst) const
|
||||
void relocate_construct(void *src, void *dst) const
|
||||
{
|
||||
BLI_assert(src != dst);
|
||||
BLI_assert(this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(this->pointer_can_point_to_instance(dst));
|
||||
|
||||
relocate_to_uninitialized_(src, dst);
|
||||
m_.relocate_construct(src, dst);
|
||||
}
|
||||
|
||||
void relocate_to_uninitialized_n(void *src, void *dst, int64_t n) const
|
||||
void relocate_construct_n(void *src, void *dst, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || src != dst);
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
relocate_to_uninitialized_n_(src, dst, n);
|
||||
this->relocate_construct_indices(src, dst, IndexMask(n));
|
||||
}
|
||||
|
||||
void relocate_to_uninitialized_indices(void *src, void *dst, IndexMask mask) const
|
||||
void relocate_construct_indices(void *src, void *dst, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || src != dst);
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
relocate_to_uninitialized_indices_(src, dst, mask);
|
||||
m_.relocate_construct_indices(src, dst, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -599,20 +508,17 @@ class CPPType : NonCopyable, NonMovable {
|
||||
*
|
||||
* Other instances of the same type should live in the array before this method is called.
|
||||
*/
|
||||
void fill_initialized(const void *value, void *dst, int64_t n) const
|
||||
void fill_assign_n(const void *value, void *dst, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(value));
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
fill_initialized_(value, dst, n);
|
||||
this->fill_assign_indices(value, dst, IndexMask(n));
|
||||
}
|
||||
|
||||
void fill_initialized_indices(const void *value, void *dst, IndexMask mask) const
|
||||
void fill_assign_indices(const void *value, void *dst, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(value));
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
fill_initialized_indices_(value, dst, mask);
|
||||
m_.fill_assign_indices(value, dst, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -620,39 +526,62 @@ class CPPType : NonCopyable, NonMovable {
|
||||
*
|
||||
* The array should be uninitialized before this method is called.
|
||||
*/
|
||||
void fill_uninitialized(const void *value, void *dst, int64_t n) const
|
||||
void fill_construct_n(const void *value, void *dst, int64_t n) const
|
||||
{
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(value));
|
||||
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
fill_uninitialized_(value, dst, n);
|
||||
this->fill_construct_indices(value, dst, IndexMask(n));
|
||||
}
|
||||
|
||||
void fill_uninitialized_indices(const void *value, void *dst, IndexMask mask) const
|
||||
void fill_construct_indices(const void *value, void *dst, IndexMask mask) const
|
||||
{
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(value));
|
||||
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
|
||||
|
||||
fill_uninitialized_indices_(value, dst, mask);
|
||||
m_.fill_construct_indices(value, dst, mask);
|
||||
}
|
||||
|
||||
void debug_print(const void *value, std::stringstream &ss) const
|
||||
void print(const void *value, std::stringstream &ss) const
|
||||
{
|
||||
BLI_assert(this->pointer_can_point_to_instance(value));
|
||||
debug_print_(value, ss);
|
||||
m_.print(value, ss);
|
||||
}
|
||||
|
||||
void print_or_default(const void *value, std::stringstream &ss, StringRef default_value) const
|
||||
{
|
||||
if (this->is_printable()) {
|
||||
this->print(value, ss);
|
||||
}
|
||||
else {
|
||||
ss << default_value;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_equal(const void *a, const void *b) const
|
||||
{
|
||||
BLI_assert(this->pointer_can_point_to_instance(a));
|
||||
BLI_assert(this->pointer_can_point_to_instance(b));
|
||||
return is_equal_(a, b);
|
||||
return m_.is_equal(a, b);
|
||||
}
|
||||
|
||||
bool is_equal_or_false(const void *a, const void *b) const
|
||||
{
|
||||
if (this->is_equality_comparable()) {
|
||||
return this->is_equal(a, b);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t hash(const void *value) const
|
||||
{
|
||||
BLI_assert(this->pointer_can_point_to_instance(value));
|
||||
return hash_(value);
|
||||
return m_.hash(value);
|
||||
}
|
||||
|
||||
uint64_t hash_or_fallback(const void *value, uint64_t fallback_hash) const
|
||||
{
|
||||
if (this->is_hashable()) {
|
||||
return this->hash(value);
|
||||
}
|
||||
return fallback_hash;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,7 +590,7 @@ class CPPType : NonCopyable, NonMovable {
|
||||
*/
|
||||
const void *default_value() const
|
||||
{
|
||||
return default_value_;
|
||||
return m_.default_value;
|
||||
}
|
||||
|
||||
uint64_t hash() const
|
||||
@@ -669,6 +598,14 @@ class CPPType : NonCopyable, NonMovable {
|
||||
return get_default_hash(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Low level access to the callbacks for this CPPType.
|
||||
*/
|
||||
const CPPTypeMembers &members() const
|
||||
{
|
||||
return m_;
|
||||
}
|
||||
|
||||
template<typename T> bool is() const
|
||||
{
|
||||
return this == &CPPType::get<std::decay_t<T>>();
|
||||
|
@@ -20,19 +20,16 @@
|
||||
* \ingroup fn
|
||||
*/
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "FN_cpp_type.hh"
|
||||
|
||||
namespace blender::fn::cpp_type_util {
|
||||
|
||||
template<typename T> void construct_default_cb(void *ptr)
|
||||
template<typename T> void default_construct_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)
|
||||
template<typename T> void default_construct_indices_cb(void *ptr, IndexMask mask)
|
||||
{
|
||||
mask.foreach_index([&](int64_t i) { new (static_cast<T *>(ptr) + i) T; });
|
||||
}
|
||||
@@ -41,31 +38,17 @@ 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)
|
||||
template<typename T> void copy_assign_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)
|
||||
template<typename T> void copy_assign_indices_cb(const void *src, void *dst, IndexMask mask)
|
||||
{
|
||||
const T *src_ = static_cast<const T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -73,16 +56,11 @@ void copy_to_initialized_indices_cb(const void *src, void *dst, IndexMask mask)
|
||||
mask.foreach_index([&](int64_t i) { dst_[i] = src_[i]; });
|
||||
}
|
||||
|
||||
template<typename T> void copy_to_uninitialized_cb(const void *src, void *dst)
|
||||
template<typename T> void copy_construct_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)
|
||||
template<typename T> void copy_construct_indices_cb(const void *src, void *dst, IndexMask mask)
|
||||
{
|
||||
const T *src_ = static_cast<const T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -90,15 +68,11 @@ void copy_to_uninitialized_indices_cb(const void *src, void *dst, IndexMask mask
|
||||
mask.foreach_index([&](int64_t i) { new (dst_ + i) T(src_[i]); });
|
||||
}
|
||||
|
||||
template<typename T> void move_to_initialized_cb(void *src, void *dst)
|
||||
template<typename T> void move_assign_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)
|
||||
template<typename T> void move_assign_indices_cb(void *src, void *dst, IndexMask mask)
|
||||
{
|
||||
T *src_ = static_cast<T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -106,15 +80,11 @@ template<typename T> void move_to_initialized_indices_cb(void *src, void *dst, I
|
||||
mask.foreach_index([&](int64_t i) { dst_[i] = std::move(src_[i]); });
|
||||
}
|
||||
|
||||
template<typename T> void move_to_uninitialized_cb(void *src, void *dst)
|
||||
template<typename T> void move_construct_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)
|
||||
template<typename T> void move_construct_indices_cb(void *src, void *dst, IndexMask mask)
|
||||
{
|
||||
T *src_ = static_cast<T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -122,7 +92,7 @@ template<typename T> void move_to_uninitialized_indices_cb(void *src, void *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)
|
||||
template<typename T> void relocate_assign_cb(void *src, void *dst)
|
||||
{
|
||||
T *src_ = static_cast<T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -130,11 +100,7 @@ template<typename T> void relocate_to_initialized_cb(void *src, void *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)
|
||||
template<typename T> void relocate_assign_indices_cb(void *src, void *dst, IndexMask mask)
|
||||
{
|
||||
T *src_ = static_cast<T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -145,7 +111,7 @@ template<typename T> void relocate_to_initialized_indices_cb(void *src, void *ds
|
||||
});
|
||||
}
|
||||
|
||||
template<typename T> void relocate_to_uninitialized_cb(void *src, void *dst)
|
||||
template<typename T> void relocate_construct_cb(void *src, void *dst)
|
||||
{
|
||||
T *src_ = static_cast<T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -153,12 +119,7 @@ template<typename T> void relocate_to_uninitialized_cb(void *src, void *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)
|
||||
template<typename T> void relocate_construct_indices_cb(void *src, void *dst, IndexMask mask)
|
||||
{
|
||||
T *src_ = static_cast<T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -169,7 +130,7 @@ void relocate_to_uninitialized_indices_cb(void *src, void *dst, IndexMask mask)
|
||||
});
|
||||
}
|
||||
|
||||
template<typename T> void fill_initialized_cb(const void *value, void *dst, int64_t n)
|
||||
template<typename T> void fill_assign_cb(const void *value, void *dst, int64_t n)
|
||||
{
|
||||
const T &value_ = *static_cast<const T *>(value);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -178,7 +139,7 @@ template<typename T> void fill_initialized_cb(const void *value, void *dst, int6
|
||||
dst_[i] = value_;
|
||||
}
|
||||
}
|
||||
template<typename T> void fill_initialized_indices_cb(const void *value, void *dst, IndexMask mask)
|
||||
template<typename T> void fill_assign_indices_cb(const void *value, void *dst, IndexMask mask)
|
||||
{
|
||||
const T &value_ = *static_cast<const T *>(value);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -186,7 +147,7 @@ template<typename T> void fill_initialized_indices_cb(const void *value, void *d
|
||||
mask.foreach_index([&](int64_t i) { dst_[i] = value_; });
|
||||
}
|
||||
|
||||
template<typename T> void fill_uninitialized_cb(const void *value, void *dst, int64_t n)
|
||||
template<typename T> void fill_construct_cb(const void *value, void *dst, int64_t n)
|
||||
{
|
||||
const T &value_ = *static_cast<const T *>(value);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -195,8 +156,7 @@ template<typename T> void fill_uninitialized_cb(const void *value, void *dst, in
|
||||
new (dst_ + i) T(value_);
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
void fill_uninitialized_indices_cb(const void *value, void *dst, IndexMask mask)
|
||||
template<typename T> void fill_construct_indices_cb(const void *value, void *dst, IndexMask mask)
|
||||
{
|
||||
const T &value_ = *static_cast<const T *>(value);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
@@ -204,7 +164,7 @@ void fill_uninitialized_indices_cb(const void *value, void *dst, IndexMask mask)
|
||||
mask.foreach_index([&](int64_t i) { new (dst_ + i) T(value_); });
|
||||
}
|
||||
|
||||
template<typename T> void debug_print_cb(const void *value, std::stringstream &ss)
|
||||
template<typename T> void print_cb(const void *value, std::stringstream &ss)
|
||||
{
|
||||
const T &value_ = *static_cast<const T *>(value);
|
||||
ss << value_;
|
||||
@@ -225,59 +185,96 @@ template<typename T> uint64_t hash_cb(const void *value)
|
||||
|
||||
} // namespace blender::fn::cpp_type_util
|
||||
|
||||
/**
|
||||
* Different types support different features. Features like copy constructibility can be detected
|
||||
* automatically easily. For some features this is harder as of C++17. Those have flags in this
|
||||
* enum and need to be determined by the programmer.
|
||||
*/
|
||||
enum class CPPTypeFlags {
|
||||
None = 0,
|
||||
Hashable = 1 << 0,
|
||||
Printable = 1 << 1,
|
||||
EqualityComparable = 1 << 2,
|
||||
|
||||
BasicType = Hashable | Printable | EqualityComparable,
|
||||
};
|
||||
ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable)
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
template<typename T>
|
||||
inline std::unique_ptr<const CPPType> create_cpp_type(StringRef name, const T &default_value)
|
||||
template<typename T, CPPTypeFlags flags>
|
||||
inline std::unique_ptr<const CPPType> create_cpp_type(StringRef name)
|
||||
{
|
||||
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));
|
||||
|
||||
CPPTypeMembers m;
|
||||
m.name = name;
|
||||
m.size = (int64_t)sizeof(T);
|
||||
m.alignment = (int64_t)alignof(T);
|
||||
m.is_trivially_destructible = std::is_trivially_destructible_v<T>;
|
||||
if constexpr (std::is_default_constructible_v<T>) {
|
||||
m.default_construct = default_construct_cb<T>;
|
||||
m.default_construct_indices = default_construct_indices_cb<T>;
|
||||
static T default_value;
|
||||
m.default_value = (void *)&default_value;
|
||||
}
|
||||
if constexpr (std::is_destructible_v<T>) {
|
||||
m.destruct = destruct_cb<T>;
|
||||
m.destruct_indices = destruct_indices_cb<T>;
|
||||
}
|
||||
if constexpr (std::is_copy_assignable_v<T>) {
|
||||
m.copy_assign = copy_assign_cb<T>;
|
||||
m.copy_assign_indices = copy_assign_indices_cb<T>;
|
||||
}
|
||||
if constexpr (std::is_copy_constructible_v<T>) {
|
||||
m.copy_construct = copy_construct_cb<T>;
|
||||
m.copy_construct_indices = copy_construct_indices_cb<T>;
|
||||
}
|
||||
if constexpr (std::is_move_assignable_v<T>) {
|
||||
m.move_assign = move_assign_cb<T>;
|
||||
m.move_assign_indices = move_assign_indices_cb<T>;
|
||||
}
|
||||
if constexpr (std::is_move_constructible_v<T>) {
|
||||
m.move_construct = move_construct_cb<T>;
|
||||
m.move_construct_indices = move_construct_indices_cb<T>;
|
||||
}
|
||||
if constexpr (std::is_destructible_v<T>) {
|
||||
if constexpr (std::is_move_assignable_v<T>) {
|
||||
m.relocate_assign = relocate_assign_cb<T>;
|
||||
m.relocate_assign_indices = relocate_assign_indices_cb<T>;
|
||||
}
|
||||
if constexpr (std::is_move_constructible_v<T>) {
|
||||
m.relocate_construct = relocate_construct_cb<T>;
|
||||
m.relocate_construct_indices = relocate_construct_indices_cb<T>;
|
||||
}
|
||||
}
|
||||
if constexpr (std::is_copy_assignable_v<T>) {
|
||||
m.fill_assign_indices = fill_assign_indices_cb<T>;
|
||||
}
|
||||
if constexpr (std::is_copy_constructible_v<T>) {
|
||||
m.fill_construct_indices = fill_construct_indices_cb<T>;
|
||||
}
|
||||
if constexpr ((bool)(flags & CPPTypeFlags::Hashable)) {
|
||||
m.hash = hash_cb<T>;
|
||||
}
|
||||
if constexpr ((bool)(flags & CPPTypeFlags::Printable)) {
|
||||
m.print = print_cb<T>;
|
||||
}
|
||||
if constexpr ((bool)(flags & CPPTypeFlags::EqualityComparable)) {
|
||||
m.is_equal = is_equal_cb<T>;
|
||||
}
|
||||
|
||||
const CPPType *type = new CPPType(std::move(m));
|
||||
return std::unique_ptr<const CPPType>(type);
|
||||
}
|
||||
|
||||
} // namespace blender::fn
|
||||
|
||||
#define MAKE_CPP_TYPE(IDENTIFIER, TYPE_NAME) \
|
||||
#define MAKE_CPP_TYPE(IDENTIFIER, TYPE_NAME, FLAGS) \
|
||||
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); \
|
||||
static std::unique_ptr<const CPPType> cpp_type = \
|
||||
blender::fn::create_cpp_type<TYPE_NAME, FLAGS>(STRINGIFY(IDENTIFIER)); \
|
||||
return *cpp_type; \
|
||||
} \
|
||||
/* Support using `CPPType::get<const T>()`. Otherwise the caller would have to remove const. */ \
|
||||
|
@@ -70,7 +70,7 @@ class GMutablePointer {
|
||||
{
|
||||
BLI_assert(this->is_type<T>());
|
||||
T value;
|
||||
type_->relocate_to_initialized(data_, &value);
|
||||
type_->relocate_assign(data_, &value);
|
||||
data_ = nullptr;
|
||||
type_ = nullptr;
|
||||
return value;
|
||||
|
@@ -60,7 +60,7 @@ template<typename Key> class GValueMap {
|
||||
{
|
||||
const CPPType &type = *value.type();
|
||||
void *buffer = allocator_.allocate(type.size(), type.alignment());
|
||||
type.move_to_uninitialized(value.get(), buffer);
|
||||
type.move_construct(value.get(), buffer);
|
||||
values_.add_new_as(std::forward<ForwardKey>(key), GMutablePointer{type, buffer});
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ template<typename Key> class GValueMap {
|
||||
{
|
||||
const CPPType &type = *value.type();
|
||||
void *buffer = allocator_.allocate(type.size(), type.alignment());
|
||||
type.copy_to_uninitialized(value.get(), buffer);
|
||||
type.copy_construct(value.get(), buffer);
|
||||
values_.add_new_as(std::forward<ForwardKey>(key), GMutablePointer{type, buffer});
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ template<typename Key> class GValueMap {
|
||||
const CPPType &type = *value.type();
|
||||
BLI_assert(type.is<T>());
|
||||
T return_value;
|
||||
type.relocate_to_initialized(value.get(), &return_value);
|
||||
type.relocate_assign(value.get(), &return_value);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
@@ -154,7 +154,7 @@ class GVVectorArray_For_GVectorArray : public GVVectorArray {
|
||||
const int64_t index_in_vector,
|
||||
void *r_value) const override
|
||||
{
|
||||
type_->copy_to_initialized(vector_array_[index][index_in_vector], r_value);
|
||||
type_->copy_assign(vector_array_[index][index_in_vector], r_value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -131,7 +131,7 @@ class GVArray {
|
||||
/* Same as `get_internal_single`, but `r_value` points to initialized memory. */
|
||||
void get_single_to_uninitialized(void *r_value) const
|
||||
{
|
||||
type_->construct_default(r_value);
|
||||
type_->default_construct(r_value);
|
||||
this->get_internal_single(r_value);
|
||||
}
|
||||
|
||||
|
@@ -398,7 +398,7 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
|
||||
if (other2 != nullptr) {
|
||||
const CPPType &type = CPPType::get<T>();
|
||||
if (type == other2->type_) {
|
||||
return type.is_equal(static_cast<const void *>(&value_), other2->value_);
|
||||
return type.is_equal_or_false(static_cast<const void *>(&value_), other2->value_);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@@ -23,20 +23,20 @@
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
MAKE_CPP_TYPE(bool, bool)
|
||||
MAKE_CPP_TYPE(bool, bool, CPPTypeFlags::BasicType)
|
||||
|
||||
MAKE_CPP_TYPE(float, float)
|
||||
MAKE_CPP_TYPE(float2, blender::float2)
|
||||
MAKE_CPP_TYPE(float3, blender::float3)
|
||||
MAKE_CPP_TYPE(float4x4, blender::float4x4)
|
||||
MAKE_CPP_TYPE(float, float, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(float2, blender::float2, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(float3, blender::float3, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(float4x4, blender::float4x4, CPPTypeFlags::BasicType)
|
||||
|
||||
MAKE_CPP_TYPE(int32, int32_t)
|
||||
MAKE_CPP_TYPE(uint32, uint32_t)
|
||||
MAKE_CPP_TYPE(uint8, uint8_t)
|
||||
MAKE_CPP_TYPE(int32, int32_t, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(uint32, uint32_t, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(uint8, uint8_t, CPPTypeFlags::BasicType)
|
||||
|
||||
MAKE_CPP_TYPE(ColorGeometry4f, blender::ColorGeometry4f)
|
||||
MAKE_CPP_TYPE(ColorGeometry4b, blender::ColorGeometry4b)
|
||||
MAKE_CPP_TYPE(ColorGeometry4f, blender::ColorGeometry4f, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(ColorGeometry4b, blender::ColorGeometry4b, CPPTypeFlags::BasicType)
|
||||
|
||||
MAKE_CPP_TYPE(string, std::string)
|
||||
MAKE_CPP_TYPE(string, std::string, CPPTypeFlags::BasicType)
|
||||
|
||||
} // namespace blender::fn
|
||||
|
@@ -43,7 +43,7 @@ void GVectorArray::append(const int64_t index, const void *value)
|
||||
}
|
||||
|
||||
void *dst = POINTER_OFFSET(item.start, element_size_ * item.length);
|
||||
type_.copy_to_uninitialized(value, dst);
|
||||
type_.copy_construct(value, dst);
|
||||
item.length++;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ void GVectorArray::realloc_to_at_least(Item &item, int64_t min_capacity)
|
||||
const int64_t new_capacity = std::max(min_capacity, item.length * 2);
|
||||
|
||||
void *new_buffer = allocator_.allocate(element_size_ * new_capacity, type_.alignment());
|
||||
type_.relocate_to_initialized_n(item.start, new_buffer, item.length);
|
||||
type_.relocate_assign_n(item.start, new_buffer, item.length);
|
||||
|
||||
item.start = new_buffer;
|
||||
item.capacity = new_capacity;
|
||||
|
@@ -149,7 +149,7 @@ GVArrayPtr GVArray::shallow_copy() const
|
||||
void GVMutableArray::set_by_copy_impl(const int64_t index, const void *value)
|
||||
{
|
||||
BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer);
|
||||
type_->copy_to_uninitialized(value, buffer);
|
||||
type_->copy_construct(value, buffer);
|
||||
this->set_by_move_impl(index, buffer);
|
||||
type_->destruct(buffer);
|
||||
}
|
||||
@@ -164,7 +164,7 @@ void GVMutableArray::set_all_impl(const void *src)
|
||||
{
|
||||
if (this->is_span()) {
|
||||
const GMutableSpan span = this->get_internal_span();
|
||||
type_->copy_to_initialized_n(src, span.data(), size_);
|
||||
type_->copy_assign_n(src, span.data(), size_);
|
||||
}
|
||||
else {
|
||||
for (int64_t i : IndexRange(size_)) {
|
||||
@@ -182,7 +182,7 @@ void GVMutableArray::fill(const void *value)
|
||||
{
|
||||
if (this->is_span()) {
|
||||
const GMutableSpan span = this->get_internal_span();
|
||||
type_->fill_initialized(value, span.data(), size_);
|
||||
type_->fill_assign_n(value, span.data(), size_);
|
||||
}
|
||||
else {
|
||||
for (int64_t i : IndexRange(size_)) {
|
||||
@@ -197,12 +197,12 @@ void GVMutableArray::fill(const void *value)
|
||||
|
||||
void GVArray_For_GSpan::get_impl(const int64_t index, void *r_value) const
|
||||
{
|
||||
type_->copy_to_initialized(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
||||
type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
||||
}
|
||||
|
||||
void GVArray_For_GSpan::get_to_uninitialized_impl(const int64_t index, void *r_value) const
|
||||
{
|
||||
type_->copy_to_uninitialized(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
||||
type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
||||
}
|
||||
|
||||
bool GVArray_For_GSpan::is_span_impl() const
|
||||
@@ -221,28 +221,28 @@ GSpan GVArray_For_GSpan::get_internal_span_impl() const
|
||||
|
||||
void GVMutableArray_For_GMutableSpan::get_impl(const int64_t index, void *r_value) const
|
||||
{
|
||||
type_->copy_to_initialized(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
||||
type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
||||
}
|
||||
|
||||
void GVMutableArray_For_GMutableSpan::get_to_uninitialized_impl(const int64_t index,
|
||||
void *r_value) const
|
||||
{
|
||||
type_->copy_to_uninitialized(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
||||
type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
||||
}
|
||||
|
||||
void GVMutableArray_For_GMutableSpan::set_by_copy_impl(const int64_t index, const void *value)
|
||||
{
|
||||
type_->copy_to_initialized(value, POINTER_OFFSET(data_, element_size_ * index));
|
||||
type_->copy_assign(value, POINTER_OFFSET(data_, element_size_ * index));
|
||||
}
|
||||
|
||||
void GVMutableArray_For_GMutableSpan::set_by_move_impl(const int64_t index, void *value)
|
||||
{
|
||||
type_->move_to_initialized(value, POINTER_OFFSET(data_, element_size_ * index));
|
||||
type_->move_construct(value, POINTER_OFFSET(data_, element_size_ * index));
|
||||
}
|
||||
|
||||
void GVMutableArray_For_GMutableSpan::set_by_relocate_impl(const int64_t index, void *value)
|
||||
{
|
||||
type_->relocate_to_initialized(value, POINTER_OFFSET(data_, element_size_ * index));
|
||||
type_->relocate_assign(value, POINTER_OFFSET(data_, element_size_ * index));
|
||||
}
|
||||
|
||||
bool GVMutableArray_For_GMutableSpan::is_span_impl() const
|
||||
@@ -261,13 +261,13 @@ GSpan GVMutableArray_For_GMutableSpan::get_internal_span_impl() const
|
||||
|
||||
void GVArray_For_SingleValueRef::get_impl(const int64_t UNUSED(index), void *r_value) const
|
||||
{
|
||||
type_->copy_to_initialized(value_, r_value);
|
||||
type_->copy_assign(value_, r_value);
|
||||
}
|
||||
|
||||
void GVArray_For_SingleValueRef::get_to_uninitialized_impl(const int64_t UNUSED(index),
|
||||
void *r_value) const
|
||||
{
|
||||
type_->copy_to_uninitialized(value_, r_value);
|
||||
type_->copy_construct(value_, r_value);
|
||||
}
|
||||
|
||||
bool GVArray_For_SingleValueRef::is_span_impl() const
|
||||
@@ -287,7 +287,7 @@ bool GVArray_For_SingleValueRef::is_single_impl() const
|
||||
|
||||
void GVArray_For_SingleValueRef::get_internal_single_impl(void *r_value) const
|
||||
{
|
||||
type_->copy_to_initialized(value_, r_value);
|
||||
type_->copy_assign(value_, r_value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
@@ -300,7 +300,7 @@ GVArray_For_SingleValue::GVArray_For_SingleValue(const CPPType &type,
|
||||
: GVArray_For_SingleValueRef(type, size)
|
||||
{
|
||||
value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__);
|
||||
type.copy_to_uninitialized(value, (void *)value_);
|
||||
type.copy_construct(value, (void *)value_);
|
||||
}
|
||||
|
||||
GVArray_For_SingleValue::~GVArray_For_SingleValue()
|
||||
@@ -351,7 +351,7 @@ GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray &varray, const bool co
|
||||
varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_);
|
||||
}
|
||||
else {
|
||||
type_->construct_default_n(owned_data_, size_);
|
||||
type_->default_construct_n(owned_data_, size_);
|
||||
}
|
||||
data_ = owned_data_;
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@ void GVArray_For_GVVectorArrayIndex::get_impl(const int64_t index_in_vector, voi
|
||||
void GVArray_For_GVVectorArrayIndex::get_to_uninitialized_impl(const int64_t index_in_vector,
|
||||
void *r_value) const
|
||||
{
|
||||
type_->construct_default(r_value);
|
||||
type_->default_construct(r_value);
|
||||
vector_array_.get_vector_element(index_, index_in_vector, r_value);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ void GVVectorArray_For_SingleGSpan::get_vector_element_impl(const int64_t UNUSED
|
||||
const int64_t index_in_vector,
|
||||
void *r_value) const
|
||||
{
|
||||
type_->copy_to_initialized(span_[index_in_vector], r_value);
|
||||
type_->copy_assign(span_[index_in_vector], r_value);
|
||||
}
|
||||
|
||||
bool GVVectorArray_For_SingleGSpan::is_single_vector_impl() const
|
||||
|
@@ -25,7 +25,7 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, const vo
|
||||
{
|
||||
MFSignatureBuilder signature{"Constant " + type.name()};
|
||||
std::stringstream ss;
|
||||
type.debug_print(value, ss);
|
||||
type.print_or_default(value, ss, type.name());
|
||||
signature.single_output(ss.str(), type);
|
||||
signature_ = signature.build();
|
||||
this->set_signature(&signature_);
|
||||
@@ -36,12 +36,12 @@ void CustomMF_GenericConstant::call(IndexMask mask,
|
||||
MFContext UNUSED(context)) const
|
||||
{
|
||||
GMutableSpan output = params.uninitialized_single_output(0);
|
||||
type_.fill_uninitialized_indices(value_, output.data(), mask);
|
||||
type_.fill_construct_indices(value_, output.data(), mask);
|
||||
}
|
||||
|
||||
uint64_t CustomMF_GenericConstant::hash() const
|
||||
{
|
||||
return type_.hash(value_);
|
||||
return type_.hash_or_fallback(value_, (uintptr_t)this);
|
||||
}
|
||||
|
||||
bool CustomMF_GenericConstant::equals(const MultiFunction &other) const
|
||||
@@ -58,11 +58,12 @@ bool CustomMF_GenericConstant::equals(const MultiFunction &other) const
|
||||
|
||||
static std::string gspan_to_string(GSpan array)
|
||||
{
|
||||
const CPPType &type = array.type();
|
||||
std::stringstream ss;
|
||||
ss << "[";
|
||||
const int64_t max_amount = 5;
|
||||
for (int64_t i : IndexRange(std::min(max_amount, array.size()))) {
|
||||
array.type().debug_print(array[i], ss);
|
||||
type.print_or_default(array[i], ss, type.name());
|
||||
ss << ", ";
|
||||
}
|
||||
if (max_amount < array.size()) {
|
||||
@@ -117,7 +118,7 @@ void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNU
|
||||
if (param_type.data_type().is_single()) {
|
||||
GMutableSpan span = params.uninitialized_single_output(param_index);
|
||||
const CPPType &type = span.type();
|
||||
type.fill_uninitialized_indices(type.default_value(), span.data(), mask);
|
||||
type.fill_construct_indices(type.default_value(), span.data(), mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -263,7 +263,7 @@ static Array<MFOutputSocket *> add_constant_folded_sockets(const MultiFunction &
|
||||
const CPPType &cpp_type = data_type.single_type();
|
||||
GMutableSpan array = params.computed_array(param_index);
|
||||
void *buffer = array.data();
|
||||
scope.add(buffer, array.type().destruct_cb(), AT);
|
||||
scope.add(buffer, array.type().members().destruct, AT);
|
||||
|
||||
constant_fn = &scope.construct<CustomMF_GenericConstant>(AT, cpp_type, buffer);
|
||||
break;
|
||||
|
@@ -76,7 +76,7 @@ struct TestType {
|
||||
|
||||
} // namespace blender::fn::tests
|
||||
|
||||
MAKE_CPP_TYPE(TestType, blender::fn::tests::TestType)
|
||||
MAKE_CPP_TYPE(TestType, blender::fn::tests::TestType, CPPTypeFlags::BasicType)
|
||||
|
||||
namespace blender::fn::tests {
|
||||
|
||||
@@ -101,15 +101,15 @@ TEST(cpp_type, Is)
|
||||
TEST(cpp_type, DefaultConstruction)
|
||||
{
|
||||
int buffer[10] = {0};
|
||||
CPPType_TestType.construct_default((void *)buffer);
|
||||
CPPType_TestType.default_construct((void *)buffer);
|
||||
EXPECT_EQ(buffer[0], default_constructed_value);
|
||||
EXPECT_EQ(buffer[1], 0);
|
||||
CPPType_TestType.construct_default_n((void *)buffer, 3);
|
||||
CPPType_TestType.default_construct_n((void *)buffer, 3);
|
||||
EXPECT_EQ(buffer[0], default_constructed_value);
|
||||
EXPECT_EQ(buffer[1], default_constructed_value);
|
||||
EXPECT_EQ(buffer[2], default_constructed_value);
|
||||
EXPECT_EQ(buffer[3], 0);
|
||||
CPPType_TestType.construct_default_indices((void *)buffer, {2, 5, 7});
|
||||
CPPType_TestType.default_construct_indices((void *)buffer, {2, 5, 7});
|
||||
EXPECT_EQ(buffer[2], default_constructed_value);
|
||||
EXPECT_EQ(buffer[4], 0);
|
||||
EXPECT_EQ(buffer[5], default_constructed_value);
|
||||
@@ -142,10 +142,10 @@ TEST(cpp_type, CopyToUninitialized)
|
||||
{
|
||||
int buffer1[10] = {0};
|
||||
int buffer2[10] = {0};
|
||||
CPPType_TestType.copy_to_uninitialized((void *)buffer1, (void *)buffer2);
|
||||
CPPType_TestType.copy_construct((void *)buffer1, (void *)buffer2);
|
||||
EXPECT_EQ(buffer1[0], copy_constructed_from_value);
|
||||
EXPECT_EQ(buffer2[0], copy_constructed_value);
|
||||
CPPType_TestType.copy_to_uninitialized_n((void *)buffer1, (void *)buffer2, 3);
|
||||
CPPType_TestType.copy_construct_n((void *)buffer1, (void *)buffer2, 3);
|
||||
EXPECT_EQ(buffer1[0], copy_constructed_from_value);
|
||||
EXPECT_EQ(buffer2[0], copy_constructed_value);
|
||||
EXPECT_EQ(buffer1[1], copy_constructed_from_value);
|
||||
@@ -154,7 +154,7 @@ TEST(cpp_type, CopyToUninitialized)
|
||||
EXPECT_EQ(buffer2[2], copy_constructed_value);
|
||||
EXPECT_EQ(buffer1[3], 0);
|
||||
EXPECT_EQ(buffer2[3], 0);
|
||||
CPPType_TestType.copy_to_uninitialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
|
||||
CPPType_TestType.copy_construct_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
|
||||
EXPECT_EQ(buffer1[2], copy_constructed_from_value);
|
||||
EXPECT_EQ(buffer2[2], copy_constructed_value);
|
||||
EXPECT_EQ(buffer1[4], 0);
|
||||
@@ -173,10 +173,10 @@ TEST(cpp_type, CopyToInitialized)
|
||||
{
|
||||
int buffer1[10] = {0};
|
||||
int buffer2[10] = {0};
|
||||
CPPType_TestType.copy_to_initialized((void *)buffer1, (void *)buffer2);
|
||||
CPPType_TestType.copy_assign((void *)buffer1, (void *)buffer2);
|
||||
EXPECT_EQ(buffer1[0], copy_assigned_from_value);
|
||||
EXPECT_EQ(buffer2[0], copy_assigned_value);
|
||||
CPPType_TestType.copy_to_initialized_n((void *)buffer1, (void *)buffer2, 3);
|
||||
CPPType_TestType.copy_assign_n((void *)buffer1, (void *)buffer2, 3);
|
||||
EXPECT_EQ(buffer1[0], copy_assigned_from_value);
|
||||
EXPECT_EQ(buffer2[0], copy_assigned_value);
|
||||
EXPECT_EQ(buffer1[1], copy_assigned_from_value);
|
||||
@@ -185,7 +185,7 @@ TEST(cpp_type, CopyToInitialized)
|
||||
EXPECT_EQ(buffer2[2], copy_assigned_value);
|
||||
EXPECT_EQ(buffer1[3], 0);
|
||||
EXPECT_EQ(buffer2[3], 0);
|
||||
CPPType_TestType.copy_to_initialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
|
||||
CPPType_TestType.copy_assign_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
|
||||
EXPECT_EQ(buffer1[2], copy_assigned_from_value);
|
||||
EXPECT_EQ(buffer2[2], copy_assigned_value);
|
||||
EXPECT_EQ(buffer1[4], 0);
|
||||
@@ -204,10 +204,10 @@ TEST(cpp_type, RelocateToUninitialized)
|
||||
{
|
||||
int buffer1[10] = {0};
|
||||
int buffer2[10] = {0};
|
||||
CPPType_TestType.relocate_to_uninitialized((void *)buffer1, (void *)buffer2);
|
||||
CPPType_TestType.relocate_construct((void *)buffer1, (void *)buffer2);
|
||||
EXPECT_EQ(buffer1[0], destructed_value);
|
||||
EXPECT_EQ(buffer2[0], move_constructed_value);
|
||||
CPPType_TestType.relocate_to_uninitialized_n((void *)buffer1, (void *)buffer2, 3);
|
||||
CPPType_TestType.relocate_construct_n((void *)buffer1, (void *)buffer2, 3);
|
||||
EXPECT_EQ(buffer1[0], destructed_value);
|
||||
EXPECT_EQ(buffer2[0], move_constructed_value);
|
||||
EXPECT_EQ(buffer1[1], destructed_value);
|
||||
@@ -216,7 +216,7 @@ TEST(cpp_type, RelocateToUninitialized)
|
||||
EXPECT_EQ(buffer2[2], move_constructed_value);
|
||||
EXPECT_EQ(buffer1[3], 0);
|
||||
EXPECT_EQ(buffer2[3], 0);
|
||||
CPPType_TestType.relocate_to_uninitialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
|
||||
CPPType_TestType.relocate_construct_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
|
||||
EXPECT_EQ(buffer1[2], destructed_value);
|
||||
EXPECT_EQ(buffer2[2], move_constructed_value);
|
||||
EXPECT_EQ(buffer1[4], 0);
|
||||
@@ -235,10 +235,10 @@ TEST(cpp_type, RelocateToInitialized)
|
||||
{
|
||||
int buffer1[10] = {0};
|
||||
int buffer2[10] = {0};
|
||||
CPPType_TestType.relocate_to_initialized((void *)buffer1, (void *)buffer2);
|
||||
CPPType_TestType.relocate_assign((void *)buffer1, (void *)buffer2);
|
||||
EXPECT_EQ(buffer1[0], destructed_value);
|
||||
EXPECT_EQ(buffer2[0], move_assigned_value);
|
||||
CPPType_TestType.relocate_to_initialized_n((void *)buffer1, (void *)buffer2, 3);
|
||||
CPPType_TestType.relocate_assign_n((void *)buffer1, (void *)buffer2, 3);
|
||||
EXPECT_EQ(buffer1[0], destructed_value);
|
||||
EXPECT_EQ(buffer2[0], move_assigned_value);
|
||||
EXPECT_EQ(buffer1[1], destructed_value);
|
||||
@@ -247,7 +247,7 @@ TEST(cpp_type, RelocateToInitialized)
|
||||
EXPECT_EQ(buffer2[2], move_assigned_value);
|
||||
EXPECT_EQ(buffer1[3], 0);
|
||||
EXPECT_EQ(buffer2[3], 0);
|
||||
CPPType_TestType.relocate_to_initialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
|
||||
CPPType_TestType.relocate_assign_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
|
||||
EXPECT_EQ(buffer1[2], destructed_value);
|
||||
EXPECT_EQ(buffer2[2], move_assigned_value);
|
||||
EXPECT_EQ(buffer1[4], 0);
|
||||
@@ -266,7 +266,7 @@ TEST(cpp_type, FillInitialized)
|
||||
{
|
||||
int buffer1 = 0;
|
||||
int buffer2[10] = {0};
|
||||
CPPType_TestType.fill_initialized((void *)&buffer1, (void *)buffer2, 3);
|
||||
CPPType_TestType.fill_assign_n((void *)&buffer1, (void *)buffer2, 3);
|
||||
EXPECT_EQ(buffer1, copy_assigned_from_value);
|
||||
EXPECT_EQ(buffer2[0], copy_assigned_value);
|
||||
EXPECT_EQ(buffer2[1], copy_assigned_value);
|
||||
@@ -274,7 +274,7 @@ TEST(cpp_type, FillInitialized)
|
||||
EXPECT_EQ(buffer2[3], 0);
|
||||
|
||||
buffer1 = 0;
|
||||
CPPType_TestType.fill_initialized_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8});
|
||||
CPPType_TestType.fill_assign_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8});
|
||||
EXPECT_EQ(buffer1, copy_assigned_from_value);
|
||||
EXPECT_EQ(buffer2[0], copy_assigned_value);
|
||||
EXPECT_EQ(buffer2[1], copy_assigned_value);
|
||||
@@ -292,7 +292,7 @@ TEST(cpp_type, FillUninitialized)
|
||||
{
|
||||
int buffer1 = 0;
|
||||
int buffer2[10] = {0};
|
||||
CPPType_TestType.fill_uninitialized((void *)&buffer1, (void *)buffer2, 3);
|
||||
CPPType_TestType.fill_construct_n((void *)&buffer1, (void *)buffer2, 3);
|
||||
EXPECT_EQ(buffer1, copy_constructed_from_value);
|
||||
EXPECT_EQ(buffer2[0], copy_constructed_value);
|
||||
EXPECT_EQ(buffer2[1], copy_constructed_value);
|
||||
@@ -300,7 +300,7 @@ TEST(cpp_type, FillUninitialized)
|
||||
EXPECT_EQ(buffer2[3], 0);
|
||||
|
||||
buffer1 = 0;
|
||||
CPPType_TestType.fill_uninitialized_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8});
|
||||
CPPType_TestType.fill_construct_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8});
|
||||
EXPECT_EQ(buffer1, copy_constructed_from_value);
|
||||
EXPECT_EQ(buffer2[0], copy_constructed_value);
|
||||
EXPECT_EQ(buffer2[1], copy_constructed_value);
|
||||
@@ -318,7 +318,7 @@ TEST(cpp_type, DebugPrint)
|
||||
{
|
||||
int value = 42;
|
||||
std::stringstream ss;
|
||||
CPPType::get<int32_t>().debug_print((void *)&value, ss);
|
||||
CPPType::get<int32_t>().print((void *)&value, ss);
|
||||
std::string text = ss.str();
|
||||
EXPECT_EQ(text, "42");
|
||||
}
|
||||
|
@@ -714,7 +714,7 @@ static void initialize_group_input(NodesModifierData &nmd,
|
||||
{
|
||||
const SocketPropertyType *property_type = get_socket_property_type(socket);
|
||||
if (property_type == nullptr) {
|
||||
cpp_type.copy_to_uninitialized(cpp_type.default_value(), r_value);
|
||||
cpp_type.copy_construct(cpp_type.default_value(), r_value);
|
||||
return;
|
||||
}
|
||||
if (nmd.settings.properties == nullptr) {
|
||||
|
@@ -292,14 +292,22 @@ class LockedNode : NonCopyable, NonMovable {
|
||||
}
|
||||
};
|
||||
|
||||
static const CPPType *get_socket_cpp_type(const DSocket socket)
|
||||
{
|
||||
return nodes::socket_cpp_type_get(*socket->typeinfo());
|
||||
}
|
||||
|
||||
static const CPPType *get_socket_cpp_type(const SocketRef &socket)
|
||||
{
|
||||
return nodes::socket_cpp_type_get(*socket.typeinfo());
|
||||
const CPPType *type = nodes::socket_cpp_type_get(*socket.typeinfo());
|
||||
if (type == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
/* The evaluator only supports types that have special member functions. */
|
||||
if (!type->has_special_member_functions()) {
|
||||
return nullptr;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static const CPPType *get_socket_cpp_type(const DSocket socket)
|
||||
{
|
||||
return get_socket_cpp_type(*socket.socket_ref());
|
||||
}
|
||||
|
||||
static bool node_supports_laziness(const DNode node)
|
||||
@@ -888,7 +896,7 @@ class GeometryNodesEvaluator {
|
||||
OutputState &output_state = node_state.outputs[socket->index()];
|
||||
output_state.has_been_computed = true;
|
||||
void *buffer = allocator.allocate(type->size(), type->alignment());
|
||||
type->copy_to_uninitialized(type->default_value(), buffer);
|
||||
type->copy_construct(type->default_value(), buffer);
|
||||
this->forward_output({node.context(), socket}, {*type, buffer});
|
||||
}
|
||||
}
|
||||
@@ -967,7 +975,7 @@ class GeometryNodesEvaluator {
|
||||
/* Move value into memory owned by the outer allocator. */
|
||||
const CPPType &type = *input_state.type;
|
||||
void *buffer = outer_allocator_.allocate(type.size(), type.alignment());
|
||||
type.move_to_uninitialized(value, buffer);
|
||||
type.move_construct(value, buffer);
|
||||
|
||||
params_.r_output_values.append({type, buffer});
|
||||
}
|
||||
@@ -1204,7 +1212,7 @@ class GeometryNodesEvaluator {
|
||||
}
|
||||
else {
|
||||
/* Cannot convert, use default value instead. */
|
||||
to_type.copy_to_uninitialized(to_type.default_value(), buffer);
|
||||
to_type.copy_construct(to_type.default_value(), buffer);
|
||||
}
|
||||
this->add_value_to_input_socket(to_socket, from_socket, {to_type, buffer});
|
||||
}
|
||||
@@ -1230,7 +1238,7 @@ class GeometryNodesEvaluator {
|
||||
const CPPType &type = *value_to_forward.type();
|
||||
for (const DInputSocket &to_socket : to_sockets.drop_front(1)) {
|
||||
void *buffer = allocator.allocate(type.size(), type.alignment());
|
||||
type.copy_to_uninitialized(value_to_forward.get(), buffer);
|
||||
type.copy_construct(value_to_forward.get(), buffer);
|
||||
this->add_value_to_input_socket(to_socket, from_socket, {type, buffer});
|
||||
}
|
||||
/* Forward the original value to one of the targets. */
|
||||
@@ -1331,7 +1339,7 @@ class GeometryNodesEvaluator {
|
||||
}
|
||||
/* Use a default fallback value when the loaded type is not compatible. */
|
||||
void *default_buffer = allocator.allocate(required_type.size(), required_type.alignment());
|
||||
required_type.copy_to_uninitialized(required_type.default_value(), default_buffer);
|
||||
required_type.copy_construct(required_type.default_value(), default_buffer);
|
||||
return {required_type, default_buffer};
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include "FN_cpp_type_make.hh"
|
||||
#include "NOD_geometry_exec.hh"
|
||||
|
||||
MAKE_CPP_TYPE(GeometrySet, GeometrySet);
|
||||
MAKE_CPP_TYPE(GeometrySet, GeometrySet, CPPTypeFlags::Printable);
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
|
@@ -130,7 +130,7 @@ static void attribute_convert_calc(GeometryComponent &component,
|
||||
const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(result_type);
|
||||
BLI_assert(cpp_type != nullptr);
|
||||
|
||||
cpp_type->copy_to_initialized_n(source_span.data(), result_span.data(), result_span.size());
|
||||
cpp_type->copy_assign_n(source_span.data(), result_span.data(), result_span.size());
|
||||
result_attribute.save();
|
||||
}
|
||||
|
||||
|
@@ -189,6 +189,7 @@ Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &compo
|
||||
if (hash_attribute) {
|
||||
BLI_assert(hashes.size() == hash_attribute->size());
|
||||
const CPPType &cpp_type = hash_attribute->type();
|
||||
BLI_assert(cpp_type.is_hashable());
|
||||
GVArray_GSpan items{*hash_attribute};
|
||||
threading::parallel_for(hashes.index_range(), 512, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
@@ -298,7 +298,7 @@ static void copy_spline_domain_attributes(const CurveComponent &curve_component,
|
||||
if (size != 0) {
|
||||
BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
|
||||
spline_attribute->get(i, buffer);
|
||||
type.fill_initialized(buffer, result[offset], size);
|
||||
type.fill_assign_n(buffer, result[offset], size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -208,7 +208,7 @@ static void fill_new_attribute(Span<const GeometryComponent *> src_components,
|
||||
GVArray_GSpan src_span{*read_attribute};
|
||||
const void *src_buffer = src_span.data();
|
||||
void *dst_buffer = dst_span[offset];
|
||||
cpp_type->copy_to_initialized_n(src_buffer, dst_buffer, domain_size);
|
||||
cpp_type->copy_assign_n(src_buffer, dst_buffer, domain_size);
|
||||
|
||||
offset += domain_size;
|
||||
}
|
||||
@@ -353,7 +353,7 @@ static void ensure_control_point_attribute(const StringRef name,
|
||||
|
||||
BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
|
||||
current_curve_attribute->get(spline_index_in_component, buffer);
|
||||
type.fill_initialized(buffer, new_attribute->data(), new_attribute->size());
|
||||
type.fill_assign_n(buffer, new_attribute->data(), new_attribute->size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ static void ensure_spline_attribute(const StringRef name,
|
||||
GVArray_GSpan src_span{*read_attribute};
|
||||
|
||||
const void *src_buffer = src_span.data();
|
||||
type.copy_to_initialized_n(src_buffer, result_attribute[offset], size);
|
||||
type.copy_assign_n(src_buffer, result_attribute[offset], size);
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
@@ -662,10 +662,10 @@ static bNodeSocketType *make_socket_type_string()
|
||||
return socktype;
|
||||
}
|
||||
|
||||
MAKE_CPP_TYPE(Object, Object *)
|
||||
MAKE_CPP_TYPE(Collection, Collection *)
|
||||
MAKE_CPP_TYPE(Texture, Tex *)
|
||||
MAKE_CPP_TYPE(Material, Material *)
|
||||
MAKE_CPP_TYPE(Object, Object *, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(Collection, Collection *, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(Texture, Tex *, CPPTypeFlags::BasicType)
|
||||
MAKE_CPP_TYPE(Material, Material *, CPPTypeFlags::BasicType)
|
||||
|
||||
static bNodeSocketType *make_socket_type_object()
|
||||
{
|
||||
|
@@ -231,7 +231,7 @@ void DataTypeConversions::convert_to_uninitialized(const CPPType &from_type,
|
||||
void *to_value) const
|
||||
{
|
||||
if (from_type == to_type) {
|
||||
from_type.copy_to_uninitialized(from_value, to_value);
|
||||
from_type.copy_construct(from_value, to_value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user