1 /*
2  * Copyright (c) 2023 NVIDIA Corporation
3  *
4  * Licensed under the Apache License Version 2.0 with LLVM Exceptions
5  * (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  *
8  *   https://llvm.org/LICENSE.txt
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "__config.hpp"
19 #include "__type_traits.hpp"
20 
21 namespace stdexec
22 {
23 
24 //////////////////////////////////////////////////////////////////////////////////////////////////
25 template <class _Fun, class... _As>
26 concept __callable =                        //
27     requires(_Fun&& __fun, _As&&... __as) { //
28         ((_Fun&&)__fun)((_As&&)__as...);    //
29     };
30 template <class _Fun, class... _As>
31 concept __nothrow_callable =    //
32     __callable<_Fun, _As...> && //
33     requires(_Fun&& __fun, _As&&... __as) {
34         {
35             ((_Fun&&)__fun)((_As&&)__as...)
36         } noexcept;
37     };
38 
39 //////////////////////////////////////////////////////////////////////////////////////////////////
40 template <class...>
41 struct __types;
42 
43 template <class... _Ts>
44 concept __typename = requires { typename __types<_Ts...>; };
45 
46 //////////////////////////////////////////////////////////////////////////////////////////////////
47 #if STDEXEC_CLANG()
48 
49 template <class _Ap, class _Bp>
50 concept __same_as = __is_same(_Ap, _Bp);
51 
52 #elif STDEXEC_GCC()
53 
54 template <class _Ap, class _Bp>
55 concept __same_as = __is_same_as(_Ap, _Bp);
56 
57 #else
58 
59 template <class _Ap, class _Bp>
60 inline constexpr bool __same_as_v = false;
61 
62 template <class _Ap>
63 inline constexpr bool __same_as_v<_Ap, _Ap> = true;
64 
65 template <class _Ap, class _Bp>
66 concept __same_as = __same_as_v<_Ap, _Bp>;
67 
68 #endif
69 
70 // Handy concepts
71 template <class _Ty, class _Up>
72 concept __decays_to = __same_as<__decay_t<_Ty>, _Up>;
73 
74 template <class _Ty, class _Up>
75 concept __not_decays_to = !__decays_to<_Ty, _Up>;
76 
77 template <bool _TrueOrFalse>
78 concept __satisfies = _TrueOrFalse;
79 
80 template <class...>
81 concept __true = true;
82 
83 template <class _Cp>
84 concept __class = __true<int _Cp::*> && (!__same_as<const _Cp, _Cp>);
85 
86 template <class _Ty, class... _As>
87 concept __one_of = (__same_as<_Ty, _As> || ...);
88 
89 template <class _Ty, class... _Us>
90 concept __all_of = (__same_as<_Ty, _Us> && ...);
91 
92 template <class _Ty, class... _Us>
93 concept __none_of = ((!__same_as<_Ty, _Us>)&&...);
94 
95 template <class, template <class...> class>
96 constexpr bool __is_instance_of_ = false;
97 template <class... _As, template <class...> class _Ty>
98 constexpr bool __is_instance_of_<_Ty<_As...>, _Ty> = true;
99 
100 template <class _Ay, template <class...> class _Ty>
101 concept __is_instance_of = __is_instance_of_<_Ay, _Ty>;
102 
103 template <class _Ay, template <class...> class _Ty>
104 concept __is_not_instance_of = !__is_instance_of<_Ay, _Ty>;
105 
106 } // namespace stdexec
107