Skip to content

Commit e21084e

Browse files
[CXX-2625] Bring our own optional<T> (#1075)
* Bring our own optional<T> * Fix: Don't instantiate unused trait operands * Ordering traits: is_totally_ordered * Fix return value of swapped compare operators * Clean up the BSONCXX_FWD macro * Formatter for strong_ordering * Fix: compare_three_way name lookup differences between compilers
1 parent c61b9d8 commit e21084e

File tree

11 files changed

+1470
-77
lines changed

11 files changed

+1470
-77
lines changed

src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/config/postlude.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,5 @@ static_assert(false, "BSONCXX_ENUM must be undef'ed");
9595
#pragma pop_macro("BSONCXX_IF_GCC")
9696
#pragma pop_macro("BSONCXX_IF_CLANG")
9797
#pragma pop_macro("BSONCXX_IF_GNU_LIKE")
98+
99+
#pragma pop_macro("BSONCXX_FWD")

src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/config/prelude.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#undef _bsoncxxDisableWarningImpl_for_MSVC
4646
#pragma push_macro("_bsoncxxDisableWarningImpl_for_GNU")
4747
#undef _bsoncxxDisableWarningImpl_for_GNU
48+
#pragma push_macro("BSONCXX_FWD")
49+
#undef BSONCXX_FWD
4850

4951
// compiler.hpp
5052
#pragma push_macro("BSONCXX_INLINE")

src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/config/util.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,6 @@
131131

132132
#define _bsoncxxDisableWarningImpl_for_MSVC(...) \
133133
BSONCXX_IF_MSVC(BSONCXX_PRAGMA(warning(disable : __VA_ARGS__)))
134+
135+
#define BSONCXX_FWD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
136+

src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/stdx/operators.hpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ class strong_ordering {
114114
DEFOP(<=);
115115
DEFOP(>=);
116116
#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+
}
117122
};
118123

119124
#pragma push_macro("INLINE_VAR")
@@ -151,8 +156,8 @@ struct compare_three_way {
151156
typename R,
152157
typename = decltype(tag_invoke(
153158
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);
156161
}
157162

158163
template <typename L, typename R>
@@ -165,19 +170,56 @@ struct compare_three_way {
165170
* implementation of tag_invoke(compare_three_way, l, r)
166171
*/
167172
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+
168181
#pragma push_macro("DEFOP")
169182
#undef DEFOP
170183
#define DEFOP(Oper) \
171184
template <typename L, typename R> \
172185
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)
174187
DEFOP(<);
175188
DEFOP(>);
176189
DEFOP(<=);
177190
DEFOP(>=);
178191
#pragma pop_macro("DEFOP")
179192
};
180193

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+
181223
} // namespace detail
182224
} // namespace bsoncxx
183225

0 commit comments

Comments
 (0)