Blender  V3.3
FN_field_cpp_type.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
9 #include "BLI_cpp_type_make.hh"
10 #include "FN_field.hh"
11 
12 namespace blender::fn {
13 
14 template<typename T> struct FieldCPPTypeParam {
15 };
16 
17 class FieldCPPType : public CPPType {
18  private:
19  const CPPType &base_type_;
20 
21  public:
22  template<typename T>
23  FieldCPPType(FieldCPPTypeParam<Field<T>> /* unused */, StringRef debug_name)
24  : CPPType(CPPTypeParam<Field<T>, CPPTypeFlags::None>(), debug_name),
25  base_type_(CPPType::get<T>())
26  {
27  }
28 
29  const CPPType &base_type() const
30  {
31  return base_type_;
32  }
33 
34  /* Ensure that #GField and #Field<T> have the same layout, to enable casting between the two. */
35  static_assert(sizeof(Field<int>) == sizeof(GField));
36  static_assert(sizeof(Field<int>) == sizeof(Field<std::string>));
37 
38  const GField &get_gfield(const void *field) const
39  {
40  return *(const GField *)field;
41  }
42 
43  void construct_from_gfield(void *r_value, const GField &gfield) const
44  {
45  new (r_value) GField(gfield);
46  }
47 };
48 
49 class ValueOrFieldCPPType : public CPPType {
50  private:
51  const CPPType &base_type_;
52  void (*construct_from_value_)(void *dst, const void *value);
53  void (*construct_from_field_)(void *dst, GField field);
54  const void *(*get_value_ptr_)(const void *value_or_field);
55  const GField *(*get_field_ptr_)(const void *value_or_field);
56  bool (*is_field_)(const void *value_or_field);
57  GField (*as_field_)(const void *value_or_field);
58 
59  public:
60  template<typename T>
62  : CPPType(CPPTypeParam<ValueOrField<T>, CPPTypeFlags::None>(), debug_name),
63  base_type_(CPPType::get<T>())
64  {
65  construct_from_value_ = [](void *dst, const void *value_or_field) {
66  new (dst) ValueOrField<T>(*(const T *)value_or_field);
67  };
68  construct_from_field_ = [](void *dst, GField field) {
69  new (dst) ValueOrField<T>(Field<T>(std::move(field)));
70  };
71  get_value_ptr_ = [](const void *value_or_field) {
72  return (const void *)&((ValueOrField<T> *)value_or_field)->value;
73  };
74  get_field_ptr_ = [](const void *value_or_field) -> const GField * {
75  return &((ValueOrField<T> *)value_or_field)->field;
76  };
77  is_field_ = [](const void *value_or_field) {
78  return ((ValueOrField<T> *)value_or_field)->is_field();
79  };
80  as_field_ = [](const void *value_or_field) -> GField {
81  return ((ValueOrField<T> *)value_or_field)->as_field();
82  };
83  }
84 
85  const CPPType &base_type() const
86  {
87  return base_type_;
88  }
89 
90  void construct_from_value(void *dst, const void *value) const
91  {
92  construct_from_value_(dst, value);
93  }
94 
95  void construct_from_field(void *dst, GField field) const
96  {
97  construct_from_field_(dst, field);
98  }
99 
100  const void *get_value_ptr(const void *value_or_field) const
101  {
102  return get_value_ptr_(value_or_field);
103  }
104 
105  void *get_value_ptr(void *value_or_field) const
106  {
107  /* Use `const_cast` to avoid duplicating the callback for the non-const case. */
108  return const_cast<void *>(get_value_ptr_(value_or_field));
109  }
110 
111  const GField *get_field_ptr(const void *value_or_field) const
112  {
113  return get_field_ptr_(value_or_field);
114  }
115 
116  bool is_field(const void *value_or_field) const
117  {
118  return is_field_(value_or_field);
119  }
120 
121  GField as_field(const void *value_or_field) const
122  {
123  return as_field_(value_or_field);
124  }
125 };
126 
127 } // namespace blender::fn
128 
129 #define MAKE_FIELD_CPP_TYPE(DEBUG_NAME, FIELD_TYPE) \
130  template<> const blender::CPPType &blender::CPPType::get_impl<blender::fn::Field<FIELD_TYPE>>() \
131  { \
132  static blender::fn::FieldCPPType cpp_type{ \
133  blender::fn::FieldCPPTypeParam<blender::fn::Field<FIELD_TYPE>>(), STRINGIFY(DEBUG_NAME)}; \
134  return cpp_type; \
135  } \
136  template<> \
137  const blender::CPPType &blender::CPPType::get_impl<blender::fn::ValueOrField<FIELD_TYPE>>() \
138  { \
139  static blender::fn::ValueOrFieldCPPType cpp_type{ \
140  blender::fn::FieldCPPTypeParam<blender::fn::ValueOrField<FIELD_TYPE>>(), \
141  STRINGIFY(DEBUG_NAME##OrValue)}; \
142  return cpp_type; \
143  }
CPPTypeFlags
Definition: BLI_cpp_type.hh:85
static const CPPType & get()
const GField & get_gfield(const void *field) const
void construct_from_gfield(void *r_value, const GField &gfield) const
FieldCPPType(FieldCPPTypeParam< Field< T >>, StringRef debug_name)
const CPPType & base_type() const
void * get_value_ptr(void *value_or_field) const
const void * get_value_ptr(const void *value_or_field) const
ValueOrFieldCPPType(FieldCPPTypeParam< ValueOrField< T >>, StringRef debug_name)
void construct_from_field(void *dst, GField field) const
const CPPType & base_type() const
const GField * get_field_ptr(const void *value_or_field) const
GField as_field(const void *value_or_field) const
void construct_from_value(void *dst, const void *value) const
bool is_field(const void *value_or_field) const
SyclQueue void void size_t num_bytes void
#define T