-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add a vector of pointers type #3249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a927497
to
ef7de83
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, but I just had the concern about polymorphic types. Apart from that question, LGTM.
return values_.end(); | ||
} | ||
|
||
friend bool operator==(const vector_of_ptr& lhs, const vector_of_ptr& rhs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: it seems like this won't work correctly on polymorphic types? Am I missing something? Otherwise, would doing a check like static_assert(!std::is_polymorphic<vector_of_ptr::value_type>::value, "operator== will not work correctly on polymorphic values")
be a good idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
operator==
does not work generally for anything polymorphic -- which version to call is resolved statically by the compiler.
Polymorphic equality has to be handled by delegation to a virtual function in any type hierarchy that supports it. So, for example, the way this works in FieldValue
is that there's a single definition of operator==
:
bool operator==(const FieldValue& lhs, const FieldValue& rhs) {
return lhs.rep_->Equals(*rhs.rep_);
}
And FieldValue::BaseValue
(the rep_
in the above), defines Equals
like so:
virtual Type type() const = 0;
virtual bool Equals(const BaseValue& other) const = 0;
The implementation of Equals
in any subclass has to do a type check before comparing values:
class DoubleValue : public NumberValue<Type::Double, double> {
// ...
bool Equals(const BaseValue& other) const override {
if (type() != other.type()) return false;
auto& other_value = Cast<DoubleValue>(other);
return util::DoubleBitwiseEquals(value(), other_value.value());
}
};
This is slightly different than the way we'll handle Field
or Document
types where the std::shared_ptr
will be public. For example for vector_of_ptr<std::shared_ptr<Field>>
, *left == *right
will resolve staticically to operator==(const Field&, const Field&)
. That will dispatch similarly to what we have in FieldValue
.
The next PR that ports FSTFilter
to C++ Filter
implements this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as this is taken into consideration, I'm fine with it. Feel free to decline on my suggestion re. the static_assert
if you think it's unnecessarily restrictive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't do the static_assert
you're suggesting because I'm writing this to support collections of Filter
instances, which are held by pointer only because they're polymorphic :-).
The idea is to make equality by pointed-to-value fully encapsulated in things like
Query::filters_
.This is a separate change from implementing filters to make it straightforward to review. We can add additional operations as required as we need them.