blob: cbb2a576272e4e60eb11f635f4c9861cbbeabbc7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup fn
*/
#include "FN_field.hh"
namespace blender::fn {
/**
* Contains information about how to deal with a `ValueOrField<T>` generically.
*/
class ValueOrFieldCPPType {
private:
void (*construct_from_value_)(void *dst, const void *value);
void (*construct_from_field_)(void *dst, GField field);
const void *(*get_value_ptr_)(const void *value_or_field);
const GField *(*get_field_ptr_)(const void *value_or_field);
bool (*is_field_)(const void *value_or_field);
GField (*as_field_)(const void *value_or_field);
public:
/** The #ValueOrField<T> itself. */
const CPPType &self;
/** The type stored in the field. */
const CPPType &value;
template<typename ValueType> ValueOrFieldCPPType(TypeTag<ValueType> /*value_type*/);
void construct_from_value(void *dst, const void *value) const
{
construct_from_value_(dst, value);
}
void construct_from_field(void *dst, GField field) const
{
construct_from_field_(dst, field);
}
const void *get_value_ptr(const void *value_or_field) const
{
return get_value_ptr_(value_or_field);
}
void *get_value_ptr(void *value_or_field) const
{
/* Use `const_cast` to avoid duplicating the callback for the non-const case. */
return const_cast<void *>(get_value_ptr_(value_or_field));
}
const GField *get_field_ptr(const void *value_or_field) const
{
return get_field_ptr_(value_or_field);
}
bool is_field(const void *value_or_field) const
{
return is_field_(value_or_field);
}
GField as_field(const void *value_or_field) const
{
return as_field_(value_or_field);
}
/**
* Try to find the #ValueOrFieldCPPType that corresponds to a #CPPType.
*/
static const ValueOrFieldCPPType *get_from_self(const CPPType &self);
/**
* Try to find the #ValueOrFieldCPPType that wraps a #ValueOrField containing the given value
* type. This only works when the type has been created with #FN_FIELD_CPP_TYPE_MAKE.
*/
static const ValueOrFieldCPPType *get_from_value(const CPPType &value);
template<typename ValueType> static const ValueOrFieldCPPType &get()
{
static const ValueOrFieldCPPType &type =
ValueOrFieldCPPType::get_impl<std::decay_t<ValueType>>();
return type;
}
private:
template<typename ValueType> static const ValueOrFieldCPPType &get_impl();
void register_self();
};
} // namespace blender::fn
|