xref: /llvm-project/libcxx/include/__type_traits/desugars_to.h (revision 0fb76bae6b2abfe5e0a34557f365a586be989364)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H
10 #define _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H
11 
12 #include <__config>
13 
14 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15 #  pragma GCC system_header
16 #endif
17 
18 _LIBCPP_BEGIN_NAMESPACE_STD
19 
20 // Tags to represent the canonical operations.
21 
22 // syntactically, the operation is equivalent to calling `a == b`
23 struct __equal_tag {};
24 
25 // syntactically, the operation is equivalent to calling `a + b`
26 struct __plus_tag {};
27 
28 // syntactically, the operation is equivalent to calling `a < b`
29 struct __less_tag {};
30 
31 // syntactically, the operation is equivalent to calling `a > b`
32 struct __greater_tag {};
33 
34 // syntactically, the operation is equivalent to calling `a < b`, and these expressions
35 // have to be true for any `a` and `b`:
36 // - `(a < b) == (b > a)`
37 // - `(!(a < b) && !(b < a)) == (a == b)`
38 // For example, this is satisfied for std::less on integral types, but also for ranges::less on all types due to
39 // additional semantic requirements on that operation.
40 struct __totally_ordered_less_tag {};
41 
42 // This class template is used to determine whether an operation "desugars"
43 // (or boils down) to a given canonical operation.
44 //
45 // For example, `std::equal_to<>`, our internal `std::__equal_to` helper and
46 // `ranges::equal_to` are all just fancy ways of representing a transparent
47 // equality operation, so they all desugar to `__equal_tag`.
48 //
49 // This is useful to optimize some functions in cases where we know e.g. the
50 // predicate being passed is actually going to call a builtin operator, or has
51 // some specific semantics.
52 template <class _CanonicalTag, class _Operation, class... _Args>
53 inline const bool __desugars_to_v = false;
54 
55 _LIBCPP_END_NAMESPACE_STD
56 
57 #endif // _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H
58