BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslalg_synththreewayutil.h
Go to the documentation of this file.
1/// @file bslalg_synththreewayutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslalg_synththreewayutil.h -*-C++-*-
8#ifndef INCLUDED_BSLALG_SYNTHTHREEWAYUTIL
9#define INCLUDED_BSLALG_SYNTHTHREEWAYUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslalg_synththreewayutil bslalg_synththreewayutil
15/// @brief Provide implementation utilities for `operator<=>`.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslalg
19/// @{
20/// @addtogroup bslalg_synththreewayutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslalg_synththreewayutil-purpose"> Purpose</a>
25/// * <a href="#bslalg_synththreewayutil-classes"> Classes </a>
26/// * <a href="#bslalg_synththreewayutil-description"> Description </a>
27/// * <a href="#bslalg_synththreewayutil-usage"> Usage </a>
28/// * <a href="#bslalg_synththreewayutil-example-1-implementing-for-a-sequence-container"> Example 1: Implementing <=> For a Sequence Container </a>
29///
30/// # Purpose {#bslalg_synththreewayutil-purpose}
31/// Provide implementation utilities for `operator<=>`.
32///
33/// # Classes {#bslalg_synththreewayutil-classes}
34///
35/// - bslalg::SynthThreeWayUtil: exposition-only utilities from <compare>
36///
37/// @see bslstl_compare
38///
39/// # Description {#bslalg_synththreewayutil-description}
40/// This component provides a namespace class,
41/// `bslalg::SynthThreeWayUtil`, that contains an implementation of the Standard
42/// exposition-only entities (see [expos.only.entity] in the C++20 Standard):
43/// `synth-three-way` (`bslalg::SynthThreeWayUtil::compare`) and
44/// `synth-three-way-result` (`bslalg::SynthThreeWayUtil::Result`).
45///
46/// `bslalg::SynthThreeWayUtil::compare` is a callable object with the following
47/// effective signature:
48/// @code
49/// template <class T1, class T2>
50/// constexpr Result<T1, T2> compare(const T1& t1, const T2& t2);
51/// @endcode
52/// It returns the result of `t1 <=> t2` expression if this expression is valid.
53/// Otherwise, if `t1 < t2` and `t2 < t1` expressions are well-formed and return
54/// boolean-testable results, `operator<` is used to emulate `operator<=>`.
55/// Otherwise this function is not defined and does not participate in overload
56/// resolution.
57///
58/// As shown above, `bslalg::SynthThreeWayUtil::Result<T1, T2>` is a type
59/// returned by `bslalg::SynthThreeWayUtil::compare<T1, T2>`.
60///
61/// ## Usage {#bslalg_synththreewayutil-usage}
62///
63///
64/// This section illustrates intended use of this component.
65///
66/// ### Example 1: Implementing <=> For a Sequence Container {#bslalg_synththreewayutil-example-1-implementing-for-a-sequence-container}
67///
68///
69/// In the following example we use `bslalg::SynthThreeWayUtil` to implement the
70/// three-way comparison operator (`<=>`) for a list container (whose details
71/// have been elided):
72/// @code
73/// template <class T, class A>
74/// bslalg::SynthThreeWayUtil::Result<T> operator<=>(const list<T,A>& lhs,
75/// const list<T,A>& rhs)
76/// {
77/// return bsl::lexicographical_compare_three_way(
78/// lhs.begin(),
79/// lhs.end(),
80/// rhs.begin(),
81/// rhs.end(),
82/// bslalg::SynthThreeWayUtil::compare);
83/// }
84/// @endcode
85/// Now the `<`, `>`, `<=` and `>=` operators are automatically defined for the
86/// container:
87/// @code
88/// // Create some instance of the template
89/// list<int> list1, list2;
90///
91/// // Empty lists are equal
92/// assert(!(list1 < list2));
93/// assert(!(list1 > list2));
94/// assert( list1 <= list2);
95/// assert( list1 >= list2);
96/// @endcode
97/// @}
98/** @} */
99/** @} */
100
101/** @addtogroup bsl
102 * @{
103 */
104/** @addtogroup bslalg
105 * @{
106 */
107/** @addtogroup bslalg_synththreewayutil
108 * @{
109 */
110
111#include <bslscm_version.h>
112
114#include <bsls_libraryfeatures.h>
115
116#if defined(BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON) && \
117 defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS)
118
119#define BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE 1
120
122
123#include <concepts>
124#include <utility>
125
126
127namespace bslalg {
128
129 // =======================
130 // class SynthThreeWayUtil
131 // =======================
132
133/// "Exposition-only" part of `bslstl_compare.h`
134///
135/// See @ref bslalg_synththreewayutil
136struct SynthThreeWayUtil {
137
138 /// Return the result of `t1 <=> t2` expression if this expression is
139 /// valid. Otherwise, if `t1 < t2` and `t2 < t1` expressions are
140 /// well-formed and return boolean-testable results, use the `<`
141 /// operator to emulate `<=>`. Otherwise this function is not defined and does not participate in overload resolution.
142 ///
143 /// \note Note that this is
144 /// an implementation of the exposition-only callable object
145 /// `synth-three-way` defined by the ISO C++20 Standard
146 /// [expos.only.entity].
147 static constexpr
148 struct {
149 template <class t_TYPE1, class t_TYPE2>
150 static constexpr bool isNoexcept(const t_TYPE1 *t1 = nullptr,
151 const t_TYPE2 *t2 = nullptr)
152 {
153 if constexpr (std::three_way_comparable_with<t_TYPE1, t_TYPE2>)
154 return noexcept(*t1 <=> *t2);
155 else
156 return noexcept(*t1 < *t2) && noexcept(*t2 < *t1);
157 }
158
159 template <class t_TYPE1, class t_TYPE2>
160 [[nodiscard]]
161 constexpr auto operator()(const t_TYPE1& t1, const t_TYPE2& t2) const
162 noexcept(isNoexcept<t_TYPE1, t_TYPE2>())
163 requires requires {
164 { t1 < t2 } -> bslmf::BooleanTestable;
165 { t2 < t1 } -> bslmf::BooleanTestable;
166 }
167 {
168 if constexpr (std::three_way_comparable_with<t_TYPE1, t_TYPE2>)
169 return t1 <=> t2;
170 else
171 {
172 if (t1 < t2)
173 return std::weak_ordering::less;
174 else if (t2 < t1)
175 return std::weak_ordering::greater;
176 else
177 return std::weak_ordering::equivalent;
178 }
179 }
180 } compare{};
181
182 /// A type returned by `SynthThreeWayUtil::compare<t_TYPE1, t_TYPE2>`.
183 ///
184 /// \note Note that this is an implementation of the exposition-only type
185 /// alias `synth-three-way-result` defined by the ISO C++20 Standard
186 /// [expos.only.entity].
187 template <class t_TYPE1, class t_TYPE2 = t_TYPE1>
188 using Result = decltype(compare(std::declval<t_TYPE1&>(),
189 std::declval<t_TYPE2&>()));
190};
191
192} // close package namespace
193
194
195#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON &&
196 // BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
197
198#endif
199
200// ----------------------------------------------------------------------------
201// Copyright 2023 Bloomberg Finance L.P.
202//
203// Licensed under the Apache License, Version 2.0 (the "License");
204// you may not use this file except in compliance with the License.
205// You may obtain a copy of the License at
206//
207// http://www.apache.org/licenses/LICENSE-2.0
208//
209// Unless required by applicable law or agreed to in writing, software
210// distributed under the License is distributed on an "AS IS" BASIS,
211// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
212// See the License for the specific language governing permissions and
213// limitations under the License.
214// ----------------------------- END-OF-FILE ----------------------------------
215
216/** @} */
217/** @} */
218/** @} */
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlc_flathashmap.h:2218