Functions: initial hash/equals implementation for constant multi-functions

This commit is contained in:
Jacques Lucke 2020-07-08 15:04:28 +02:00
parent 840941215d
commit 34d175f372
2 changed files with 97 additions and 25 deletions

View File

@ -202,6 +202,39 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction {
}
};
bool generic_values_are_equal(const CPPType &type, const void *a, const void *b);
/**
* A multi-function that outputs the same value every time. The value is not owned by an instance
* of this function. The caller is responsible for destructing and freeing the value.
*/
class CustomMF_GenericConstant : public MultiFunction {
private:
const CPPType &type_;
const void *value_;
template<typename T> friend class CustomMF_Constant;
public:
CustomMF_GenericConstant(const CPPType &type, const void *value);
void call(IndexMask mask, MFParams params, MFContext context) const override;
uint32_t hash() const override;
bool equals(const MultiFunction &other) const override;
};
/**
* A multi-function that outputs the same array every time. The array is not owned by in instance
* of this function. The caller is responsible for destructing and freeing the values.
*/
class CustomMF_GenericConstantArray : public MultiFunction {
private:
GSpan array_;
public:
CustomMF_GenericConstantArray(GSpan array);
void call(IndexMask mask, MFParams params, MFContext context) const override;
};
/**
* Generates a multi-function that outputs a constant value.
*/
@ -223,33 +256,27 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
MutableSpan<T> output = params.uninitialized_single_output<T>(0);
mask.foreach_index([&](uint i) { new (&output[i]) T(value_); });
}
};
/**
* A multi-function that outputs the same value every time. The value is not owned by an instance
* of this function. The caller is responsible for destructing and freeing the value.
*/
class CustomMF_GenericConstant : public MultiFunction {
private:
const CPPType &type_;
const void *value_;
uint32_t hash() const override
{
return DefaultHash<T>{}(value_);
}
public:
CustomMF_GenericConstant(const CPPType &type, const void *value);
void call(IndexMask mask, MFParams params, MFContext context) const override;
};
/**
* A multi-function that outputs the same array every time. The array is not owned by in instance
* of this function. The caller is responsible for destructing and freeing the values.
*/
class CustomMF_GenericConstantArray : public MultiFunction {
private:
GSpan array_;
public:
CustomMF_GenericConstantArray(GSpan array);
void call(IndexMask mask, MFParams params, MFContext context) const override;
bool equals(const MultiFunction &other) const override
{
const CustomMF_Constant *other1 = dynamic_cast<const CustomMF_Constant *>(&other);
if (other1 != nullptr) {
return value_ == other1->value_;
}
const CustomMF_GenericConstant *other2 = dynamic_cast<const CustomMF_GenericConstant *>(
&other);
if (other2 != nullptr) {
if (CPPType::get<T>() == other2->type_) {
return generic_values_are_equal(other2->type_, (const void *)&value_, other2->value_);
}
}
return false;
}
};
} // namespace blender::fn

View File

@ -14,8 +14,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "FN_cpp_types.hh"
#include "FN_multi_function_builder.hh"
#include "BLI_float3.hh"
#include "BLI_hash.hh"
namespace blender::fn {
CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, const void *value)
@ -35,6 +39,47 @@ void CustomMF_GenericConstant::call(IndexMask mask,
type_.fill_uninitialized_indices(value_, output.buffer(), mask);
}
uint CustomMF_GenericConstant::hash() const
{
if (type_ == CPPType_float3) {
return DefaultHash<float3>{}(*(float3 *)value_);
}
if (type_ == CPPType_int32) {
return DefaultHash<int32_t>{}(*(int32_t *)value_);
}
if (type_ == CPPType_float) {
return DefaultHash<float>{}(*(float *)value_);
}
return MultiFunction::hash();
}
/* This should be moved into CPPType. */
bool generic_values_are_equal(const CPPType &type, const void *a, const void *b)
{
if (type == CPPType_float3) {
return *(float3 *)a == *(float3 *)b;
}
if (type == CPPType_int32) {
return *(int *)a == *(int *)b;
}
if (type == CPPType_float) {
return *(float *)a == *(float *)b;
}
return false;
}
bool CustomMF_GenericConstant::equals(const MultiFunction &other) const
{
const CustomMF_GenericConstant *_other = dynamic_cast<const CustomMF_GenericConstant *>(&other);
if (_other == nullptr) {
return false;
}
if (type_ != _other->type_) {
return false;
}
return generic_values_are_equal(type_, value_, _other->value_);
}
static std::string gspan_to_string(GSpan array)
{
std::stringstream ss;