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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
/*
* 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.
*/
#ifndef __FN_MULTI_FUNCTION_PARAM_TYPE_HH__
#define __FN_MULTI_FUNCTION_PARAM_TYPE_HH__
/** \file
* \ingroup fn
*
* A multi-function has an arbitrary amount of parameters. Every parameter belongs to one of three
* interface types:
* - Input: An input parameter is readonly inside the function. The values have to be provided by
* the caller.
* - Output: An output parameter has to be initialized by the function. However, the caller
* provides the memory where the data has to be constructed.
* - Mutable: A mutable parameter can be considered to be an input and output. The caller has to
* initialize the data, but the function is allowed to modify it.
*
* Furthermore, every parameter has a MFDataType that describes what kind of data is being passed
* around.
*/
#include "FN_multi_function_data_type.hh"
namespace blender::fn {
class MFParamType {
public:
enum InterfaceType {
Input,
Output,
Mutable,
};
enum Category {
SingleInput,
VectorInput,
SingleOutput,
VectorOutput,
SingleMutable,
VectorMutable,
};
private:
InterfaceType interface_type_;
MFDataType data_type_;
public:
MFParamType(InterfaceType interface_type, MFDataType data_type)
: interface_type_(interface_type), data_type_(data_type)
{
}
static MFParamType ForSingleInput(const CPPType &type)
{
return MFParamType(InterfaceType::Input, MFDataType::ForSingle(type));
}
static MFParamType ForVectorInput(const CPPType &base_type)
{
return MFParamType(InterfaceType::Input, MFDataType::ForVector(base_type));
}
static MFParamType ForSingleOutput(const CPPType &type)
{
return MFParamType(InterfaceType::Output, MFDataType::ForSingle(type));
}
static MFParamType ForVectorOutput(const CPPType &base_type)
{
return MFParamType(InterfaceType::Output, MFDataType::ForVector(base_type));
}
static MFParamType ForMutableSingle(const CPPType &type)
{
return MFParamType(InterfaceType::Mutable, MFDataType::ForSingle(type));
}
static MFParamType ForMutableVector(const CPPType &base_type)
{
return MFParamType(InterfaceType::Mutable, MFDataType::ForVector(base_type));
}
MFDataType data_type() const
{
return data_type_;
}
InterfaceType interface_type() const
{
return interface_type_;
}
Category category() const
{
switch (data_type_.category()) {
case MFDataType::Single: {
switch (interface_type_) {
case Input:
return SingleInput;
case Output:
return SingleOutput;
case Mutable:
return SingleMutable;
}
break;
}
case MFDataType::Vector: {
switch (interface_type_) {
case Input:
return VectorInput;
case Output:
return VectorOutput;
case Mutable:
return VectorMutable;
}
break;
}
}
BLI_assert(false);
return SingleInput;
}
bool is_input_or_mutable() const
{
return ELEM(interface_type_, Input, Mutable);
}
bool is_output_or_mutable() const
{
return ELEM(interface_type_, Output, Mutable);
}
friend bool operator==(const MFParamType &a, const MFParamType &b);
friend bool operator!=(const MFParamType &a, const MFParamType &b);
};
inline bool operator==(const MFParamType &a, const MFParamType &b)
{
return a.interface_type_ == b.interface_type_ && a.data_type_ == b.data_type_;
}
inline bool operator!=(const MFParamType &a, const MFParamType &b)
{
return !(a == b);
}
} // namespace blender::fn
#endif /* __FN_MULTI_FUNCTION_PARAM_TYPE_HH__ */
|