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 "__meta.hpp" 20 21 namespace stdexec 22 { 23 template <class _Fn, class... _Ts> 24 requires __nothrow_callable<_Fn, _Ts...> 25 struct __scope_guard; 26 27 template <class _Fn> 28 struct __scope_guard<_Fn> 29 { 30 STDEXEC_ATTRIBUTE((no_unique_address)) 31 _Fn __fn_; 32 STDEXEC_ATTRIBUTE((no_unique_address)) 33 __immovable __hidden_{}; 34 bool __dismissed_{false}; 35 ~__scope_guardstdexec::__scope_guard36 ~__scope_guard() 37 { 38 if (!__dismissed_) 39 static_cast<_Fn&&>(__fn_)(); 40 } 41 __dismissstdexec::__scope_guard42 void __dismiss() noexcept 43 { 44 __dismissed_ = true; 45 } 46 }; 47 48 template <class _Fn, class _T0> 49 struct __scope_guard<_Fn, _T0> 50 { 51 STDEXEC_ATTRIBUTE((no_unique_address)) 52 _Fn __fn_; 53 STDEXEC_ATTRIBUTE((no_unique_address)) 54 _T0 __t0_; 55 STDEXEC_ATTRIBUTE((no_unique_address)) 56 __immovable __hidden_{}; 57 58 bool __dismissed_{false}; 59 __dismissstdexec::__scope_guard60 void __dismiss() noexcept 61 { 62 __dismissed_ = true; 63 } 64 ~__scope_guardstdexec::__scope_guard65 ~__scope_guard() 66 { 67 if (!__dismissed_) 68 static_cast<_Fn&&>(__fn_)(static_cast<_T0&&>(__t0_)); 69 } 70 }; 71 72 template <class _Fn, class _T0, class _T1> 73 struct __scope_guard<_Fn, _T0, _T1> 74 { 75 STDEXEC_ATTRIBUTE((no_unique_address)) 76 _Fn __fn_; 77 STDEXEC_ATTRIBUTE((no_unique_address)) 78 _T0 __t0_; 79 STDEXEC_ATTRIBUTE((no_unique_address)) 80 _T1 __t1_; 81 STDEXEC_ATTRIBUTE((no_unique_address)) 82 __immovable __hidden_{}; 83 84 bool __dismissed_{false}; 85 __dismissstdexec::__scope_guard86 void __dismiss() noexcept 87 { 88 __dismissed_ = true; 89 } 90 ~__scope_guardstdexec::__scope_guard91 ~__scope_guard() 92 { 93 if (!__dismissed_) 94 static_cast<_Fn&&>( 95 __fn_)(static_cast<_T0&&>(__t0_), static_cast<_T1&&>(__t1_)); 96 } 97 }; 98 99 template <class _Fn, class _T0, class _T1, class _T2> 100 struct __scope_guard<_Fn, _T0, _T1, _T2> 101 { 102 STDEXEC_ATTRIBUTE((no_unique_address)) 103 _Fn __fn_; 104 STDEXEC_ATTRIBUTE((no_unique_address)) 105 _T0 __t0_; 106 STDEXEC_ATTRIBUTE((no_unique_address)) 107 _T1 __t1_; 108 STDEXEC_ATTRIBUTE((no_unique_address)) 109 _T2 __t2_; 110 STDEXEC_ATTRIBUTE((no_unique_address)) 111 __immovable __hidden_{}; 112 113 bool __dismissed_{false}; 114 __dismissstdexec::__scope_guard115 void __dismiss() noexcept 116 { 117 __dismissed_ = true; 118 } 119 ~__scope_guardstdexec::__scope_guard120 ~__scope_guard() 121 { 122 if (!__dismissed_) 123 static_cast<_Fn&&>( 124 __fn_)(static_cast<_T0&&>(__t0_), static_cast<_T1&&>(__t1_), 125 static_cast<_T2&&>(__t2_)); 126 } 127 }; 128 129 template <class _Fn, class... _Ts> 130 __scope_guard(_Fn, _Ts...) -> __scope_guard<_Fn, _Ts...>; 131 } // namespace stdexec 132