Skip to content

Commit

Permalink
Fix variant::operator< not producing a strict ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
CelticMinstrel committed Apr 3, 2017
1 parent f12696d commit 651861d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 36 deletions.
18 changes: 9 additions & 9 deletions src/formula/variant.cpp
Expand Up @@ -614,44 +614,44 @@ bool variant::operator==(const variant& v) const
return false;
}

return *value_ == *v.value_;
return value_->equals(*v.value_);
}

bool variant::operator!=(const variant& v) const
{
return !operator==(v);
}

bool variant::operator<=(const variant& v) const
bool variant::operator<(const variant& v) const
{
if(type() != v.type()) {
if(is_decimal() && v.is_int()) {
return as_decimal() <= v.as_decimal();
return as_decimal() < v.as_decimal();
}

if(v.is_decimal() && is_int()) {
return as_decimal() <= v.as_decimal();
return as_decimal() < v.as_decimal();
}

return type() < v.type();
}

return *value_ <= *v.value_;
return value_->less_than(*v.value_);
}

bool variant::operator>=(const variant& v) const
{
return v <= *this;
return !(*this < v);
}

bool variant::operator<(const variant& v) const
bool variant::operator<=(const variant& v) const
{
return !(*this >= v);
return !(v < *this);
}

bool variant::operator>(const variant& v) const
{
return !(*this <= v);
return v < *this;
}

variant variant::list_elements_add(const variant& v) const
Expand Down
16 changes: 8 additions & 8 deletions src/formula/variant_value.cpp
Expand Up @@ -114,12 +114,12 @@ std::string variant_callable::get_debug_string(formula_seen_stack& seen, bool ve
return ss.str();
}

bool variant_callable::operator==(variant_value_base& other) const
bool variant_callable::equals(variant_value_base& other) const
{
return callable_->equals(value_ref_cast<variant_callable>(other).callable_);
}

bool variant_callable::operator<=(variant_value_base& other) const
bool variant_callable::less_than(variant_value_base& other) const
{
return value_ref_cast<variant_callable>(other).callable_->less(callable_);
}
Expand Down Expand Up @@ -224,7 +224,7 @@ variant variant_list::list_op(value_base_ptr second, std::function<variant(varia
return variant(res);
}

bool variant_list::operator==(variant_value_base& other) const
bool variant_list::equals(variant_value_base& other) const
{
const auto& other_container = value_ref_cast<variant_list>(other).get_container();

Expand All @@ -241,7 +241,7 @@ bool variant_list::operator==(variant_value_base& other) const
return true;
}

bool variant_list::operator<=(variant_value_base& other) const
bool variant_list::less_than(variant_value_base& other) const
{
const auto& other_container = value_ref_cast<variant_list>(other).get_container();

Expand All @@ -253,7 +253,7 @@ bool variant_list::operator<=(variant_value_base& other) const
}
}

return num_elements() <= other.num_elements();
return num_elements() < other.num_elements();
}

std::string variant_map::to_string_detail(const variant_map_raw::value_type& container_val, mod_func_t mod_func) const
Expand All @@ -267,14 +267,14 @@ std::string variant_map::to_string_detail(const variant_map_raw::value_type& con
return ss.str();
}

bool variant_map::operator==(variant_value_base& other) const
bool variant_map::equals(variant_value_base& other) const
{
return get_container() == value_ref_cast<variant_map>(other).get_container();
}

bool variant_map::operator<=(variant_value_base& other) const
bool variant_map::less_than(variant_value_base& other) const
{
return get_container() <= value_ref_cast<variant_map>(other).get_container();
return get_container() < value_ref_cast<variant_map>(other).get_container();
}

} // namespace game_logic
42 changes: 23 additions & 19 deletions src/formula/variant_value.hpp
Expand Up @@ -126,14 +126,18 @@ class variant_value_base
return false;
}

virtual bool operator==(variant_value_base& other) const
/** Called to determine if this variant is equal to another _of the same type_.
This function is _only_ called if get_type() returns the same result for both arguments. */
virtual bool equals(variant_value_base& /*other*/) const
{
return other.get_type() == VARIANT_TYPE::TYPE_NULL;
return true; // null is equal to null
}

virtual bool operator<=(variant_value_base& /*other*/) const
/** Called to determine if this variant is less than another _of the same type_.
This function is _only_ called if get_type() returns the same result for both arguments. */
virtual bool less_than(variant_value_base& /*other*/) const
{
return true;
return false; // null is not less than null
}

/** Returns the id of the variant type */
Expand Down Expand Up @@ -177,14 +181,14 @@ class variant_int : public virtual variant_value_base
return string_cast();
}

virtual bool operator==(variant_value_base& other) const override
virtual bool equals(variant_value_base& other) const override
{
return value_ == value_ref_cast<variant_int>(other).value_;
}

virtual bool operator<=(variant_value_base& other) const override
virtual bool less_than(variant_value_base& other) const override
{
return value_ <= value_ref_cast<variant_int>(other).value_;
return value_ < value_ref_cast<variant_int>(other).value_;
}

virtual const VARIANT_TYPE& get_type() const override
Expand Down Expand Up @@ -241,14 +245,14 @@ class variant_decimal : public virtual variant_value_base
return to_string_impl(true);
}

virtual bool operator==(variant_value_base& other) const override
virtual bool equals(variant_value_base& other) const override
{
return value_ == value_ref_cast<variant_decimal>(other).value_;
}

virtual bool operator<=(variant_value_base& other) const override
virtual bool less_than(variant_value_base& other) const override
{
return value_ <= value_ref_cast<variant_decimal>(other).value_;
return value_ < value_ref_cast<variant_decimal>(other).value_;
}

virtual const VARIANT_TYPE& get_type() const override
Expand Down Expand Up @@ -293,8 +297,8 @@ class variant_callable : public virtual variant_value_base

virtual std::string get_debug_string(formula_seen_stack& seen, bool verbose) const override;

virtual bool operator==(variant_value_base& other) const override;
virtual bool operator<=(variant_value_base& other) const override;
virtual bool equals(variant_value_base& other) const override;
virtual bool less_than(variant_value_base& other) const override;

virtual const VARIANT_TYPE& get_type() const override
{
Expand Down Expand Up @@ -339,14 +343,14 @@ class variant_string : public virtual variant_value_base
return string_;
}

virtual bool operator==(variant_value_base& other) const override
virtual bool equals(variant_value_base& other) const override
{
return string_ == value_ref_cast<variant_string>(other).string_;
}

virtual bool operator<=(variant_value_base& other) const override
virtual bool less_than(variant_value_base& other) const override
{
return string_ <= value_ref_cast<variant_string>(other).string_;
return string_ < value_ref_cast<variant_string>(other).string_;
}

virtual const VARIANT_TYPE& get_type() const override
Expand Down Expand Up @@ -443,8 +447,8 @@ class variant_list : public variant_container<variant_vector>
*/
variant list_op(value_base_ptr second, std::function<variant(variant&, variant&)> op_func);

virtual bool operator==(variant_value_base& other) const override;
virtual bool operator<=(variant_value_base& other) const override;
virtual bool equals(variant_value_base& other) const override;
virtual bool less_than(variant_value_base& other) const override;

virtual const VARIANT_TYPE& get_type() const override
{
Expand All @@ -467,8 +471,8 @@ class variant_map : public variant_container<variant_map_raw>
: variant_container<variant_map_raw>(map)
{}

virtual bool operator==(variant_value_base& other) const override;
virtual bool operator<=(variant_value_base& other) const override;
virtual bool equals(variant_value_base& other) const override;
virtual bool less_than(variant_value_base& other) const override;

virtual const VARIANT_TYPE& get_type() const override
{
Expand Down

0 comments on commit 651861d

Please sign in to comment.