@@ -114,6 +114,11 @@ class strong_ordering {
114
114
DEFOP (<=);
115
115
DEFOP (>=);
116
116
#pragma pop_macro("DEFOP")
117
+
118
+ // nonstd: Swap greater/less values
119
+ constexpr strong_ordering inverted () const noexcept {
120
+ return *this < 0 ? greater : *this > 0 ? less : *this ;
121
+ }
117
122
};
118
123
119
124
#pragma push_macro("INLINE_VAR")
@@ -151,8 +156,8 @@ struct compare_three_way {
151
156
typename R,
152
157
typename = decltype (tag_invoke(
153
158
std::declval<compare_three_way>(), std::declval<L>(), std::declval<R>()))>
154
- constexpr strong_ordering impl (L const & l, R const & r, rank<2 >) const {
155
- return tag_invoke (* this , l, r);
159
+ constexpr static strong_ordering impl (L const & l, R const & r, rank<2 >) {
160
+ return tag_invoke (compare_three_way{} , l, r);
156
161
}
157
162
158
163
template <typename L, typename R>
@@ -165,19 +170,56 @@ struct compare_three_way {
165
170
* implementation of tag_invoke(compare_three_way, l, r)
166
171
*/
167
172
struct ordering_operators {
173
+ template <typename L, typename R>
174
+ constexpr static auto impl (const L& l, const R& r, rank<1 >)
175
+ BSONCXX_RETURNS(tag_invoke(compare_three_way{}, l, r));
176
+
177
+ template <typename L, typename R>
178
+ constexpr static auto impl (const L& l, const R& r, rank<0 >)
179
+ BSONCXX_RETURNS(tag_invoke(compare_three_way{}, r, l).inverted());
180
+
168
181
#pragma push_macro("DEFOP")
169
182
#undef DEFOP
170
183
#define DEFOP (Oper ) \
171
184
template <typename L, typename R> \
172
185
constexpr friend auto operator Oper (const L& l, const R& r) \
173
- BSONCXX_RETURNS(tag_invoke(compare_three_way{}, l, r) Oper 0)
186
+ BSONCXX_RETURNS(ordering_operators::impl( l, r, rank< 1 >{} ) Oper 0)
174
187
DEFOP(<);
175
188
DEFOP (>);
176
189
DEFOP (<=);
177
190
DEFOP (>=);
178
191
#pragma pop_macro("DEFOP")
179
192
};
180
193
194
+ template <typename T, typename U>
195
+ std::false_type is_partially_ordered_with_f (rank<0 >);
196
+
197
+ template <typename T, typename U>
198
+ auto is_partially_ordered_with_f (rank<1 >,
199
+ const T& l = soft_declval<T>(),
200
+ const U& r = soft_declval<U>()) //
201
+ -> true_t<decltype(l > r),
202
+ decltype(l < r),
203
+ decltype(l >= r),
204
+ decltype(l <= r),
205
+ decltype(r < l),
206
+ decltype(r > l),
207
+ decltype(r <= l),
208
+ decltype(r >= l)>;
209
+
210
+ template <typename T, typename U>
211
+ struct is_partially_ordered_with : decltype (is_partially_ordered_with_f<T, U>(rank<1 >{})) {};
212
+
213
+ template <typename T>
214
+ struct is_totally_ordered
215
+ : conjunction<is_equality_comparable<T>, is_partially_ordered_with<T, T>> {};
216
+
217
+ template <typename T, typename U>
218
+ struct is_totally_ordered_with : conjunction<is_totally_ordered<T>,
219
+ is_totally_ordered<U>,
220
+ is_equality_comparable<T, U>,
221
+ is_partially_ordered_with<T, U>> {};
222
+
181
223
} // namespace detail
182
224
} // namespace bsoncxx
183
225
0 commit comments