BDE 4.14.0 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`
134struct SynthThreeWayUtil {
135
136 /// Return the result of `t1 <=> t2` expression if this expression is
137 /// valid. Otherwise, if `t1 < t2` and `t2 < t1` expressions are
138 /// well-formed and return boolean-testable results, use the `<`
139 /// operator to emulate `<=>`. Otherwise this function is not defined
140 /// and does not participate in overload resolution. Note that this is
141 /// an implementation of the exposition-only callable object
142 /// `synth-three-way` defined by the ISO C++20 Standard
143 /// [expos.only.entity].
144 static constexpr
145 struct {
146 template <class t_TYPE1, class t_TYPE2>
147 static constexpr bool isNoexcept(const t_TYPE1 *t1 = nullptr,
148 const t_TYPE2 *t2 = nullptr)
149 {
150 if constexpr (std::three_way_comparable_with<t_TYPE1, t_TYPE2>)
151 return noexcept(*t1 <=> *t2);
152 else
153 return noexcept(*t1 < *t2) && noexcept(*t2 < *t1);
154 }
155
156 template <class t_TYPE1, class t_TYPE2>
157 [[nodiscard]]
158 constexpr auto operator()(const t_TYPE1& t1, const t_TYPE2& t2) const
159 noexcept(isNoexcept<t_TYPE1, t_TYPE2>())
160 requires requires {
161 { t1 < t2 } -> bslmf::BooleanTestable;
162 { t2 < t1 } -> bslmf::BooleanTestable;
163 }
164 {
165 if constexpr (std::three_way_comparable_with<t_TYPE1, t_TYPE2>)
166 return t1 <=> t2;
167 else
168 {
169 if (t1 < t2)
170 return std::weak_ordering::less;
171 else if (t2 < t1)
172 return std::weak_ordering::greater;
173 else
174 return std::weak_ordering::equivalent;
175 }
176 }
177 } compare{};
178
179 /// A type returned by `SynthThreeWayUtil::compare<t_TYPE1, t_TYPE2>`.
180 /// Note that this is an implementation of the exposition-only type
181 /// alias `synth-three-way-result` defined by the ISO C++20 Standard
182 /// [expos.only.entity].
183 template <class t_TYPE1, class t_TYPE2 = t_TYPE1>
184 using Result = decltype(compare(std::declval<t_TYPE1&>(),
185 std::declval<t_TYPE2&>()));
186};
187
188} // close package namespace
189
190
191#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON &&
192 // BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
193
194#endif
195
196// ----------------------------------------------------------------------------
197// Copyright 2023 Bloomberg Finance L.P.
198//
199// Licensed under the Apache License, Version 2.0 (the "License");
200// you may not use this file except in compliance with the License.
201// You may obtain a copy of the License at
202//
203// http://www.apache.org/licenses/LICENSE-2.0
204//
205// Unless required by applicable law or agreed to in writing, software
206// distributed under the License is distributed on an "AS IS" BASIS,
207// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
208// See the License for the specific language governing permissions and
209// limitations under the License.
210// ----------------------------- END-OF-FILE ----------------------------------
211
212/** @} */
213/** @} */
214/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlc_flathashmap.h:1805