Description
The SFINAE logic in the declarations of the comparison operator free functions for bsoncxx::types::value is overly greedy, such that it prevents users from declaring their own comparison operator overloads which name bsoncxx::types::value as a parameter. See below for the current declarations of these functions:
385 // sfinae in the bool return to avoid competing with the value == value |
386 // operators |
387 template <typename T> |
388 using not_value = |
389 typename std::enable_if<!std::is_same<typename std::remove_reference<T>::type, value>::value, |
390 bool>::type; |
391
|
392 // these all return bool |
393 template <typename T> |
394 BSONCXX_INLINE not_value<T> operator==(const value& lhs, T&& rhs) { |
395 return lhs == value{std::forward<T>(rhs)}; |
396 }
|
397
|
398 template <typename T> |
399 BSONCXX_INLINE not_value<T> operator==(T&& lhs, const value& rhs) { |
400 return value{std::forward<T>(lhs)} == rhs; |
401 }
|
402
|
403 template <typename T> |
404 BSONCXX_INLINE not_value<T> operator!=(const value& lhs, T&& rhs) { |
405 return lhs != value{std::forward<T>(rhs)}; |
406 }
|
407
|
408 template <typename T> |
409 BSONCXX_INLINE not_value<T> operator!=(T&& lhs, const value& rhs) { |
410 return value{std::forward<T>(lhs)} != rhs; |
411 }
|
In addition to inconveniencing users, this prevents us from being able to use bsoncxx::types::value as an operand in "REQUIRE(x == y)" statements with our unit testing framework, since those macro expansions declare operator==() overloads with decltype(y) as a parameter type.