WG14 result
Loading...
Searching...
No Matches
result.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_RESULT_H
21#define WG14_RESULT_STATUS_CODE_RESULT_H
22
23#include "status_code_system.h"
24
25#ifdef __cplusplus
26extern "C"
27{
28#endif
29
30 // Identical to
31 // https://github.com/ned14/outcome/blob/develop/include/outcome/detail/value_storage.hpp
32 // As a result, it does contain some values peculiar to C++, however that then
33 // shows correctly in the debugger for results which came from C++. As
34 // described there, it has been found the painful way that spelling out every
35 // possible configuration of status bits is the least worst approach for
36 // codegen.
37 enum WG14_RESULT_PREFIX(result_status_flags)
38#if __STDC_VERSION__ >= 202000L
39 : uint16_t
40#endif
41 {
42 // WARNING: These bits are not tracked by abi-dumper, but changing them will
43 // break ABI! bits 0-5 in use.
44 WG14_RESULT_PREFIX(result_status_flag_none) = 0,
45
46 WG14_RESULT_PREFIX(result_status_flag_have_value) = (1U << 0U),
47 WG14_RESULT_PREFIX(result_status_flag_have_error) = (1U << 1U),
48 WG14_RESULT_PREFIX(result_status_flag_have_exception) = (2U << 1U),
49 WG14_RESULT_PREFIX(result_status_flag_have_error_exception) = (3U << 1U),
50
51 // failed to complete a strong swap
52 WG14_RESULT_PREFIX(result_status_flag_have_lost_consistency) = (1U << 3U),
53
55 (1U << 0U) | (1U << 3U),
57 (1U << 1U) | (1U << 3U),
59 (2U << 1U) | (1U << 3U),
60 WG14_RESULT_PREFIX(
62 (1U << 3U),
63
64 // can errno be set from this error?
65 WG14_RESULT_PREFIX(result_status_flag_have_error_is_errno) = (1U << 4U),
66
68 (1U << 1U) | (1U << 4U),
70 (3U << 1U) | (1U << 4U),
71
72 WG14_RESULT_PREFIX(
74 (1U << 1U) | (1U << 3U) | (1U << 4U),
75 WG14_RESULT_PREFIX(
77 (3U << 1U) | (1U << 3U) | (1U << 4U),
78
79 // value has been moved from
80 WG14_RESULT_PREFIX(result_status_flag_have_moved_from) = (1U << 5U),
81
82 WG14_RESULT_PREFIX(result_status_flag_have_value_moved_from) = (1U << 0U) |
83 (1U << 5U),
84 WG14_RESULT_PREFIX(result_status_flag_have_error_moved_from) = (1U << 1U) |
85 (1U << 5U),
87 (2U << 1U) | (1U << 5U),
89 (3U << 1U) | (1U << 5U),
90
91 WG14_RESULT_PREFIX(
93 (1U << 3U) |
94 (1U << 5U),
95 WG14_RESULT_PREFIX(
97 (1U << 3U) |
98 (1U << 5U),
99 WG14_RESULT_PREFIX(
101 (2U << 1U) | (1U << 3U) | (1U << 5U),
102 WG14_RESULT_PREFIX(
104 (3U << 1U) | (1U << 3U) | (1U << 5U),
105
107 (1U << 4U) | (1U << 5U),
108 WG14_RESULT_PREFIX(
110 (1U << 4U) |
111 (1U << 5U),
112 WG14_RESULT_PREFIX(
114 (3U << 1U) | (1U << 4U) | (1U << 5U),
115
116 WG14_RESULT_PREFIX(
118 (1U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
119 WG14_RESULT_PREFIX(
121 (3U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
122 };
123
125 union WG14_RESULT_PREFIX(result_flags)
126 {
127 // We use a union to provide backwards compatible ABI on C standards which
128 // don't support enums with underlying type other than int
129 enum WG14_RESULT_PREFIX(result_status_flags) status;
130 struct
131 {
132 uint16_t status_bits; // status above, low bits
133 uint16_t spare_storage_value; // spare storage sixteen bits, high bits
134 };
135 };
136#if __STDC_VERSION__ >= 201100L
137 _Static_assert(sizeof(union WG14_RESULT_PREFIX(result_flags)) ==
138 sizeof(uint32_t),
139 "result_flags is not the size it is supposed to be!");
140 _Static_assert(__alignof(union WG14_RESULT_PREFIX(result_flags)) ==
141 __alignof(uint32_t),
142 "result_flags does not have the alignment it is supposed to!");
143#endif
144
146 typedef struct WG14_RESULT_PREFIX(result_with_void)
147 {
148 union WG14_RESULT_PREFIX(result_flags) _flags_;
149 WG14_RESULT_PREFIX(status_code_system) error;
150 } WG14_RESULT_PREFIX(result_with_void);
151#if __STDC_VERSION__ >= 201100L
152 _Static_assert(sizeof(WG14_RESULT_PREFIX(result_with_void)) ==
153 3 * sizeof(void *),
154 "Result is not the size it is supposed to be!");
155 _Static_assert(__alignof(WG14_RESULT_PREFIX(result_with_void)) ==
156 __alignof(void *),
157 "Result does not have the alignment it is supposed to!");
158#endif
159
161 WG14_RESULT_INLINE struct WG14_RESULT_PREFIX(result_with_void)
162 WG14_RESULT_PREFIX(result_void_make_success)(void)
163 {
164 struct WG14_RESULT_PREFIX(result_with_void)
165 ret = {{WG14_RESULT_PREFIX(result_status_flag_have_value)},
166 WG14_RESULT_PREFIX(status_code_system_empty)};
167 return ret;
168 }
170 WG14_RESULT_INLINE struct WG14_RESULT_PREFIX(result_with_void)
171 WG14_RESULT_PREFIX(result_void_make_failure)(
172 WG14_RESULT_PREFIX(status_code_system) err)
173 {
174 struct WG14_RESULT_PREFIX(result_with_void)
175 ret = {{WG14_RESULT_PREFIX(result_status_flag_have_error)}, err};
176 return ret;
177 }
178
180#define WG14_RESULT_DECLARE(T, name) \
181 struct WG14_RESULT_PREFIX(result_with_##name) \
182 { \
183 T value; \
184 union WG14_RESULT_PREFIX(result_flags) _flags_; \
185 WG14_RESULT_PREFIX(status_code_system) error; \
186 }; \
187 WG14_RESULT_INLINE struct WG14_RESULT_PREFIX(result_with_##name) \
188 WG14_RESULT_PREFIX(result_##name##_make_success)(T val) \
189 { \
190 struct WG14_RESULT_PREFIX(result_with_##name) \
191 ret = {val, \
192 {WG14_RESULT_PREFIX(result_status_flag_have_value)}, \
193 WG14_RESULT_PREFIX(status_code_system_empty)}; \
194 return ret; \
195 } \
196 WG14_RESULT_INLINE struct WG14_RESULT_PREFIX(result_with_##name) \
197 WG14_RESULT_PREFIX(result_##name##_make_failure)( \
198 WG14_RESULT_PREFIX(status_code_system) err) \
199 { \
200 struct WG14_RESULT_PREFIX(result_with_##name) ret; \
201 memset(&ret, 0, sizeof(ret)); \
202 ret.error = err; \
203 ret._flags_.status = WG14_RESULT_PREFIX(result_status_flag_have_error); \
204 return ret; \
205 }
207#define WG14_RESULT(name) struct WG14_RESULT_PREFIX(result_with_##name)
209#define WG14_RESULT_MAKE_SUCCESS(name, ...) \
210 WG14_RESULT_PREFIX(result_##name##_make_success)(__VA_ARGS__)
212#define WG14_RESULT_MAKE_FAILURE(name, ...) \
213 WG14_RESULT_PREFIX(result_##name##_make_failure)(__VA_ARGS__)
215#define WG14_RESULT_HAS_VALUE(...) \
216 ((__VA_ARGS__)._flags_.status_bits & \
217 WG14_RESULT_PREFIX(result_status_flag_have_value))
219#define WG14_RESULT_HAS_ERROR(...) \
220 ((__VA_ARGS__)._flags_.status_bits & \
221 WG14_RESULT_PREFIX(result_status_flag_have_error))
222
223#ifdef __cplusplus
224}
225#endif
226
227#endif
#define WG14_RESULT_INLINE
Definition config.h:63
result_status_flags
Definition result.h:41
@ result_status_flag_have_error_exception_lost_consistency_error_is_errno
Definition result.h:76
@ result_status_flag_have_error_exception_error_is_errno
Definition result.h:69
@ result_status_flag_have_error_exception
Definition result.h:49
@ result_status_flag_have_value_lost_consistency
Definition result.h:54
@ result_status_flag_have_moved_from
Definition result.h:80
@ result_status_flag_have_error_error_is_errno
Definition result.h:67
@ result_status_flag_have_value
Definition result.h:46
@ result_status_flag_have_error_exception_moved_from
Definition result.h:88
@ result_status_flag_have_error_error_is_errno_moved_from
Definition result.h:109
@ result_status_flag_none
Definition result.h:44
@ result_status_flag_have_error_exception_lost_consistency_moved_from
Definition result.h:103
@ result_status_flag_have_error_is_errno
Definition result.h:65
@ result_status_flag_have_error_exception_lost_consistency_error_is_errno_moved_from
Definition result.h:120
@ result_status_flag_have_error_lost_consistency_moved_from
Definition result.h:96
@ result_status_flag_have_error_exception_error_is_errno_moved_from
Definition result.h:113
@ result_status_flag_have_lost_consistency
Definition result.h:52
@ result_status_flag_have_error_lost_consistency
Definition result.h:56
@ result_status_flag_have_exception_moved_from
Definition result.h:86
@ result_status_flag_have_value_moved_from
Definition result.h:82
@ result_status_flag_have_error_moved_from
Definition result.h:84
@ result_status_flag_have_value_lost_consistency_moved_from
Definition result.h:92
@ result_status_flag_have_exception_lost_consistency
Definition result.h:58
@ result_status_flag_have_error_is_errno_moved_from
Definition result.h:106
@ result_status_flag_have_error_lost_consistency_error_is_errno_moved_from
Definition result.h:117
@ result_status_flag_have_error_lost_consistency_error_is_errno
Definition result.h:73
@ result_status_flag_have_exception_lost_consistency_moved_from
Definition result.h:100
@ result_status_flag_have_error_exception_lost_consistency
Definition result.h:61
@ result_status_flag_have_exception
Definition result.h:48
@ result_status_flag_have_error
Definition result.h:47
A Result for type void.
Definition result.h:147
status_code_system error
Definition result.h:149
A status_code guaranteed to be able to hold any system error code in full. The payload is always an i...
The flags type within a Result.
Definition result.h:126
uint16_t status_bits
Definition result.h:132
enum result_status_flags status
Definition result.h:129
uint16_t spare_storage_value
Definition result.h:133