[CXX-1325] Overly-greedy template substitution in declarations of comparison operator free functions for bsoncxx::types::value Created: 24/Apr/17  Updated: 28/Oct/23  Resolved: 26/Jun/17

Status: Closed
Project: C++ Driver
Component/s: API
Affects Version/s: None
Fix Version/s: 3.2.0-rc0

Type: Bug Priority: Minor - P4
Reporter: J Rassi Assignee: Isabella Siu (Inactive)
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 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.



 Comments   
Comment by Githook User [ 26/Jun/17 ]

Author:

{u'username': u'iwysiu', u'name': u'Isabella Siu', u'email': u'sakurablossom@blueblueworld.com'}

Message: CXX-1325 change overly greedy template substitiution in bsoncxx::types::value comparison operators
Branch: master
https://github.com/mongodb/mongo-cxx-driver/commit/b150786d23f4da1a94122817d315df7a99c3478c

Comment by J Rassi [ 24/Apr/17 ]

One potential fix for this issue:

diff --git a/src/bsoncxx/types/value.hpp b/src/bsoncxx/types/value.hpp
index e6d379a..c90b907 100644
--- a/src/bsoncxx/types/value.hpp
+++ b/src/bsoncxx/types/value.hpp
@@ -386,7 +386,8 @@ class BSONCXX_API value {
 // operators
 template <typename T>
 using not_value =
-    typename std::enable_if<!std::is_same<typename std::remove_reference<T>::type, value>::value,
+    typename std::enable_if<std::is_constructible<value, T>::value &&
+                                !std::is_same<typename std::remove_reference<T>::type, value>::value,
                             bool>::type;
 
 // these all return bool

Generated at Wed Feb 07 22:02:12 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.