Cleanup: reduce boilerplate for equality operators for structs

Pull Request: https://projects.blender.org/blender/blender/pulls/115088
This commit is contained in:
Jacques Lucke 2023-11-20 09:39:13 +01:00
parent b8c84d03cd
commit a976cf4876
18 changed files with 102 additions and 205 deletions

View File

@ -11,6 +11,7 @@
#include "BLI_generic_virtual_array.hh"
#include "BLI_offset_indices.hh"
#include "BLI_set.hh"
#include "BLI_struct_equality_utils.hh"
#include "BKE_anonymous_attribute_id.hh"
#include "BKE_attribute.h"
@ -50,7 +51,8 @@ class AttributeIDRef {
StringRef name() const;
const AnonymousAttributeID &anonymous_id() const;
friend bool operator==(const AttributeIDRef &a, const AttributeIDRef &b);
BLI_STRUCT_EQUALITY_OPERATORS_1(AttributeIDRef, name_)
friend std::ostream &operator<<(std::ostream &stream, const AttributeIDRef &attribute_id);
};
@ -63,10 +65,7 @@ struct AttributeMetaData {
eAttrDomain domain;
eCustomDataType data_type;
constexpr friend bool operator==(AttributeMetaData a, AttributeMetaData b)
{
return (a.domain == b.domain) && (a.data_type == b.data_type);
}
BLI_STRUCT_EQUALITY_OPERATORS_2(AttributeMetaData, domain, data_type)
};
struct AttributeKind {
@ -835,11 +834,6 @@ inline AttributeIDRef::AttributeIDRef(const AnonymousAttributeID *anonymous_id)
anonymous_id_ = anonymous_id;
}
inline bool operator==(const AttributeIDRef &a, const AttributeIDRef &b)
{
return a.name_ == b.name_;
}
inline AttributeIDRef::operator bool() const
{
return !name_.is_empty();

View File

@ -9,6 +9,7 @@
#include "BLI_bit_group_vector.hh"
#include "BLI_bit_span_ops.hh"
#include "BLI_set.hh"
#include "BLI_struct_equality_utils.hh"
#include "BLI_task.hh"
#include "BLI_timeit.hh"
@ -69,10 +70,7 @@ struct ZoneRelation {
return get_default_hash_2(this->parent, this->child);
}
friend bool operator==(const ZoneRelation &a, const ZoneRelation &b)
{
return a.parent == b.parent && a.child == b.child;
}
BLI_STRUCT_EQUALITY_OPERATORS_2(ZoneRelation, parent, child)
};
static std::optional<Vector<ZoneRelation>> get_direct_zone_relations(

View File

@ -7,6 +7,7 @@
#include <ostream>
#include "BLI_math_color.h"
#include "BLI_struct_equality_utils.hh"
namespace blender {
@ -118,17 +119,7 @@ template<typename ChannelStorageType, eSpace Space, eAlpha Alpha> class ColorRGB
return stream;
}
friend bool operator==(const ColorRGBA<ChannelStorageType, Space, Alpha> &a,
const ColorRGBA<ChannelStorageType, Space, Alpha> &b)
{
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
}
friend bool operator!=(const ColorRGBA<ChannelStorageType, Space, Alpha> &a,
const ColorRGBA<ChannelStorageType, Space, Alpha> &b)
{
return !(a == b);
}
BLI_STRUCT_EQUALITY_OPERATORS_4(ColorRGBA, r, g, b, a)
uint64_t hash() const
{

View File

@ -38,6 +38,7 @@
#include "BLI_linear_allocator.hh"
#include "BLI_stack.hh"
#include "BLI_string_ref.hh"
#include "BLI_struct_equality_utils.hh"
namespace blender {
@ -55,15 +56,7 @@ struct ComputeContextHash {
return v1;
}
friend bool operator==(const ComputeContextHash &a, const ComputeContextHash &b)
{
return a.v1 == b.v1 && a.v2 == b.v2;
}
friend bool operator!=(const ComputeContextHash &a, const ComputeContextHash &b)
{
return !(a == b);
}
BLI_STRUCT_EQUALITY_OPERATORS_2(ComputeContextHash, v1, v2)
void mix_in(const void *data, int64_t len);

View File

@ -9,6 +9,7 @@
*/
#include "BLI_implicit_sharing.hh"
#include "BLI_struct_equality_utils.hh"
namespace blender {
@ -127,10 +128,7 @@ template<typename T> class ImplicitSharingPtr {
return get_default_hash(data_);
}
friend bool operator==(const ImplicitSharingPtr &a, const ImplicitSharingPtr &b)
{
return a.data_ == b.data_;
}
BLI_STRUCT_EQUALITY_OPERATORS_1(ImplicitSharingPtr, data_)
private:
static void add_user(T *data)

View File

@ -20,6 +20,7 @@
#include <ostream>
#include "BLI_math_base.hh"
#include "BLI_struct_equality_utils.hh"
namespace blender::math {
@ -144,15 +145,7 @@ template<typename T> struct AngleRadianBase {
return *this;
}
friend bool operator==(const AngleRadianBase &a, const AngleRadianBase &b)
{
return a.value_ == b.value_;
}
friend bool operator!=(const AngleRadianBase &a, const AngleRadianBase &b)
{
return !(a == b);
}
BLI_STRUCT_EQUALITY_OPERATORS_1(AngleRadianBase, value_)
friend std::ostream &operator<<(std::ostream &stream, const AngleRadianBase &rot)
{
@ -348,15 +341,7 @@ template<typename T> struct AngleCartesianBase {
return *this;
}
friend bool operator==(const AngleCartesianBase &a, const AngleCartesianBase &b)
{
return a.cos_ == b.cos_ && a.sin_ == b.sin_;
}
friend bool operator!=(const AngleCartesianBase &a, const AngleCartesianBase &b)
{
return !(a == b);
}
BLI_STRUCT_EQUALITY_OPERATORS_2(AngleCartesianBase, cos_, sin_)
friend std::ostream &operator<<(std::ostream &stream, const AngleCartesianBase &rot)
{

View File

@ -79,15 +79,7 @@ template<typename T, typename AngleT> struct AxisAngleBase {
/** Operators. */
friend bool operator==(const AxisAngleBase &a, const AxisAngleBase &b)
{
return (a.axis() == b.axis()) && (a.angle() == b.angle());
}
friend bool operator!=(const AxisAngleBase &a, const AxisAngleBase &b)
{
return (a != b);
}
BLI_STRUCT_EQUALITY_OPERATORS_2(AxisAngleBase, axis_, angle_)
friend std::ostream &operator<<(std::ostream &stream, const AxisAngleBase &rot)
{

View File

@ -31,6 +31,7 @@
#include "BLI_math_angle_types.hh"
#include "BLI_math_base.hh"
#include "BLI_math_basis_types.hh"
#include "BLI_struct_equality_utils.hh"
namespace blender::math {
@ -186,10 +187,7 @@ template<typename T> struct EulerXYZBase : public EulerBase<T> {
return {-a.xyz_.x, -a.xyz_.y, -a.xyz_.z};
}
friend bool operator==(const EulerXYZBase &a, const EulerXYZBase &b)
{
return a.xyz_ == b.xyz_;
}
BLI_STRUCT_EQUALITY_OPERATORS_1(EulerXYZBase, xyz_)
friend std::ostream &operator<<(std::ostream &stream, const EulerXYZBase &rot)
{
@ -336,10 +334,7 @@ template<typename T> struct Euler3Base : public EulerBase<T> {
return {-a.xyz_, a.order_};
}
friend bool operator==(const Euler3Base &a, const Euler3Base &b)
{
return a.xyz_ == b.xyz_ && a.order_ == b.order_;
}
BLI_STRUCT_EQUALITY_OPERATORS_2(Euler3Base, xyz_, order_)
friend std::ostream &operator<<(std::ostream &stream, const Euler3Base &rot)
{

View File

@ -15,6 +15,7 @@
#include "BLI_math_basis_types.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_struct_equality_utils.hh"
namespace blender::math {
@ -157,10 +158,7 @@ template<typename T> struct QuaternionBase {
return {-a.w, -a.x, -a.y, -a.z};
}
friend bool operator==(const QuaternionBase &a, const QuaternionBase &b)
{
return (a.w == b.w) && (a.x == b.x) && (a.y == b.y) && (a.z == b.z);
}
BLI_STRUCT_EQUALITY_OPERATORS_4(QuaternionBase, w, x, y, z)
uint64_t hash() const
{
@ -264,11 +262,8 @@ template<typename T> struct DualQuaternionBase {
return dq;
}
friend bool operator==(const DualQuaternionBase &a, const DualQuaternionBase &b)
{
return (a.quat == b.quat) && (a.trans == b.trans) && (a.quat_weight == b.quat_weight) &&
(a.scale_weight == b.scale_weight) && (a.scale == b.scale);
}
BLI_STRUCT_EQUALITY_OPERATORS_5(
DualQuaternionBase, quat, trans, quat_weight, scale_weight, scale)
friend std::ostream &operator<<(std::ostream &stream, const DualQuaternionBase &rot)
{

View File

@ -0,0 +1,55 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/**
* The macros below reduce the boilerplate needed to implement basic equality operators for
* structs. These macros could be removed starting with C++20, because then we can use defaulted
* comparison operators: https://en.cppreference.com/w/cpp/language/default_comparisons
*
* Using these macros also reduces the probably for common typos, like comparing a value to itself
* or comparing the same value twice.
*/
#define BLI_STRUCT_DERIVED_UNEQUAL_OPERATOR(Type) \
friend bool operator!=(const Type &a, const Type &b) \
{ \
return !(a == b); \
}
#define BLI_STRUCT_EQUALITY_OPERATORS_1(Type, m) \
friend bool operator==(const Type &a, const Type &b) \
{ \
return a.m == b.m; \
} \
BLI_STRUCT_DERIVED_UNEQUAL_OPERATOR(Type)
#define BLI_STRUCT_EQUALITY_OPERATORS_2(Type, m1, m2) \
friend bool operator==(const Type &a, const Type &b) \
{ \
return a.m1 == b.m1 && a.m2 == b.m2; \
} \
BLI_STRUCT_DERIVED_UNEQUAL_OPERATOR(Type)
#define BLI_STRUCT_EQUALITY_OPERATORS_3(Type, m1, m2, m3) \
friend bool operator==(const Type &a, const Type &b) \
{ \
return a.m1 == b.m1 && a.m2 == b.m2 && a.m3 == b.m3; \
} \
BLI_STRUCT_DERIVED_UNEQUAL_OPERATOR(Type)
#define BLI_STRUCT_EQUALITY_OPERATORS_4(Type, m1, m2, m3, m4) \
friend bool operator==(const Type &a, const Type &b) \
{ \
return a.m1 == b.m1 && a.m2 == b.m2 && a.m3 == b.m3 && a.m4 == b.m4; \
} \
BLI_STRUCT_DERIVED_UNEQUAL_OPERATOR(Type)
#define BLI_STRUCT_EQUALITY_OPERATORS_5(Type, m1, m2, m3, m4, m5) \
friend bool operator==(const Type &a, const Type &b) \
{ \
return a.m1 == b.m1 && a.m2 == b.m2 && a.m3 == b.m3 && a.m4 == b.m4 && a.m5 == b.m5; \
} \
BLI_STRUCT_DERIVED_UNEQUAL_OPERATOR(Type)

View File

@ -8,6 +8,7 @@
#include "BLI_assert.h"
#include "BLI_math_base.h"
#include "BLI_struct_equality_utils.hh"
namespace blender {
@ -58,15 +59,7 @@ struct SubFrame {
return {INT32_MAX, std::nexttowardf(1.0f, 0.0)};
}
friend bool operator==(const SubFrame &a, const SubFrame &b)
{
return a.frame_ == b.frame_ && a.subframe_ == b.subframe_;
}
friend bool operator!=(const SubFrame &a, const SubFrame &b)
{
return !(a == b);
}
BLI_STRUCT_EQUALITY_OPERATORS_2(SubFrame, frame_, subframe_)
friend bool operator<(const SubFrame &a, const SubFrame &b)
{

View File

@ -355,6 +355,7 @@ set(SRC
BLI_string_utf8.h
BLI_string_utf8_symbols.h
BLI_string_utils.hh
BLI_struct_equality_utils.hh
BLI_sub_frame.hh
BLI_sys_types.h
BLI_system.h

View File

@ -13,6 +13,7 @@
*/
#include "BLI_cpp_type.hh"
#include "BLI_struct_equality_utils.hh"
namespace blender::fn::multi_function {
@ -79,8 +80,7 @@ class DataType {
return *type_;
}
friend bool operator==(const DataType &a, const DataType &b);
friend bool operator!=(const DataType &a, const DataType &b);
BLI_STRUCT_EQUALITY_OPERATORS_2(DataType, category_, type_)
std::string to_string() const
{
@ -100,14 +100,4 @@ class DataType {
}
};
inline bool operator==(const DataType &a, const DataType &b)
{
return a.category_ == b.category_ && a.type_ == b.type_;
}
inline bool operator!=(const DataType &a, const DataType &b)
{
return !(a == b);
}
} // namespace blender::fn::multi_function

View File

@ -141,18 +141,7 @@ class ParamType {
return interface_type_ == Output;
}
friend bool operator==(const ParamType &a, const ParamType &b);
friend bool operator!=(const ParamType &a, const ParamType &b);
BLI_STRUCT_EQUALITY_OPERATORS_2(ParamType, interface_type_, data_type_)
};
inline bool operator==(const ParamType &a, const ParamType &b)
{
return a.interface_type_ == b.interface_type_ && a.data_type_ == b.data_type_;
}
inline bool operator!=(const ParamType &a, const ParamType &b)
{
return !(a == b);
}
} // namespace blender::fn::multi_function

View File

@ -67,16 +67,7 @@ class InstructionCursor {
Type type() const;
friend bool operator==(const InstructionCursor &a, const InstructionCursor &b)
{
return a.type_ == b.type_ && a.instruction_ == b.instruction_ &&
a.branch_output_ == b.branch_output_;
}
friend bool operator!=(const InstructionCursor &a, const InstructionCursor &b)
{
return !(a == b);
}
BLI_STRUCT_EQUALITY_OPERATORS_3(InstructionCursor, type_, instruction_, branch_output_)
};
/**

View File

@ -83,8 +83,8 @@ class DNode {
const bNode *operator->() const;
const bNode &operator*() const;
friend bool operator==(const DNode &a, const DNode &b);
friend bool operator!=(const DNode &a, const DNode &b);
BLI_STRUCT_EQUALITY_OPERATORS_2(DNode, context_, bnode_)
operator bool() const;
uint64_t hash() const;
@ -119,8 +119,8 @@ class DSocket {
const bNodeSocket *operator->() const;
const bNodeSocket &operator*() const;
friend bool operator==(const DSocket &a, const DSocket &b);
friend bool operator!=(const DSocket &a, const DSocket &b);
BLI_STRUCT_EQUALITY_OPERATORS_2(DSocket, context_, bsocket_)
operator bool() const;
uint64_t hash() const;
@ -295,16 +295,6 @@ inline const bNode *DNode::bnode() const
return bnode_;
}
inline bool operator==(const DNode &a, const DNode &b)
{
return a.context_ == b.context_ && a.bnode_ == b.bnode_;
}
inline bool operator!=(const DNode &a, const DNode &b)
{
return !(a == b);
}
inline DNode::operator bool() const
{
return bnode_ != nullptr;
@ -379,16 +369,6 @@ inline const bNodeSocket *DSocket::bsocket() const
return bsocket_;
}
inline bool operator==(const DSocket &a, const DSocket &b)
{
return a.context_ == b.context_ && a.bsocket_ == b.bsocket_;
}
inline bool operator!=(const DSocket &a, const DSocket &b)
{
return !(a == b);
}
inline DSocket::operator bool() const
{
return bsocket_ != nullptr;

View File

@ -73,8 +73,7 @@ class OutputFieldDependency {
OutputSocketFieldType field_type() const;
Span<int> linked_input_indices() const;
friend bool operator==(const OutputFieldDependency &a, const OutputFieldDependency &b);
friend bool operator!=(const OutputFieldDependency &a, const OutputFieldDependency &b);
BLI_STRUCT_EQUALITY_OPERATORS_2(OutputFieldDependency, type_, linked_input_indices_)
};
/**
@ -84,8 +83,7 @@ struct FieldInferencingInterface {
Vector<InputSocketFieldType> inputs;
Vector<OutputFieldDependency> outputs;
friend bool operator==(const FieldInferencingInterface &a, const FieldInferencingInterface &b);
friend bool operator!=(const FieldInferencingInterface &a, const FieldInferencingInterface &b);
BLI_STRUCT_EQUALITY_OPERATORS_2(FieldInferencingInterface, inputs, outputs)
};
namespace anonymous_attribute_lifetime {
@ -97,11 +95,7 @@ struct PropagateRelation {
int from_geometry_input;
int to_geometry_output;
friend bool operator==(const PropagateRelation &a, const PropagateRelation &b)
{
return a.from_geometry_input == b.from_geometry_input &&
a.to_geometry_output == b.to_geometry_output;
}
BLI_STRUCT_EQUALITY_OPERATORS_2(PropagateRelation, from_geometry_input, to_geometry_output)
};
/**
@ -111,10 +105,7 @@ struct ReferenceRelation {
int from_field_input;
int to_field_output;
friend bool operator==(const ReferenceRelation &a, const ReferenceRelation &b)
{
return a.from_field_input == b.from_field_input && a.to_field_output == b.to_field_output;
}
BLI_STRUCT_EQUALITY_OPERATORS_2(ReferenceRelation, from_field_input, to_field_output)
};
/**
@ -124,10 +115,7 @@ struct EvalRelation {
int field_input;
int geometry_input;
friend bool operator==(const EvalRelation &a, const EvalRelation &b)
{
return a.field_input == b.field_input && a.geometry_input == b.geometry_input;
}
BLI_STRUCT_EQUALITY_OPERATORS_2(EvalRelation, field_input, geometry_input)
};
/**
@ -137,10 +125,7 @@ struct AvailableRelation {
int field_output;
int geometry_output;
friend bool operator==(const AvailableRelation &a, const AvailableRelation &b)
{
return a.field_output == b.field_output && a.geometry_output == b.geometry_output;
}
BLI_STRUCT_EQUALITY_OPERATORS_2(AvailableRelation, field_output, geometry_output)
};
struct RelationsInNode {
@ -149,10 +134,15 @@ struct RelationsInNode {
Vector<EvalRelation> eval_relations;
Vector<AvailableRelation> available_relations;
Vector<int> available_on_none;
BLI_STRUCT_EQUALITY_OPERATORS_5(RelationsInNode,
propagate_relations,
reference_relations,
eval_relations,
available_relations,
available_on_none)
};
bool operator==(const RelationsInNode &a, const RelationsInNode &b);
bool operator!=(const RelationsInNode &a, const RelationsInNode &b);
std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations);
} // namespace anonymous_attribute_lifetime

View File

@ -147,19 +147,6 @@ void NodeDeclarationBuilder::set_active_panel_builder(const PanelDeclarationBuil
namespace anonymous_attribute_lifetime {
bool operator==(const RelationsInNode &a, const RelationsInNode &b)
{
return a.propagate_relations == b.propagate_relations &&
a.reference_relations == b.reference_relations && a.eval_relations == b.eval_relations &&
a.available_relations == b.available_relations &&
a.available_on_none == b.available_on_none;
}
bool operator!=(const RelationsInNode &a, const RelationsInNode &b)
{
return !(a == b);
}
std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations)
{
stream << "Propagate Relations: " << relations.propagate_relations.size() << "\n";
@ -857,26 +844,6 @@ Span<int> OutputFieldDependency::linked_input_indices() const
return linked_input_indices_;
}
bool operator==(const OutputFieldDependency &a, const OutputFieldDependency &b)
{
return a.type_ == b.type_ && a.linked_input_indices_ == b.linked_input_indices_;
}
bool operator!=(const OutputFieldDependency &a, const OutputFieldDependency &b)
{
return !(a == b);
}
bool operator==(const FieldInferencingInterface &a, const FieldInferencingInterface &b)
{
return a.inputs == b.inputs && a.outputs == b.outputs;
}
bool operator!=(const FieldInferencingInterface &a, const FieldInferencingInterface &b)
{
return !(a == b);
}
const CompositorInputRealizationOptions &SocketDeclaration::compositor_realization_options() const
{
return compositor_realization_options_;