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 "__concepts.hpp" 20 #include "__utility.hpp" 21 22 namespace stdexec { 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 STDEXEC_ATTRIBUTE(no_unique_address) _Fn __fn_; STDEXEC_ATTRIBUTEstdexec::__scope_guard30 STDEXEC_ATTRIBUTE(no_unique_address) __immovable __hidden_ { }; 31 bool __dismissed_{false}; 32 ~__scope_guardstdexec::__scope_guard33 ~__scope_guard() { 34 if (!__dismissed_) 35 static_cast<_Fn&&>(__fn_)(); 36 } 37 __dismissstdexec::__scope_guard38 void __dismiss() noexcept { 39 __dismissed_ = true; 40 } 41 }; 42 43 template <class _Fn, class _T0> 44 struct __scope_guard<_Fn, _T0> { 45 STDEXEC_ATTRIBUTE(no_unique_address) _Fn __fn_; 46 STDEXEC_ATTRIBUTE(no_unique_address) _T0 __t0_; STDEXEC_ATTRIBUTEstdexec::__scope_guard47 STDEXEC_ATTRIBUTE(no_unique_address) __immovable __hidden_ { }; 48 49 bool __dismissed_{false}; 50 __dismissstdexec::__scope_guard51 void __dismiss() noexcept { 52 __dismissed_ = true; 53 } 54 ~__scope_guardstdexec::__scope_guard55 ~__scope_guard() { 56 if (!__dismissed_) 57 static_cast<_Fn&&>(__fn_)(static_cast<_T0&&>(__t0_)); 58 } 59 }; 60 61 template <class _Fn, class _T0, class _T1> 62 struct __scope_guard<_Fn, _T0, _T1> { 63 STDEXEC_ATTRIBUTE(no_unique_address) _Fn __fn_; 64 STDEXEC_ATTRIBUTE(no_unique_address) _T0 __t0_; 65 STDEXEC_ATTRIBUTE(no_unique_address) _T1 __t1_; STDEXEC_ATTRIBUTEstdexec::__scope_guard66 STDEXEC_ATTRIBUTE(no_unique_address) __immovable __hidden_ { }; 67 68 bool __dismissed_{false}; 69 __dismissstdexec::__scope_guard70 void __dismiss() noexcept { 71 __dismissed_ = true; 72 } 73 ~__scope_guardstdexec::__scope_guard74 ~__scope_guard() { 75 if (!__dismissed_) 76 static_cast<_Fn&&>(__fn_)(static_cast<_T0&&>(__t0_), static_cast<_T1&&>(__t1_)); 77 } 78 }; 79 80 template <class _Fn, class _T0, class _T1, class _T2> 81 struct __scope_guard<_Fn, _T0, _T1, _T2> { 82 STDEXEC_ATTRIBUTE(no_unique_address) _Fn __fn_; 83 STDEXEC_ATTRIBUTE(no_unique_address) _T0 __t0_; 84 STDEXEC_ATTRIBUTE(no_unique_address) _T1 __t1_; 85 STDEXEC_ATTRIBUTE(no_unique_address) _T2 __t2_; STDEXEC_ATTRIBUTEstdexec::__scope_guard86 STDEXEC_ATTRIBUTE(no_unique_address) __immovable __hidden_ { }; 87 88 bool __dismissed_{false}; 89 __dismissstdexec::__scope_guard90 void __dismiss() noexcept { 91 __dismissed_ = true; 92 } 93 ~__scope_guardstdexec::__scope_guard94 ~__scope_guard() { 95 if (!__dismissed_) 96 static_cast<_Fn&&>( 97 __fn_)(static_cast<_T0&&>(__t0_), static_cast<_T1&&>(__t1_), static_cast<_T2&&>(__t2_)); 98 } 99 }; 100 101 template <class _Fn, class... _Ts> 102 __scope_guard(_Fn, _Ts...) -> __scope_guard<_Fn, _Ts...>; 103 } // namespace stdexec 104