xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__scope.hpp (revision 10d0b4b7d1498cfd5c3d37edea271a54d1984e41)
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