Cleanup: move inline method definitions out of class

This makes it easier to scan the API.
This commit is contained in:
Jacques Lucke
2024-08-29 13:43:22 +02:00
parent 28ed225100
commit acda21e055
4 changed files with 719 additions and 513 deletions

View File

@@ -28,76 +28,105 @@ class DataType {
Category category_;
const CPPType *type_;
DataType(Category category, const CPPType &type) : category_(category), type_(&type) {}
DataType(Category category, const CPPType &type);
public:
DataType() = default;
static DataType ForSingle(const CPPType &type)
{
return DataType(Single, type);
}
static DataType ForSingle(const CPPType &type);
static DataType ForVector(const CPPType &type);
static DataType ForVector(const CPPType &type)
{
return DataType(Vector, type);
}
template<typename T> static DataType ForSingle();
template<typename T> static DataType ForVector();
template<typename T> static DataType ForSingle()
{
return DataType::ForSingle(CPPType::get<T>());
}
bool is_single() const;
bool is_vector() const;
template<typename T> static DataType ForVector()
{
return DataType::ForVector(CPPType::get<T>());
}
Category category() const;
bool is_single() const
{
return category_ == Single;
}
bool is_vector() const
{
return category_ == Vector;
}
Category category() const
{
return category_;
}
const CPPType &single_type() const
{
BLI_assert(this->is_single());
return *type_;
}
const CPPType &vector_base_type() const
{
BLI_assert(this->is_vector());
return *type_;
}
const CPPType &single_type() const;
const CPPType &vector_base_type() const;
BLI_STRUCT_EQUALITY_OPERATORS_2(DataType, category_, type_)
std::string to_string() const
{
switch (category_) {
case Single:
return type_->name();
case Vector:
return type_->name() + " Vector";
}
BLI_assert(false);
return "";
}
std::string to_string() const;
uint64_t hash() const
{
return get_default_hash(*type_, category_);
}
uint64_t hash() const;
};
/* -------------------------------------------------------------------- */
/** \name #DataType Inline Methods
* \{ */
inline DataType::DataType(Category category, const CPPType &type)
: category_(category), type_(&type)
{
}
inline DataType DataType::ForSingle(const CPPType &type)
{
return DataType(Single, type);
}
inline DataType DataType::ForVector(const CPPType &type)
{
return DataType(Vector, type);
}
template<typename T> inline DataType DataType::ForSingle()
{
return DataType::ForSingle(CPPType::get<T>());
}
template<typename T> inline DataType DataType::ForVector()
{
return DataType::ForVector(CPPType::get<T>());
}
inline bool DataType::is_single() const
{
return category_ == Single;
}
inline bool DataType::is_vector() const
{
return category_ == Vector;
}
inline DataType::Category DataType::category() const
{
return category_;
}
inline const CPPType &DataType::single_type() const
{
BLI_assert(this->is_single());
return *type_;
}
inline const CPPType &DataType::vector_base_type() const
{
BLI_assert(this->is_vector());
return *type_;
}
inline std::string DataType::to_string() const
{
switch (category_) {
case Single:
return type_->name();
case Vector:
return type_->name() + " Vector";
}
BLI_assert(false);
return "";
}
inline uint64_t DataType::hash() const
{
return get_default_hash(*type_, category_);
}
/** \} */
} // namespace blender::fn::multi_function

View File

@@ -51,97 +51,120 @@ class ParamType {
DataType data_type_;
public:
ParamType(InterfaceType interface_type, DataType data_type)
: interface_type_(interface_type), data_type_(data_type)
{
}
ParamType(InterfaceType interface_type, DataType data_type);
static ParamType ForSingleInput(const CPPType &type)
{
return ParamType(InterfaceType::Input, DataType::ForSingle(type));
}
static ParamType ForSingleInput(const CPPType &type);
static ParamType ForVectorInput(const CPPType &base_type);
static ParamType ForSingleOutput(const CPPType &type);
static ParamType ForVectorOutput(const CPPType &base_type);
static ParamType ForMutableSingle(const CPPType &type);
static ParamType ForMutableVector(const CPPType &base_type);
static ParamType ForVectorInput(const CPPType &base_type)
{
return ParamType(InterfaceType::Input, DataType::ForVector(base_type));
}
const DataType &data_type() const;
InterfaceType interface_type() const;
ParamCategory category() const;
static ParamType ForSingleOutput(const CPPType &type)
{
return ParamType(InterfaceType::Output, DataType::ForSingle(type));
}
static ParamType ForVectorOutput(const CPPType &base_type)
{
return ParamType(InterfaceType::Output, DataType::ForVector(base_type));
}
static ParamType ForMutableSingle(const CPPType &type)
{
return ParamType(InterfaceType::Mutable, DataType::ForSingle(type));
}
static ParamType ForMutableVector(const CPPType &base_type)
{
return ParamType(InterfaceType::Mutable, DataType::ForVector(base_type));
}
const DataType &data_type() const
{
return data_type_;
}
InterfaceType interface_type() const
{
return interface_type_;
}
ParamCategory category() const
{
switch (data_type_.category()) {
case DataType::Single: {
switch (interface_type_) {
case Input:
return ParamCategory::SingleInput;
case Output:
return ParamCategory::SingleOutput;
case Mutable:
return ParamCategory::SingleMutable;
}
break;
}
case DataType::Vector: {
switch (interface_type_) {
case Input:
return ParamCategory::VectorInput;
case Output:
return ParamCategory::VectorOutput;
case Mutable:
return ParamCategory::VectorMutable;
}
break;
}
}
BLI_assert_unreachable();
return ParamCategory::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);
}
bool is_output() const
{
return interface_type_ == Output;
}
bool is_input_or_mutable() const;
bool is_output_or_mutable() const;
bool is_output() const;
BLI_STRUCT_EQUALITY_OPERATORS_2(ParamType, interface_type_, data_type_)
};
/* -------------------------------------------------------------------- */
/** \name #ParamType Inline Methods
* \{ */
inline ParamType::ParamType(InterfaceType interface_type, DataType data_type)
: interface_type_(interface_type), data_type_(data_type)
{
}
inline ParamType ParamType::ForSingleInput(const CPPType &type)
{
return ParamType(InterfaceType::Input, DataType::ForSingle(type));
}
inline ParamType ParamType::ForVectorInput(const CPPType &base_type)
{
return ParamType(InterfaceType::Input, DataType::ForVector(base_type));
}
inline ParamType ParamType::ForSingleOutput(const CPPType &type)
{
return ParamType(InterfaceType::Output, DataType::ForSingle(type));
}
inline ParamType ParamType::ForVectorOutput(const CPPType &base_type)
{
return ParamType(InterfaceType::Output, DataType::ForVector(base_type));
}
inline ParamType ParamType::ForMutableSingle(const CPPType &type)
{
return ParamType(InterfaceType::Mutable, DataType::ForSingle(type));
}
inline ParamType ParamType::ForMutableVector(const CPPType &base_type)
{
return ParamType(InterfaceType::Mutable, DataType::ForVector(base_type));
}
inline const DataType &ParamType::data_type() const
{
return data_type_;
}
inline ParamType::InterfaceType ParamType::interface_type() const
{
return interface_type_;
}
inline ParamCategory ParamType::category() const
{
switch (data_type_.category()) {
case DataType::Single: {
switch (interface_type_) {
case Input:
return ParamCategory::SingleInput;
case Output:
return ParamCategory::SingleOutput;
case Mutable:
return ParamCategory::SingleMutable;
}
break;
}
case DataType::Vector: {
switch (interface_type_) {
case Input:
return ParamCategory::VectorInput;
case Output:
return ParamCategory::VectorOutput;
case Mutable:
return ParamCategory::VectorMutable;
}
break;
}
}
BLI_assert_unreachable();
return ParamCategory::SingleInput;
}
inline bool ParamType::is_input_or_mutable() const
{
return ELEM(interface_type_, Input, Mutable);
}
inline bool ParamType::is_output_or_mutable() const
{
return ELEM(interface_type_, Output, Mutable);
}
inline bool ParamType::is_output() const
{
return interface_type_ == Output;
}
/** \} */
} // namespace blender::fn::multi_function

View File

@@ -36,11 +36,7 @@ class ParamsBuilder {
friend class Params;
ParamsBuilder(const Signature &signature, const IndexMask &mask)
: signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size())
{
actual_params_.reserve(signature.params.size());
}
ParamsBuilder(const Signature &signature, const IndexMask &mask);
public:
/**
@@ -49,182 +45,42 @@ class ParamsBuilder {
*/
ParamsBuilder(const class MultiFunction &fn, const IndexMask *mask);
template<typename T> void add_readonly_single_input_value(T value, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForSingleInput(CPPType::get<T>()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single{},
CPPType::get<T>(),
min_array_size_,
&value);
}
template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForSingleInput(CPPType::get<T>()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single_ref{},
CPPType::get<T>(),
min_array_size_,
value);
}
void add_readonly_single_input(const GSpan span, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForSingleInput(span.type()), expected_name);
BLI_assert(span.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>, varray_tag::span{}, span);
}
void add_readonly_single_input(GPointer value, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForSingleInput(*value.type()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single_ref{},
*value.type(),
min_array_size_,
value.get());
}
void add_readonly_single_input(GVArray varray, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForSingleInput(varray.type()), expected_name);
BLI_assert(varray.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>, std::move(varray));
}
template<typename T> void add_readonly_single_input_value(T value, StringRef expected_name = "");
template<typename T>
void add_readonly_single_input(const T *value, StringRef expected_name = "");
void add_readonly_single_input(const GSpan span, StringRef expected_name = "");
void add_readonly_single_input(GPointer value, StringRef expected_name = "");
void add_readonly_single_input(GVArray varray, StringRef expected_name = "");
void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "")
{
this->add_readonly_vector_input(
this->resource_scope().construct<GVVectorArray_For_GVectorArray>(vector_array),
expected_name);
}
void add_readonly_vector_input(const GSpan single_vector, StringRef expected_name = "")
{
this->add_readonly_vector_input(
this->resource_scope().construct<GVVectorArray_For_SingleGSpan>(single_vector,
min_array_size_),
expected_name);
}
void add_readonly_vector_input(const GVVectorArray &ref, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForVectorInput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<const GVVectorArray *>, &ref);
}
void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "");
void add_readonly_vector_input(const GSpan single_vector, StringRef expected_name = "");
void add_readonly_vector_input(const GVVectorArray &ref, StringRef expected_name = "");
template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "")
{
this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1),
expected_name);
}
void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForSingleOutput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, ref);
}
void add_ignored_single_output(StringRef expected_name = "")
{
this->assert_current_param_name(expected_name);
const int param_index = this->current_param_index();
const ParamType &param_type = signature_->params[param_index].type;
BLI_assert(param_type.category() == ParamCategory::SingleOutput);
const DataType data_type = param_type.data_type();
const CPPType &type = data_type.single_type();
template<typename T>
void add_uninitialized_single_output(T *value, StringRef expected_name = "");
void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "");
if (bool(signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput)) {
/* An empty span indicates that this is ignored. */
const GMutableSpan dummy_span{type};
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, dummy_span);
}
else {
this->add_unused_output_for_unsupporting_function(type);
}
}
void add_ignored_single_output(StringRef expected_name = "");
void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForVectorOutput(vector_array.type()),
expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVectorArray *>, &vector_array);
}
void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "");
void add_single_mutable(GMutableSpan ref, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForMutableSingle(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, ref);
}
void add_single_mutable(GMutableSpan ref, StringRef expected_name = "");
void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "")
{
this->assert_current_param_type(ParamType::ForMutableVector(vector_array.type()),
expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVectorArray *>, &vector_array);
}
void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "");
int next_param_index() const
{
return actual_params_.size();
}
int next_param_index() const;
GMutableSpan computed_array(int param_index)
{
BLI_assert(ELEM(signature_->params[param_index].type.category(),
ParamCategory::SingleOutput,
ParamCategory::SingleMutable));
return std::get<GMutableSpan>(actual_params_[param_index]);
}
GMutableSpan computed_array(int param_index);
GVectorArray &computed_vector_array(int param_index)
{
BLI_assert(ELEM(signature_->params[param_index].type.category(),
ParamCategory::VectorOutput,
ParamCategory::VectorMutable));
return *std::get<GVectorArray *>(actual_params_[param_index]);
}
GVectorArray &computed_vector_array(int param_index);
private:
void assert_current_param_type(ParamType param_type, StringRef expected_name = "")
{
UNUSED_VARS_NDEBUG(param_type, expected_name);
#ifndef NDEBUG
int param_index = this->current_param_index();
void assert_current_param_type(ParamType param_type, StringRef expected_name = "");
void assert_current_param_name(StringRef expected_name);
if (expected_name != "") {
StringRef actual_name = signature_->params[param_index].name;
BLI_assert(actual_name == expected_name);
}
int current_param_index() const;
ParamType expected_type = signature_->params[param_index].type;
BLI_assert(expected_type == param_type);
#endif
}
void assert_current_param_name(StringRef expected_name)
{
UNUSED_VARS_NDEBUG(expected_name);
#ifndef NDEBUG
if (expected_name.is_empty()) {
return;
}
const int param_index = this->current_param_index();
StringRef actual_name = signature_->params[param_index].name;
BLI_assert(actual_name == expected_name);
#endif
}
int current_param_index() const
{
return actual_params_.size();
}
ResourceScope &resource_scope()
{
if (!scope_) {
scope_ = std::make_unique<ResourceScope>();
}
return *scope_;
}
ResourceScope &resource_scope();
void add_unused_output_for_unsupporting_function(const CPPType &type);
};
@@ -236,16 +92,8 @@ class Params {
public:
Params(ParamsBuilder &builder) : builder_(&builder) {}
template<typename T> VArray<T> readonly_single_input(int param_index, StringRef name = "")
{
const GVArray &varray = this->readonly_single_input(param_index, name);
return varray.typed<T>();
}
const GVArray &readonly_single_input(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, ParamCategory::SingleInput);
return std::get<GVArray>(builder_->actual_params_[param_index]);
}
template<typename T> VArray<T> readonly_single_input(int param_index, StringRef name = "");
const GVArray &readonly_single_input(int param_index, StringRef name = "");
/**
* \return True when the caller provided a buffer for this output parameter. This allows the
@@ -253,110 +101,364 @@ class Params {
* #uninitialized_single_output when this returns false. In this case a new temporary buffer is
* allocated.
*/
bool single_output_is_required(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
return !std::get<GMutableSpan>(builder_->actual_params_[param_index]).is_empty();
}
bool single_output_is_required(int param_index, StringRef name = "");
template<typename T>
MutableSpan<T> uninitialized_single_output(int param_index, StringRef name = "")
{
return this->uninitialized_single_output(param_index, name).typed<T>();
}
GMutableSpan uninitialized_single_output(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
BLI_assert(
!bool(builder_->signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput));
GMutableSpan span = std::get<GMutableSpan>(builder_->actual_params_[param_index]);
BLI_assert(span.size() >= builder_->min_array_size_);
return span;
}
MutableSpan<T> uninitialized_single_output(int param_index, StringRef name = "");
GMutableSpan uninitialized_single_output(int param_index, StringRef name = "");
/**
* Same as #uninitialized_single_output, but returns an empty span when the output is not
* required.
*/
template<typename T>
MutableSpan<T> uninitialized_single_output_if_required(int param_index, StringRef name = "")
{
return this->uninitialized_single_output_if_required(param_index, name).typed<T>();
}
GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
BLI_assert(
bool(builder_->signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput));
return std::get<GMutableSpan>(builder_->actual_params_[param_index]);
}
MutableSpan<T> uninitialized_single_output_if_required(int param_index, StringRef name = "");
GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "");
template<typename T>
const VVectorArray<T> &readonly_vector_input(int param_index, StringRef name = "")
{
const GVVectorArray &vector_array = this->readonly_vector_input(param_index, name);
return builder_->resource_scope().construct<VVectorArray_For_GVVectorArray<T>>(vector_array);
}
const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, ParamCategory::VectorInput);
return *std::get<const GVVectorArray *>(builder_->actual_params_[param_index]);
}
const VVectorArray<T> &readonly_vector_input(int param_index, StringRef name = "");
const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "");
template<typename T>
GVectorArray_TypedMutableRef<T> vector_output(int param_index, StringRef name = "")
{
return {this->vector_output(param_index, name)};
}
GVectorArray &vector_output(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, ParamCategory::VectorOutput);
return *std::get<GVectorArray *>(builder_->actual_params_[param_index]);
}
GVectorArray_TypedMutableRef<T> vector_output(int param_index, StringRef name = "");
GVectorArray &vector_output(int param_index, StringRef name = "");
template<typename T> MutableSpan<T> single_mutable(int param_index, StringRef name = "")
{
return this->single_mutable(param_index, name).typed<T>();
}
GMutableSpan single_mutable(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, ParamCategory::SingleMutable);
return std::get<GMutableSpan>(builder_->actual_params_[param_index]);
}
template<typename T> MutableSpan<T> single_mutable(int param_index, StringRef name = "");
GMutableSpan single_mutable(int param_index, StringRef name = "");
template<typename T>
GVectorArray_TypedMutableRef<T> vector_mutable(int param_index, StringRef name = "")
{
return {this->vector_mutable(param_index, name)};
}
GVectorArray &vector_mutable(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, ParamCategory::VectorMutable);
return *std::get<GVectorArray *>(builder_->actual_params_[param_index]);
}
GVectorArray_TypedMutableRef<T> vector_mutable(int param_index, StringRef name = "");
GVectorArray &vector_mutable(int param_index, StringRef name = "");
private:
void assert_correct_param(int param_index, StringRef name, ParamType param_type)
{
UNUSED_VARS_NDEBUG(param_index, name, param_type);
#ifndef NDEBUG
BLI_assert(builder_->signature_->params[param_index].type == param_type);
if (name.size() > 0) {
BLI_assert(builder_->signature_->params[param_index].name == name);
}
#endif
}
void assert_correct_param(int param_index, StringRef name, ParamCategory category)
{
UNUSED_VARS_NDEBUG(param_index, name, category);
#ifndef NDEBUG
BLI_assert(builder_->signature_->params[param_index].type.category() == category);
if (name.size() > 0) {
BLI_assert(builder_->signature_->params[param_index].name == name);
}
#endif
}
void assert_correct_param(int param_index, StringRef name, ParamType param_type);
void assert_correct_param(int param_index, StringRef name, ParamCategory category);
};
/* -------------------------------------------------------------------- */
/** \name #Paramsbuilder Inline Methods
* \{ */
inline ParamsBuilder::ParamsBuilder(const Signature &signature, const IndexMask &mask)
: signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size())
{
actual_params_.reserve(signature.params.size());
}
template<typename T>
inline void ParamsBuilder::add_readonly_single_input_value(T value, StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForSingleInput(CPPType::get<T>()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single{},
CPPType::get<T>(),
min_array_size_,
&value);
}
template<typename T>
inline void ParamsBuilder::add_readonly_single_input(const T *value, StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForSingleInput(CPPType::get<T>()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single_ref{},
CPPType::get<T>(),
min_array_size_,
value);
}
inline void ParamsBuilder::add_readonly_single_input(const GSpan span, StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForSingleInput(span.type()), expected_name);
BLI_assert(span.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>, varray_tag::span{}, span);
}
inline void ParamsBuilder::add_readonly_single_input(GPointer value, StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForSingleInput(*value.type()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single_ref{},
*value.type(),
min_array_size_,
value.get());
}
inline void ParamsBuilder::add_readonly_single_input(GVArray varray, StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForSingleInput(varray.type()), expected_name);
BLI_assert(varray.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>, std::move(varray));
}
inline void ParamsBuilder::add_readonly_vector_input(const GVectorArray &vector_array,
StringRef expected_name)
{
this->add_readonly_vector_input(
this->resource_scope().construct<GVVectorArray_For_GVectorArray>(vector_array),
expected_name);
}
inline void ParamsBuilder::add_readonly_vector_input(const GSpan single_vector,
StringRef expected_name)
{
this->add_readonly_vector_input(this->resource_scope().construct<GVVectorArray_For_SingleGSpan>(
single_vector, min_array_size_),
expected_name);
}
inline void ParamsBuilder::add_readonly_vector_input(const GVVectorArray &ref,
StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForVectorInput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<const GVVectorArray *>, &ref);
}
template<typename T>
inline void ParamsBuilder::add_uninitialized_single_output(T *value, StringRef expected_name)
{
this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1), expected_name);
}
inline void ParamsBuilder::add_uninitialized_single_output(GMutableSpan ref,
StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForSingleOutput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, ref);
}
inline void ParamsBuilder::add_ignored_single_output(StringRef expected_name)
{
this->assert_current_param_name(expected_name);
const int param_index = this->current_param_index();
const ParamType &param_type = signature_->params[param_index].type;
BLI_assert(param_type.category() == ParamCategory::SingleOutput);
const DataType data_type = param_type.data_type();
const CPPType &type = data_type.single_type();
if (bool(signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput)) {
/* An empty span indicates that this is ignored. */
const GMutableSpan dummy_span{type};
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, dummy_span);
}
else {
this->add_unused_output_for_unsupporting_function(type);
}
}
inline void ParamsBuilder::add_vector_output(GVectorArray &vector_array, StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForVectorOutput(vector_array.type()), expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVectorArray *>, &vector_array);
}
inline void ParamsBuilder::add_single_mutable(GMutableSpan ref, StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForMutableSingle(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, ref);
}
inline void ParamsBuilder::add_vector_mutable(GVectorArray &vector_array, StringRef expected_name)
{
this->assert_current_param_type(ParamType::ForMutableVector(vector_array.type()), expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVectorArray *>, &vector_array);
}
inline int ParamsBuilder::next_param_index() const
{
return actual_params_.size();
}
inline GMutableSpan ParamsBuilder::computed_array(int param_index)
{
BLI_assert(ELEM(signature_->params[param_index].type.category(),
ParamCategory::SingleOutput,
ParamCategory::SingleMutable));
return std::get<GMutableSpan>(actual_params_[param_index]);
}
inline GVectorArray &ParamsBuilder::computed_vector_array(int param_index)
{
BLI_assert(ELEM(signature_->params[param_index].type.category(),
ParamCategory::VectorOutput,
ParamCategory::VectorMutable));
return *std::get<GVectorArray *>(actual_params_[param_index]);
}
inline void ParamsBuilder::assert_current_param_type(ParamType param_type, StringRef expected_name)
{
UNUSED_VARS_NDEBUG(param_type, expected_name);
#ifndef NDEBUG
int param_index = this->current_param_index();
if (expected_name != "") {
StringRef actual_name = signature_->params[param_index].name;
BLI_assert(actual_name == expected_name);
}
ParamType expected_type = signature_->params[param_index].type;
BLI_assert(expected_type == param_type);
#endif
}
inline void ParamsBuilder::assert_current_param_name(StringRef expected_name)
{
UNUSED_VARS_NDEBUG(expected_name);
#ifndef NDEBUG
if (expected_name.is_empty()) {
return;
}
const int param_index = this->current_param_index();
StringRef actual_name = signature_->params[param_index].name;
BLI_assert(actual_name == expected_name);
#endif
}
inline int ParamsBuilder::current_param_index() const
{
return actual_params_.size();
}
inline ResourceScope &ParamsBuilder::resource_scope()
{
if (!scope_) {
scope_ = std::make_unique<ResourceScope>();
}
return *scope_;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name #Params Inline Methods
* \{ */
template<typename T>
inline VArray<T> Params::readonly_single_input(int param_index, StringRef name)
{
const GVArray &varray = this->readonly_single_input(param_index, name);
return varray.typed<T>();
}
inline const GVArray &Params::readonly_single_input(int param_index, StringRef name)
{
this->assert_correct_param(param_index, name, ParamCategory::SingleInput);
return std::get<GVArray>(builder_->actual_params_[param_index]);
}
inline bool Params::single_output_is_required(int param_index, StringRef name)
{
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
return !std::get<GMutableSpan>(builder_->actual_params_[param_index]).is_empty();
}
template<typename T>
inline MutableSpan<T> Params::uninitialized_single_output(int param_index, StringRef name)
{
return this->uninitialized_single_output(param_index, name).typed<T>();
}
inline GMutableSpan Params::uninitialized_single_output(int param_index, StringRef name)
{
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
BLI_assert(
!bool(builder_->signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput));
GMutableSpan span = std::get<GMutableSpan>(builder_->actual_params_[param_index]);
BLI_assert(span.size() >= builder_->min_array_size_);
return span;
}
template<typename T>
inline MutableSpan<T> Params::uninitialized_single_output_if_required(int param_index,
StringRef name)
{
return this->uninitialized_single_output_if_required(param_index, name).typed<T>();
}
inline GMutableSpan Params::uninitialized_single_output_if_required(int param_index,
StringRef name)
{
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
BLI_assert(
bool(builder_->signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput));
return std::get<GMutableSpan>(builder_->actual_params_[param_index]);
}
template<typename T>
inline const VVectorArray<T> &Params::readonly_vector_input(int param_index, StringRef name)
{
const GVVectorArray &vector_array = this->readonly_vector_input(param_index, name);
return builder_->resource_scope().construct<VVectorArray_For_GVVectorArray<T>>(vector_array);
}
inline const GVVectorArray &Params::readonly_vector_input(int param_index, StringRef name)
{
this->assert_correct_param(param_index, name, ParamCategory::VectorInput);
return *std::get<const GVVectorArray *>(builder_->actual_params_[param_index]);
}
template<typename T>
inline GVectorArray_TypedMutableRef<T> Params::vector_output(int param_index, StringRef name)
{
return {this->vector_output(param_index, name)};
}
inline GVectorArray &Params::vector_output(int param_index, StringRef name)
{
this->assert_correct_param(param_index, name, ParamCategory::VectorOutput);
return *std::get<GVectorArray *>(builder_->actual_params_[param_index]);
}
template<typename T> inline MutableSpan<T> Params::single_mutable(int param_index, StringRef name)
{
return this->single_mutable(param_index, name).typed<T>();
}
inline GMutableSpan Params::single_mutable(int param_index, StringRef name)
{
this->assert_correct_param(param_index, name, ParamCategory::SingleMutable);
return std::get<GMutableSpan>(builder_->actual_params_[param_index]);
}
template<typename T>
inline GVectorArray_TypedMutableRef<T> Params::vector_mutable(int param_index, StringRef name)
{
return {this->vector_mutable(param_index, name)};
}
inline GVectorArray &Params::vector_mutable(int param_index, StringRef name)
{
this->assert_correct_param(param_index, name, ParamCategory::VectorMutable);
return *std::get<GVectorArray *>(builder_->actual_params_[param_index]);
}
inline void Params::assert_correct_param(int param_index, StringRef name, ParamType param_type)
{
UNUSED_VARS_NDEBUG(param_index, name, param_type);
#ifndef NDEBUG
BLI_assert(builder_->signature_->params[param_index].type == param_type);
if (name.size() > 0) {
BLI_assert(builder_->signature_->params[param_index].name == name);
}
#endif
}
inline void Params::assert_correct_param(int param_index, StringRef name, ParamCategory category)
{
UNUSED_VARS_NDEBUG(param_index, name, category);
#ifndef NDEBUG
BLI_assert(builder_->signature_->params[param_index].type.category() == category);
if (name.size() > 0) {
BLI_assert(builder_->signature_->params[param_index].name == name);
}
#endif
}
/** \} */
} // namespace blender::fn::multi_function

View File

@@ -51,123 +51,175 @@ class SignatureBuilder {
Signature &signature_;
public:
SignatureBuilder(const char *function_name, Signature &signature_to_build)
: signature_(signature_to_build)
{
signature_.function_name = function_name;
}
SignatureBuilder(const char *function_name, Signature &signature_to_build);
/* Input Parameter Types */
template<typename T> void single_input(const char *name)
{
this->single_input(name, CPPType::get<T>());
}
void single_input(const char *name, const CPPType &type)
{
this->input(name, DataType::ForSingle(type));
}
template<typename T> void vector_input(const char *name)
{
this->vector_input(name, CPPType::get<T>());
}
void vector_input(const char *name, const CPPType &base_type)
{
this->input(name, DataType::ForVector(base_type));
}
void input(const char *name, DataType data_type)
{
signature_.params.append({ParamType(ParamType::Input, data_type), name});
}
template<typename T> void single_input(const char *name);
void single_input(const char *name, const CPPType &type);
template<typename T> void vector_input(const char *name);
void vector_input(const char *name, const CPPType &base_type);
void input(const char *name, DataType data_type);
/* Output Parameter Types */
template<typename T> void single_output(const char *name, const ParamFlag flag = ParamFlag::None)
{
this->single_output(name, CPPType::get<T>(), flag);
}
void single_output(const char *name, const CPPType &type, const ParamFlag flag = ParamFlag::None)
{
this->output(name, DataType::ForSingle(type), flag);
}
template<typename T> void vector_output(const char *name, const ParamFlag flag = ParamFlag::None)
{
this->vector_output(name, CPPType::get<T>(), flag);
}
template<typename T>
void single_output(const char *name, const ParamFlag flag = ParamFlag::None);
void single_output(const char *name,
const CPPType &type,
const ParamFlag flag = ParamFlag::None);
template<typename T>
void vector_output(const char *name, const ParamFlag flag = ParamFlag::None);
void vector_output(const char *name,
const CPPType &base_type,
const ParamFlag flag = ParamFlag::None)
{
this->output(name, DataType::ForVector(base_type), flag);
}
void output(const char *name, DataType data_type, const ParamFlag flag = ParamFlag::None)
{
signature_.params.append({ParamType(ParamType::Output, data_type), name, flag});
}
const ParamFlag flag = ParamFlag::None);
void output(const char *name, DataType data_type, const ParamFlag flag = ParamFlag::None);
/* Mutable Parameter Types */
template<typename T> void single_mutable(const char *name)
{
this->single_mutable(name, CPPType::get<T>());
}
void single_mutable(const char *name, const CPPType &type)
{
this->mutable_(name, DataType::ForSingle(type));
}
template<typename T> void vector_mutable(const char *name)
{
this->vector_mutable(name, CPPType::get<T>());
}
void vector_mutable(const char *name, const CPPType &base_type)
{
this->mutable_(name, DataType::ForVector(base_type));
}
void mutable_(const char *name, DataType data_type)
{
signature_.params.append({ParamType(ParamType::Mutable, data_type), name});
}
void add(const char *name, const ParamType &param_type)
{
switch (param_type.interface_type()) {
case ParamType::Input:
this->input(name, param_type.data_type());
break;
case ParamType::Mutable:
this->mutable_(name, param_type.data_type());
break;
case ParamType::Output:
this->output(name, param_type.data_type());
break;
}
}
template<typename T> void single_mutable(const char *name);
void single_mutable(const char *name, const CPPType &type);
template<typename T> void vector_mutable(const char *name);
void vector_mutable(const char *name, const CPPType &base_type);
void mutable_(const char *name, DataType data_type);
template<ParamCategory Category, typename T>
void add(ParamTag<Category, T> /*tag*/, const char *name)
{
switch (Category) {
case ParamCategory::SingleInput:
this->single_input<T>(name);
return;
case ParamCategory::VectorInput:
this->vector_input<T>(name);
return;
case ParamCategory::SingleOutput:
this->single_output<T>(name);
return;
case ParamCategory::VectorOutput:
this->vector_output<T>(name);
return;
case ParamCategory::SingleMutable:
this->single_mutable<T>(name);
return;
case ParamCategory::VectorMutable:
this->vector_mutable<T>(name);
return;
}
BLI_assert_unreachable();
}
void add(ParamTag<Category, T> /*tag*/, const char *name);
void add(const char *name, const ParamType &param_type);
};
/* -------------------------------------------------------------------- */
/** \name #SignatureBuilder Inline Methods
* \{ */
inline SignatureBuilder::SignatureBuilder(const char *function_name, Signature &signature_to_build)
: signature_(signature_to_build)
{
signature_.function_name = function_name;
}
template<typename T> inline void SignatureBuilder::single_input(const char *name)
{
this->single_input(name, CPPType::get<T>());
}
inline void SignatureBuilder::single_input(const char *name, const CPPType &type)
{
this->input(name, DataType::ForSingle(type));
}
template<typename T> inline void SignatureBuilder::vector_input(const char *name)
{
this->vector_input(name, CPPType::get<T>());
}
inline void SignatureBuilder::vector_input(const char *name, const CPPType &base_type)
{
this->input(name, DataType::ForVector(base_type));
}
inline void SignatureBuilder::input(const char *name, DataType data_type)
{
signature_.params.append({ParamType(ParamType::Input, data_type), name});
}
template<typename T>
inline void SignatureBuilder::single_output(const char *name, const ParamFlag flag)
{
this->single_output(name, CPPType::get<T>(), flag);
}
inline void SignatureBuilder::single_output(const char *name,
const CPPType &type,
const ParamFlag flag)
{
this->output(name, DataType::ForSingle(type), flag);
}
template<typename T>
inline void SignatureBuilder::vector_output(const char *name, const ParamFlag flag)
{
this->vector_output(name, CPPType::get<T>(), flag);
}
inline void SignatureBuilder::vector_output(const char *name,
const CPPType &base_type,
const ParamFlag flag)
{
this->output(name, DataType::ForVector(base_type), flag);
}
inline void SignatureBuilder::output(const char *name, DataType data_type, const ParamFlag flag)
{
signature_.params.append({ParamType(ParamType::Output, data_type), name, flag});
}
template<typename T> inline void SignatureBuilder::single_mutable(const char *name)
{
this->single_mutable(name, CPPType::get<T>());
}
inline void SignatureBuilder::single_mutable(const char *name, const CPPType &type)
{
this->mutable_(name, DataType::ForSingle(type));
}
template<typename T> inline void SignatureBuilder::vector_mutable(const char *name)
{
this->vector_mutable(name, CPPType::get<T>());
}
inline void SignatureBuilder::vector_mutable(const char *name, const CPPType &base_type)
{
this->mutable_(name, DataType::ForVector(base_type));
}
inline void SignatureBuilder::mutable_(const char *name, DataType data_type)
{
signature_.params.append({ParamType(ParamType::Mutable, data_type), name});
}
inline void SignatureBuilder::add(const char *name, const ParamType &param_type)
{
switch (param_type.interface_type()) {
case ParamType::Input:
this->input(name, param_type.data_type());
break;
case ParamType::Mutable:
this->mutable_(name, param_type.data_type());
break;
case ParamType::Output:
this->output(name, param_type.data_type());
break;
}
}
template<ParamCategory Category, typename T>
inline void SignatureBuilder::add(ParamTag<Category, T> /*tag*/, const char *name)
{
switch (Category) {
case ParamCategory::SingleInput:
this->single_input<T>(name);
return;
case ParamCategory::VectorInput:
this->vector_input<T>(name);
return;
case ParamCategory::SingleOutput:
this->single_output<T>(name);
return;
case ParamCategory::VectorOutput:
this->vector_output<T>(name);
return;
case ParamCategory::SingleMutable:
this->single_mutable<T>(name);
return;
case ParamCategory::VectorMutable:
this->vector_mutable<T>(name);
return;
}
BLI_assert_unreachable();
}
/** \} */
} // namespace blender::fn::multi_function