Skip to content

Commit

Permalink
Disable relational operators for classes and exceptions (#2862)
Browse files Browse the repository at this point in the history
  • Loading branch information
bernardnormier authored Oct 7, 2024
1 parent ea24d76 commit dfbdfb3
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 76 deletions.
36 changes: 24 additions & 12 deletions cpp/include/Ice/Comparable.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,84 +117,96 @@ namespace Ice
namespace Tuple
{
/**
* Relational operator for generated structs and classes.
* Relational operator for generated structs.
* @param lhs The left-hand side.
* @param rhs The right-hand side.
* @return True if the left-hand side compares less than the right-hand side, false otherwise.
*/
template<
class C,
std::enable_if_t<std::is_member_function_pointer<decltype(&C::ice_tuple)>::value, bool> = true>
std::enable_if_t<
std::is_member_function_pointer<decltype(&C::ice_tuple)>::value && !std::is_polymorphic_v<C>,
bool> = true>
bool operator<(const C& lhs, const C& rhs)
{
return lhs.ice_tuple() < rhs.ice_tuple();
}

/**
* Relational operator for generated structs and classes.
* Relational operator for generated structs.
* @param lhs The left-hand side.
* @param rhs The right-hand side.
* @return True if the left-hand side compares less than or equal to the right-hand side, false otherwise.
*/
template<
class C,
std::enable_if_t<std::is_member_function_pointer<decltype(&C::ice_tuple)>::value, bool> = true>
std::enable_if_t<
std::is_member_function_pointer<decltype(&C::ice_tuple)>::value && !std::is_polymorphic_v<C>,
bool> = true>
bool operator<=(const C& lhs, const C& rhs)
{
return lhs.ice_tuple() <= rhs.ice_tuple();
}

/**
* Relational operator for generated structs and classes.
* Relational operator for generated structs.
* @param lhs The left-hand side.
* @param rhs The right-hand side.
* @return True if the left-hand side compares greater than the right-hand side, false otherwise.
*/
template<
class C,
std::enable_if_t<std::is_member_function_pointer<decltype(&C::ice_tuple)>::value, bool> = true>
std::enable_if_t<
std::is_member_function_pointer<decltype(&C::ice_tuple)>::value && !std::is_polymorphic_v<C>,
bool> = true>
bool operator>(const C& lhs, const C& rhs)
{
return lhs.ice_tuple() > rhs.ice_tuple();
}

/**
* Relational operator for generated structs and classes.
* Relational operator for generated structs.
* @param lhs The left-hand side.
* @param rhs The right-hand side.
* @return True if the left-hand side compares greater than or equal to the right-hand side, false otherwise.
*/
template<
class C,
std::enable_if_t<std::is_member_function_pointer<decltype(&C::ice_tuple)>::value, bool> = true>
std::enable_if_t<
std::is_member_function_pointer<decltype(&C::ice_tuple)>::value && !std::is_polymorphic_v<C>,
bool> = true>
bool operator>=(const C& lhs, const C& rhs)
{
return lhs.ice_tuple() >= rhs.ice_tuple();
}

/**
* Relational operator for generated structs and classes.
* Relational operator for generated structs.
* @param lhs The left-hand side.
* @param rhs The right-hand side.
* @return True if the left-hand side compares equal to the right-hand side, false otherwise.
*/
template<
class C,
std::enable_if_t<std::is_member_function_pointer<decltype(&C::ice_tuple)>::value, bool> = true>
std::enable_if_t<
std::is_member_function_pointer<decltype(&C::ice_tuple)>::value && !std::is_polymorphic_v<C>,
bool> = true>
bool operator==(const C& lhs, const C& rhs)
{
return lhs.ice_tuple() == rhs.ice_tuple();
}

/**
* Relational operator for generated structs and classes.
* Relational operator for generated structs.
* @param lhs The left-hand side.
* @param rhs The right-hand side.
* @return True if the left-hand side is not equal to the right-hand side, false otherwise.
*/
template<
class C,
std::enable_if_t<std::is_member_function_pointer<decltype(&C::ice_tuple)>::value, bool> = true>
std::enable_if_t<
std::is_member_function_pointer<decltype(&C::ice_tuple)>::value && !std::is_polymorphic_v<C>,
bool> = true>
bool operator!=(const C& lhs, const C& rhs)
{
return lhs.ice_tuple() != rhs.ice_tuple();
Expand Down
22 changes: 13 additions & 9 deletions cpp/src/slice2cpp/Gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1994,16 +1994,20 @@ Slice::Gen::DataDefVisitor::visitModuleStart(const ModulePtr& p)
}

void
Slice::Gen::DataDefVisitor::visitModuleEnd(const ModulePtr&)
Slice::Gen::DataDefVisitor::visitModuleEnd(const ModulePtr& p)
{
// Always generated when this module contains a struct, class, or exception.
H << sp;
H << nl << "using Ice::Tuple::operator<;";
H << nl << "using Ice::Tuple::operator<=;";
H << nl << "using Ice::Tuple::operator>;";
H << nl << "using Ice::Tuple::operator>=;";
H << nl << "using Ice::Tuple::operator==;";
H << nl << "using Ice::Tuple::operator!=;";
if (p->contains<Struct>())
{
// Bring in relational operators for structs.
H << sp;
H << nl << "using Ice::Tuple::operator<;";
H << nl << "using Ice::Tuple::operator<=;";
H << nl << "using Ice::Tuple::operator>;";
H << nl << "using Ice::Tuple::operator>=;";
H << nl << "using Ice::Tuple::operator==;";
H << nl << "using Ice::Tuple::operator!=;";
}

H << sp << nl << '}';
_useWstring = resetUseWstring(_useWstringHist);
}
Expand Down
10 changes: 3 additions & 7 deletions cpp/test/Ice/objects/AllTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,14 @@ allTests(Test::TestHelper* helper)
test(ba2->theS.str == "hello");
test(ba2->str == "hi");

test(*ba1 < *ba2);
test(*ba2 > *ba1);
test(*ba1 != *ba2);
auto [s2, str2] = ba2->ice_tuple();
test(s2 == s);
test(str2 == "hi");

ba1 = ba2->ice_clone();
test(ba1->theS.str == "hello");
test(ba1->str == "hi");

test(*ba1 == *ba2);
test(*ba1 >= *ba2);
test(*ba1 <= *ba2);

BasePtr bp1 = make_shared<Base>();
bp1 = ba2->ice_clone();
test(bp1->theS.str == "hello");
Expand Down
Loading

0 comments on commit dfbdfb3

Please sign in to comment.