WG14 result
Loading...
Searching...
No Matches
try.h
Go to the documentation of this file.
1/* Proposed WG14 Result
2(C) 2024 - 2026 Niall Douglas <http://www.nedproductions.biz/>
3File Created: Nov 2025
4
5
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License in the accompanying file
9Licence.txt or at
10
11http://www.apache.org/licenses/LICENSE-2.0
12
13Unless required by applicable law or agreed to in writing, software
14distributed under the License is distributed on an "AS IS" BASIS,
15WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16See the License for the specific language governing permissions and
17limitations under the License.
18*/
19
20#ifndef WG14_RESULT_STATUS_CODE_TRY_H
21#define WG14_RESULT_STATUS_CODE_TRY_H
22
23#include "config.h"
24
25#ifdef __cplusplus
26extern "C"
27{
28#endif
29
30 /* You should ensure that this tracks closely
31 https://github.com/ned14/outcome/blob/develop/include/outcome/detail/try.h
32 in both directions!
33 */
34
35#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8
36#pragma GCC diagnostic push
37#pragma GCC diagnostic ignored "-Wparentheses"
38#endif
39
40#define OUTCOME_TRY_GLUE2(x, y) x##y
41#define OUTCOME_TRY_GLUE(x, y) OUTCOME_TRY_GLUE2(x, y)
42#define OUTCOME_TRY_UNIQUE_NAME \
43 OUTCOME_TRY_GLUE(_outcome_try_unique_name_temporary, __COUNTER__)
44
45#define OUTCOME_TRY_RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, \
46 count, ...) \
47 count
48#define OUTCOME_TRY_EXPAND_ARGS(args) OUTCOME_TRY_RETURN_ARG_COUNT args
49#define OUTCOME_TRY_COUNT_ARGS_MAX8(...) \
50 OUTCOME_TRY_EXPAND_ARGS((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0))
51#define OUTCOME_TRY_OVERLOAD_MACRO2(name, count) name##count
52#define OUTCOME_TRY_OVERLOAD_MACRO1(name, count) \
53 OUTCOME_TRY_OVERLOAD_MACRO2(name, count)
54#define OUTCOME_TRY_OVERLOAD_MACRO(name, count) \
55 OUTCOME_TRY_OVERLOAD_MACRO1(name, count)
56#define OUTCOME_TRY_OVERLOAD_GLUE(x, y) x y
57#define OUTCOME_TRY_CALL_OVERLOAD(name, ...) \
58 OUTCOME_TRY_OVERLOAD_GLUE( \
59 OUTCOME_TRY_OVERLOAD_MACRO(name, OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), \
60 (__VA_ARGS__))
61
62#define _OUTCOME_TRY_RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, \
63 count, ...) \
64 count
65#define _OUTCOME_TRY_EXPAND_ARGS(args) _OUTCOME_TRY_RETURN_ARG_COUNT args
66#define _OUTCOME_TRY_COUNT_ARGS_MAX8(...) \
67 _OUTCOME_TRY_EXPAND_ARGS((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0))
68#define _OUTCOME_TRY_OVERLOAD_MACRO2(name, count) name##count
69#define _OUTCOME_TRY_OVERLOAD_MACRO1(name, count) \
70 _OUTCOME_TRY_OVERLOAD_MACRO2(name, count)
71#define _OUTCOME_TRY_OVERLOAD_MACRO(name, count) \
72 _OUTCOME_TRY_OVERLOAD_MACRO1(name, count)
73#define _OUTCOME_TRY_OVERLOAD_GLUE(x, y) x y
74#define _OUTCOME_TRY_CALL_OVERLOAD(name, ...) \
75 _OUTCOME_TRY_OVERLOAD_GLUE(_OUTCOME_TRY_OVERLOAD_MACRO( \
76 name, _OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), \
77 (__VA_ARGS__))
78
79#if !defined(OUTCOME_TRY_LIKELY_IF) && defined(__has_cpp_attribute)
80#if __has_cpp_attribute(likely)
81#define OUTCOME_TRY_LIKELY_IF(...) if(__VA_ARGS__) [[likely]]
82#endif
83#endif
84#ifndef OUTCOME_TRY_LIKELY_IF
85#if defined(__clang__) || defined(__GNUC__)
86#define OUTCOME_TRY_LIKELY_IF(...) if(__builtin_expect(!!(__VA_ARGS__), 1))
87#else
88#define OUTCOME_TRY_LIKELY_IF(...) if(__VA_ARGS__)
89#endif
90#endif
91
92#ifdef __cplusplus
93#define OUTCOME_TRYV2_UNIQUE_STORAGE_AUTO(...) auto
94#else
95#define OUTCOME_TRYV2_UNIQUE_STORAGE_AUTO(...) __typeof__(__VA_ARGS__)
96#endif
97
98#define OUTCOME_TRYV2_UNIQUE_STORAGE_UNPACK(...) __VA_ARGS__
99#define OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE3(unique, ...) \
100 OUTCOME_TRYV2_UNIQUE_STORAGE_AUTO(__VA_ARGS__) unique = (__VA_ARGS__)
101#define OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE2(x) x
102#define OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE(unique, x, ...) \
103 OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE2( \
104 OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE3(unique, __VA_ARGS__))
105#define OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED3(unique, x, y, ...) \
106 x unique = (__VA_ARGS__)
107#define OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED2(x) x
108#define OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED(unique, ...) \
109 OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED2( \
110 OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED3(unique, __VA_ARGS__))
111#define OUTCOME_TRYV2_UNIQUE_STORAGE1(...) OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE
112#define OUTCOME_TRYV2_UNIQUE_STORAGE2(...) \
113 OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED
114#define OUTCOME_TRYV2_UNIQUE_STORAGE(unique, spec, ...) \
115 _OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRYV2_UNIQUE_STORAGE, \
116 OUTCOME_TRYV2_UNIQUE_STORAGE_UNPACK spec) \
117 (unique, OUTCOME_TRYV2_UNIQUE_STORAGE_UNPACK spec, __VA_ARGS__)
118
119#define OUTCOME_TRY2_VAR_SECOND2(x, var) var
120#define OUTCOME_TRY2_VAR_SECOND3(x, y, ...) x y
121#define OUTCOME_TRY2_VAR(spec) \
122 _OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY2_VAR_SECOND, \
123 OUTCOME_TRYV2_UNIQUE_STORAGE_UNPACK spec, spec)
124
125#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8
126#pragma GCC diagnostic pop
127#endif
128
129
130 /* You should ensure that this tracks closely
131 https://github.com/ned14/outcome/blob/develop/include/outcome/experimental/result.h
132 in both directions!
133 */
134
135#define WG14_RESULT_TRY_IMPLV(unique, retstmt, cleanup, spec, ...) \
136 OUTCOME_TRYV2_UNIQUE_STORAGE(unique, spec, __VA_ARGS__); \
137 OUTCOME_TRY_LIKELY_IF(WG14_RESULT_HAS_VALUE(unique)); \
138 else \
139 { \
140 cleanup; \
141 retstmt; \
142 }
143#define WG14_RESULT_TRY_IMPLA(unique, retstmt, cleanup, var, ...) \
144 WG14_RESULT_TRY_IMPLV(unique, retstmt, cleanup, var, __VA_ARGS__) \
145 OUTCOME_TRY2_VAR(var) = unique.value
146
147#define WG14_RESULT_TRY_IMPL_RETURN(unique, ident) \
148 WG14_RESULT(ident) unique##_f; \
149 unique##_f._flags_ = (unique)._flags_; \
150 unique##_f.error = (unique).error; \
151 return unique##_f
152
153#define WG14_RESULT_TRY_WITH_SPEC_AND_CLEANUP_AND_NEW_RETURN_TYPE( \
154unique, spec, ident, cleanup, ...) \
155 WG14_RESULT_TRY_IMPLA(unique, WG14_RESULT_TRY_IMPL_RETURN(unique, ident), \
156 cleanup, spec, __VA_ARGS__)
157#define WG14_RESULT_TRY_WITH_SPEC_AND_CLEANUP(unique, spec, cleanup, ...) \
158 WG14_RESULT_TRY_IMPLA(unique, return unique, cleanup, spec, __VA_ARGS__)
159#define WG14_RESULT_TRY_WITH_CLEANUP(unique, cleanup, ...) \
160 WG14_RESULT_TRY_IMPLV(unique, return unique, cleanup, deduce, __VA_ARGS__)
161#define WG14_RESULT_TRY_SAME_RETURN_TYPE(unique, ...) \
162 WG14_RESULT_TRY_IMPLV(unique, return unique, , deduce, __VA_ARGS__)
163
164#define WG14_RESULT_TRY_INVOKE_TRY8(a, b, c, d, e, f, g, h) \
165 WG14_RESULT_TRY_WITH_SPEC_AND_CLEANUP_AND_NEW_RETURN_TYPE( \
166 OUTCOME_TRY_UNIQUE_NAME, a, b, c, d, e, f, g, h)
167#define WG14_RESULT_TRY_INVOKE_TRY7(a, b, c, d, e, f, g) \
168 WG14_RESULT_TRY_WITH_SPEC_AND_CLEANUP_AND_NEW_RETURN_TYPE( \
169 OUTCOME_TRY_UNIQUE_NAME, a, b, c, d, e, f, g)
170#define WG14_RESULT_TRY_INVOKE_TRY6(a, b, c, d, e, f) \
171 WG14_RESULT_TRY_WITH_SPEC_AND_CLEANUP_AND_NEW_RETURN_TYPE( \
172 OUTCOME_TRY_UNIQUE_NAME, a, b, c, d, e, f)
173#define WG14_RESULT_TRY_INVOKE_TRY5(a, b, c, d, e) \
174 WG14_RESULT_TRY_WITH_SPEC_AND_CLEANUP_AND_NEW_RETURN_TYPE( \
175 OUTCOME_TRY_UNIQUE_NAME, a, b, c, d, e)
176#define WG14_RESULT_TRY_INVOKE_TRY4(a, b, c, d) \
177 WG14_RESULT_TRY_WITH_SPEC_AND_CLEANUP_AND_NEW_RETURN_TYPE( \
178 OUTCOME_TRY_UNIQUE_NAME, a, b, c, d)
179#define WG14_RESULT_TRY_INVOKE_TRY3(a, b, c) \
180 WG14_RESULT_TRY_WITH_SPEC_AND_CLEANUP(OUTCOME_TRY_UNIQUE_NAME, a, b, c)
181#define WG14_RESULT_TRY_INVOKE_TRY2(a, b) \
182 WG14_RESULT_TRY_WITH_CLEANUP(OUTCOME_TRY_UNIQUE_NAME, a, b)
183#define WG14_RESULT_TRY_INVOKE_TRY1(expr) \
184 WG14_RESULT_TRY_SAME_RETURN_TYPE(OUTCOME_TRY_UNIQUE_NAME, expr)
185
186#define WG14_RESULT_TRY(...) \
187 OUTCOME_TRY_CALL_OVERLOAD(WG14_RESULT_TRY_INVOKE_TRY, __VA_ARGS__)
188
189
190#ifdef __cplusplus
191}
192#endif
193
194#endif