MongoDB C++ Driver 4.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
compare.hpp
Go to the documentation of this file.
1// Copyright 2009-present MongoDB, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
18
21
22#include <cstddef>
23#include <functional>
24#include <type_traits>
25
26namespace bsoncxx {
27namespace detail {
28
29// Callable object and tag type for equality comparison.
30struct equal_to {
31 template <typename L, typename R>
32 constexpr requires_t<bool, is_equality_comparable<L, R>> operator()(L&& l, R&& r) const noexcept(noexcept(l == r)) {
33 return l == r;
34 }
35};
36
37// Derive from this class to define ADL-only operator== and operator!= on the basis of
38// an ADL-only tag_invoke(equal_to, l, r).
39class equality_operators {
40 template <typename L, typename R>
41 constexpr static auto impl(rank<1>, L& l, R& r) BSONCXX_PRIVATE_RETURNS(tag_invoke(equal_to{}, l, r));
42
43 template <typename L, typename R>
44 constexpr static auto impl(rank<0>, L& l, R& r) BSONCXX_PRIVATE_RETURNS(tag_invoke(equal_to{}, r, l));
45
46 // @cond DOXYGEN_DISABLE "Found ';' while parsing initializer list!"
47 template <typename Left, typename Other>
48 constexpr friend auto operator==(Left const& self, Other const& other)
49 BSONCXX_PRIVATE_RETURNS(equality_operators::impl(rank<1>{}, self, other));
50 // @endcond
51
52 // @cond DOXYGEN_DISABLE "Found ';' while parsing initializer list!"
53 template <typename Left, typename Other>
54 constexpr friend auto operator!=(Left const& self, Other const& other)
55 BSONCXX_PRIVATE_RETURNS(!equality_operators::impl(rank<1>{}, self, other));
56 // @endcond
57};
58
59// Very basic impl of C++20 std::strong_ordering.
60//
61// We don't need other weaker orderings yet, so this is all that we have.
62class strong_ordering {
63 signed char _c;
64 struct _construct {};
65
66 constexpr strong_ordering(_construct, signed char c) noexcept : _c(c) {}
67
68 public:
69 static strong_ordering const less;
70 static strong_ordering const greater;
71 static strong_ordering const equivalent;
72 static strong_ordering const equal;
73
74 constexpr strong_ordering(std::nullptr_t) noexcept : strong_ordering(_construct{}, 0) {}
75
76 constexpr bool operator==(strong_ordering o) const noexcept {
77 return _c == o._c;
78 }
79 constexpr bool operator!=(strong_ordering o) const noexcept {
80 return !(*this == o);
81 }
82#pragma push_macro("DEFOP")
83#undef DEFOP
84#define DEFOP(Op) \
85 constexpr bool operator Op(std::nullptr_t) const noexcept { \
86 return _c Op 0; \
87 } \
88 static_assert(true, "")
89 DEFOP(<);
90 DEFOP(>);
91 DEFOP(<=);
92 DEFOP(>=);
93#pragma pop_macro("DEFOP")
94
95 // nonstd: Swap greater/less values
96 constexpr strong_ordering inverted() const noexcept {
97 return *this < nullptr ? greater : *this > nullptr ? less : *this;
98 }
99};
100
101#pragma push_macro("INLINE_VAR")
102#undef INLINE_VAR
103#define INLINE_VAR \
104 BSONCXX_PRIVATE_IF_GNU_LIKE([[gnu::weak]]) \
105 BSONCXX_PRIVATE_IF_MSVC(__declspec(selectany))
106
107INLINE_VAR const strong_ordering strong_ordering::less = strong_ordering(strong_ordering::_construct{}, -1);
108INLINE_VAR const strong_ordering strong_ordering::greater = strong_ordering(strong_ordering::_construct{}, 1);
109INLINE_VAR const strong_ordering strong_ordering::equivalent = strong_ordering(strong_ordering::_construct{}, 0);
110INLINE_VAR const strong_ordering strong_ordering::equal = strong_ordering(strong_ordering::_construct{}, 0);
111
112#pragma pop_macro("INLINE_VAR")
113
114// Implements a three-way comparison between two objects. That is, in
115// a single operation, determine whether the left operand is less-than, greater-than,
116// or equal-to the right-hand operand.
117struct compare_three_way {
118 BSONCXX_PRIVATE_WARNINGS_PUSH();
119 BSONCXX_PRIVATE_WARNINGS_DISABLE(GNU("-Wfloat-equal"));
120 template <
121 typename L,
122 typename R,
123 typename = decltype(std::declval<L>() < std::declval<R>()),
124 typename = decltype(std::declval<L>() == std::declval<R>())>
125 constexpr static strong_ordering impl(L const& l, R const& r, rank<1>) {
126 return (l < r) ? strong_ordering::less : (l == r ? strong_ordering::equal : strong_ordering::greater);
127 }
128 BSONCXX_PRIVATE_WARNINGS_POP();
129
130 template <
131 typename L,
132 typename R,
133 typename = decltype(tag_invoke(std::declval<compare_three_way>(), std::declval<L>(), std::declval<R>()))>
134 constexpr static strong_ordering impl(L const& l, R const& r, rank<2>) {
135 return tag_invoke(compare_three_way{}, l, r);
136 }
137
138 template <typename L, typename R>
139 constexpr auto operator()(L const& l, R const& r) const BSONCXX_PRIVATE_RETURNS((impl)(l, r, rank<2>{}));
140};
141
142// Inherit to define ADL-visible ordering operators based on an ADL-visible
143// implementation of tag_invoke(compare_three_way, l, r).
144struct ordering_operators {
145 template <typename L, typename R>
146 constexpr static auto impl(L const& l, R const& r, rank<1>)
147 BSONCXX_PRIVATE_RETURNS(tag_invoke(compare_three_way{}, l, r));
148
149 template <typename L, typename R>
150 constexpr static auto impl(L const& l, R const& r, rank<0>)
151 BSONCXX_PRIVATE_RETURNS(tag_invoke(compare_three_way{}, r, l).inverted());
152
153#pragma push_macro("DEFOP")
154#undef DEFOP
155#define DEFOP(Oper) \
156 template <typename L, typename R> \
157 constexpr friend auto operator Oper(L const& l, R const& r) \
158 BSONCXX_PRIVATE_RETURNS(ordering_operators::impl(l, r, rank<1>{}) Oper nullptr)
159 DEFOP(<);
160 DEFOP(>);
161 DEFOP(<=);
162 DEFOP(>=);
163#pragma pop_macro("DEFOP")
164};
165
166} // namespace detail
167} // namespace bsoncxx
168
170
For internal use only!
The bsoncxx v1 macro guard postlude header.
The bsoncxx v1 macro guard prelude header.
bool operator!=(element const &elem, types::bson_value::view const &v)
Convenience methods to compare for equality against a bson_value.
The top-level namespace within which all bsoncxx library entities are declared.
bool operator==(view_or_value< View, Value > const &lhs, view_or_value< View, Value > const &rhs)
Compare view_or_value objects for (in)equality.
Definition view_or_value.hpp:151
For internal use only!