]>
Commit | Line | Data |
---|---|---|
92f5a8d4 | 1 | /* Proposed SG14 status_code |
20effc67 | 2 | (C) 2018 - 2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits) |
92f5a8d4 TL |
3 | File Created: Feb 2018 |
4 | ||
5 | ||
6 | Licensed under the Apache License, Version 2.0 (the "License"); | |
7 | you may not use this file except in compliance with the License. | |
8 | You may obtain a copy of the License in the accompanying file | |
9 | Licence.txt or at | |
10 | ||
11 | http://www.apache.org/licenses/LICENSE-2.0 | |
12 | ||
13 | Unless required by applicable law or agreed to in writing, software | |
14 | distributed under the License is distributed on an "AS IS" BASIS, | |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
16 | See the License for the specific language governing permissions and | |
17 | limitations under the License. | |
18 | ||
19 | ||
20 | Distributed under the Boost Software License, Version 1.0. | |
21 | (See accompanying file Licence.txt or copy at | |
22 | http://www.boost.org/LICENSE_1_0.txt) | |
23 | */ | |
24 | ||
25 | #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_GENERIC_CODE_HPP | |
26 | #define BOOST_OUTCOME_SYSTEM_ERROR2_GENERIC_CODE_HPP | |
27 | ||
28 | #include "status_error.hpp" | |
29 | ||
30 | #include <cerrno> // for error constants | |
31 | ||
32 | BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN | |
33 | ||
34 | //! The generic error coding (POSIX) | |
35 | enum class errc : int | |
36 | { | |
37 | success = 0, | |
38 | unknown = -1, | |
39 | ||
40 | address_family_not_supported = EAFNOSUPPORT, | |
41 | address_in_use = EADDRINUSE, | |
42 | address_not_available = EADDRNOTAVAIL, | |
43 | already_connected = EISCONN, | |
44 | argument_list_too_long = E2BIG, | |
45 | argument_out_of_domain = EDOM, | |
46 | bad_address = EFAULT, | |
47 | bad_file_descriptor = EBADF, | |
48 | bad_message = EBADMSG, | |
49 | broken_pipe = EPIPE, | |
50 | connection_aborted = ECONNABORTED, | |
51 | connection_already_in_progress = EALREADY, | |
52 | connection_refused = ECONNREFUSED, | |
53 | connection_reset = ECONNRESET, | |
54 | cross_device_link = EXDEV, | |
55 | destination_address_required = EDESTADDRREQ, | |
56 | device_or_resource_busy = EBUSY, | |
57 | directory_not_empty = ENOTEMPTY, | |
58 | executable_format_error = ENOEXEC, | |
59 | file_exists = EEXIST, | |
60 | file_too_large = EFBIG, | |
61 | filename_too_long = ENAMETOOLONG, | |
62 | function_not_supported = ENOSYS, | |
63 | host_unreachable = EHOSTUNREACH, | |
64 | identifier_removed = EIDRM, | |
65 | illegal_byte_sequence = EILSEQ, | |
66 | inappropriate_io_control_operation = ENOTTY, | |
67 | interrupted = EINTR, | |
68 | invalid_argument = EINVAL, | |
69 | invalid_seek = ESPIPE, | |
70 | io_error = EIO, | |
71 | is_a_directory = EISDIR, | |
72 | message_size = EMSGSIZE, | |
73 | network_down = ENETDOWN, | |
74 | network_reset = ENETRESET, | |
75 | network_unreachable = ENETUNREACH, | |
76 | no_buffer_space = ENOBUFS, | |
77 | no_child_process = ECHILD, | |
78 | no_link = ENOLINK, | |
79 | no_lock_available = ENOLCK, | |
80 | no_message = ENOMSG, | |
81 | no_protocol_option = ENOPROTOOPT, | |
82 | no_space_on_device = ENOSPC, | |
83 | no_stream_resources = ENOSR, | |
84 | no_such_device_or_address = ENXIO, | |
85 | no_such_device = ENODEV, | |
86 | no_such_file_or_directory = ENOENT, | |
87 | no_such_process = ESRCH, | |
88 | not_a_directory = ENOTDIR, | |
89 | not_a_socket = ENOTSOCK, | |
90 | not_a_stream = ENOSTR, | |
91 | not_connected = ENOTCONN, | |
92 | not_enough_memory = ENOMEM, | |
93 | not_supported = ENOTSUP, | |
94 | operation_canceled = ECANCELED, | |
95 | operation_in_progress = EINPROGRESS, | |
96 | operation_not_permitted = EPERM, | |
97 | operation_not_supported = EOPNOTSUPP, | |
98 | operation_would_block = EWOULDBLOCK, | |
99 | owner_dead = EOWNERDEAD, | |
100 | permission_denied = EACCES, | |
f67539c2 | 101 | protocol_error = EPROTO, |
92f5a8d4 TL |
102 | protocol_not_supported = EPROTONOSUPPORT, |
103 | read_only_file_system = EROFS, | |
104 | resource_deadlock_would_occur = EDEADLK, | |
105 | resource_unavailable_try_again = EAGAIN, | |
106 | result_out_of_range = ERANGE, | |
107 | state_not_recoverable = ENOTRECOVERABLE, | |
108 | stream_timeout = ETIME, | |
109 | text_file_busy = ETXTBSY, | |
110 | timed_out = ETIMEDOUT, | |
111 | too_many_files_open_in_system = ENFILE, | |
112 | too_many_files_open = EMFILE, | |
113 | too_many_links = EMLINK, | |
114 | too_many_symbolic_link_levels = ELOOP, | |
115 | value_too_large = EOVERFLOW, | |
116 | wrong_protocol_type = EPROTOTYPE | |
117 | }; | |
118 | ||
119 | namespace detail | |
120 | { | |
121 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline const char *generic_code_message(errc code) noexcept | |
122 | { | |
123 | switch(code) | |
124 | { | |
125 | case errc::success: | |
126 | return "Success"; | |
127 | case errc::address_family_not_supported: | |
128 | return "Address family not supported by protocol"; | |
129 | case errc::address_in_use: | |
130 | return "Address already in use"; | |
131 | case errc::address_not_available: | |
132 | return "Cannot assign requested address"; | |
133 | case errc::already_connected: | |
134 | return "Transport endpoint is already connected"; | |
135 | case errc::argument_list_too_long: | |
136 | return "Argument list too long"; | |
137 | case errc::argument_out_of_domain: | |
138 | return "Numerical argument out of domain"; | |
139 | case errc::bad_address: | |
140 | return "Bad address"; | |
141 | case errc::bad_file_descriptor: | |
142 | return "Bad file descriptor"; | |
143 | case errc::bad_message: | |
144 | return "Bad message"; | |
145 | case errc::broken_pipe: | |
146 | return "Broken pipe"; | |
147 | case errc::connection_aborted: | |
148 | return "Software caused connection abort"; | |
149 | case errc::connection_already_in_progress: | |
150 | return "Operation already in progress"; | |
151 | case errc::connection_refused: | |
152 | return "Connection refused"; | |
153 | case errc::connection_reset: | |
154 | return "Connection reset by peer"; | |
155 | case errc::cross_device_link: | |
156 | return "Invalid cross-device link"; | |
157 | case errc::destination_address_required: | |
158 | return "Destination address required"; | |
159 | case errc::device_or_resource_busy: | |
160 | return "Device or resource busy"; | |
161 | case errc::directory_not_empty: | |
162 | return "Directory not empty"; | |
163 | case errc::executable_format_error: | |
164 | return "Exec format error"; | |
165 | case errc::file_exists: | |
166 | return "File exists"; | |
167 | case errc::file_too_large: | |
168 | return "File too large"; | |
169 | case errc::filename_too_long: | |
170 | return "File name too long"; | |
171 | case errc::function_not_supported: | |
172 | return "Function not implemented"; | |
173 | case errc::host_unreachable: | |
174 | return "No route to host"; | |
175 | case errc::identifier_removed: | |
176 | return "Identifier removed"; | |
177 | case errc::illegal_byte_sequence: | |
178 | return "Invalid or incomplete multibyte or wide character"; | |
179 | case errc::inappropriate_io_control_operation: | |
180 | return "Inappropriate ioctl for device"; | |
181 | case errc::interrupted: | |
182 | return "Interrupted system call"; | |
183 | case errc::invalid_argument: | |
184 | return "Invalid argument"; | |
185 | case errc::invalid_seek: | |
186 | return "Illegal seek"; | |
187 | case errc::io_error: | |
188 | return "Input/output error"; | |
189 | case errc::is_a_directory: | |
190 | return "Is a directory"; | |
191 | case errc::message_size: | |
192 | return "Message too long"; | |
193 | case errc::network_down: | |
194 | return "Network is down"; | |
195 | case errc::network_reset: | |
196 | return "Network dropped connection on reset"; | |
197 | case errc::network_unreachable: | |
198 | return "Network is unreachable"; | |
199 | case errc::no_buffer_space: | |
200 | return "No buffer space available"; | |
201 | case errc::no_child_process: | |
202 | return "No child processes"; | |
203 | case errc::no_link: | |
204 | return "Link has been severed"; | |
205 | case errc::no_lock_available: | |
206 | return "No locks available"; | |
207 | case errc::no_message: | |
208 | return "No message of desired type"; | |
209 | case errc::no_protocol_option: | |
210 | return "Protocol not available"; | |
211 | case errc::no_space_on_device: | |
212 | return "No space left on device"; | |
213 | case errc::no_stream_resources: | |
214 | return "Out of streams resources"; | |
215 | case errc::no_such_device_or_address: | |
216 | return "No such device or address"; | |
217 | case errc::no_such_device: | |
218 | return "No such device"; | |
219 | case errc::no_such_file_or_directory: | |
220 | return "No such file or directory"; | |
221 | case errc::no_such_process: | |
222 | return "No such process"; | |
223 | case errc::not_a_directory: | |
224 | return "Not a directory"; | |
225 | case errc::not_a_socket: | |
226 | return "Socket operation on non-socket"; | |
227 | case errc::not_a_stream: | |
228 | return "Device not a stream"; | |
229 | case errc::not_connected: | |
230 | return "Transport endpoint is not connected"; | |
231 | case errc::not_enough_memory: | |
232 | return "Cannot allocate memory"; | |
233 | #if ENOTSUP != EOPNOTSUPP | |
234 | case errc::not_supported: | |
235 | return "Operation not supported"; | |
236 | #endif | |
237 | case errc::operation_canceled: | |
238 | return "Operation canceled"; | |
239 | case errc::operation_in_progress: | |
240 | return "Operation now in progress"; | |
241 | case errc::operation_not_permitted: | |
242 | return "Operation not permitted"; | |
243 | case errc::operation_not_supported: | |
244 | return "Operation not supported"; | |
245 | #if EAGAIN != EWOULDBLOCK | |
246 | case errc::operation_would_block: | |
247 | return "Resource temporarily unavailable"; | |
248 | #endif | |
249 | case errc::owner_dead: | |
250 | return "Owner died"; | |
251 | case errc::permission_denied: | |
252 | return "Permission denied"; | |
f67539c2 | 253 | case errc::protocol_error: |
92f5a8d4 TL |
254 | return "Protocol error"; |
255 | case errc::protocol_not_supported: | |
256 | return "Protocol not supported"; | |
257 | case errc::read_only_file_system: | |
258 | return "Read-only file system"; | |
259 | case errc::resource_deadlock_would_occur: | |
260 | return "Resource deadlock avoided"; | |
261 | case errc::resource_unavailable_try_again: | |
262 | return "Resource temporarily unavailable"; | |
263 | case errc::result_out_of_range: | |
264 | return "Numerical result out of range"; | |
265 | case errc::state_not_recoverable: | |
266 | return "State not recoverable"; | |
267 | case errc::stream_timeout: | |
268 | return "Timer expired"; | |
269 | case errc::text_file_busy: | |
270 | return "Text file busy"; | |
271 | case errc::timed_out: | |
272 | return "Connection timed out"; | |
273 | case errc::too_many_files_open_in_system: | |
274 | return "Too many open files in system"; | |
275 | case errc::too_many_files_open: | |
276 | return "Too many open files"; | |
277 | case errc::too_many_links: | |
278 | return "Too many links"; | |
279 | case errc::too_many_symbolic_link_levels: | |
280 | return "Too many levels of symbolic links"; | |
281 | case errc::value_too_large: | |
282 | return "Value too large for defined data type"; | |
283 | case errc::wrong_protocol_type: | |
284 | return "Protocol wrong type for socket"; | |
285 | default: | |
286 | return "unknown"; | |
287 | } | |
288 | } | |
289 | } // namespace detail | |
290 | ||
291 | /*! The implementation of the domain for generic status codes, those mapped by `errc` (POSIX). | |
292 | */ | |
293 | class _generic_code_domain : public status_code_domain | |
294 | { | |
295 | template <class> friend class status_code; | |
296 | template <class StatusCode> friend class detail::indirecting_domain; | |
297 | using _base = status_code_domain; | |
298 | ||
299 | public: | |
300 | //! The value type of the generic code, which is an `errc` as per POSIX. | |
301 | using value_type = errc; | |
302 | using string_ref = _base::string_ref; | |
303 | ||
304 | public: | |
305 | //! Default constructor | |
20effc67 TL |
306 | constexpr explicit _generic_code_domain(typename _base::unique_id_type id = 0x746d6354f4f733e9) noexcept |
307 | : _base(id) | |
308 | { | |
309 | } | |
92f5a8d4 TL |
310 | _generic_code_domain(const _generic_code_domain &) = default; |
311 | _generic_code_domain(_generic_code_domain &&) = default; | |
312 | _generic_code_domain &operator=(const _generic_code_domain &) = default; | |
313 | _generic_code_domain &operator=(_generic_code_domain &&) = default; | |
314 | ~_generic_code_domain() = default; | |
315 | ||
316 | //! Constexpr singleton getter. Returns the constexpr generic_code_domain variable. | |
317 | static inline constexpr const _generic_code_domain &get(); | |
318 | ||
319 | virtual _base::string_ref name() const noexcept override { return string_ref("generic domain"); } // NOLINT | |
320 | protected: | |
321 | virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT | |
322 | { | |
323 | assert(code.domain() == *this); // NOLINT | |
324 | return static_cast<const generic_code &>(code).value() != errc::success; // NOLINT | |
325 | } | |
326 | virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT | |
327 | { | |
328 | assert(code1.domain() == *this); // NOLINT | |
329 | const auto &c1 = static_cast<const generic_code &>(code1); // NOLINT | |
330 | if(code2.domain() == *this) | |
331 | { | |
332 | const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT | |
333 | return c1.value() == c2.value(); | |
334 | } | |
335 | return false; | |
336 | } | |
337 | virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT | |
338 | { | |
339 | assert(code.domain() == *this); // NOLINT | |
340 | return static_cast<const generic_code &>(code); // NOLINT | |
341 | } | |
342 | virtual _base::string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT | |
343 | { | |
344 | assert(code.domain() == *this); // NOLINT | |
345 | const auto &c = static_cast<const generic_code &>(code); // NOLINT | |
346 | return string_ref(detail::generic_code_message(c.value())); | |
347 | } | |
348 | #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) | |
349 | BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT | |
350 | { | |
351 | assert(code.domain() == *this); // NOLINT | |
352 | const auto &c = static_cast<const generic_code &>(code); // NOLINT | |
353 | throw status_error<_generic_code_domain>(c); | |
354 | } | |
355 | #endif | |
356 | }; | |
357 | //! A specialisation of `status_error` for the generic code domain. | |
358 | using generic_error = status_error<_generic_code_domain>; | |
359 | //! A constexpr source variable for the generic code domain, which is that of `errc` (POSIX). Returned by `_generic_code_domain::get()`. | |
360 | constexpr _generic_code_domain generic_code_domain; | |
361 | inline constexpr const _generic_code_domain &_generic_code_domain::get() | |
362 | { | |
363 | return generic_code_domain; | |
364 | } | |
365 | // Enable implicit construction of generic_code from errc | |
366 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline generic_code make_status_code(errc c) noexcept | |
367 | { | |
368 | return generic_code(in_place, c); | |
369 | } | |
370 | ||
371 | ||
372 | /*************************************************************************************************************/ | |
373 | ||
374 | ||
1e59de90 | 375 | template <class T> inline BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 bool status_code<void>::equivalent(const status_code<T> &o) const noexcept |
92f5a8d4 TL |
376 | { |
377 | if(_domain && o._domain) | |
378 | { | |
379 | if(_domain->_do_equivalent(*this, o)) | |
380 | { | |
381 | return true; | |
382 | } | |
383 | if(o._domain->_do_equivalent(o, *this)) | |
384 | { | |
385 | return true; | |
386 | } | |
387 | generic_code c1 = o._domain->_generic_code(o); | |
388 | if(c1.value() != errc::unknown && _domain->_do_equivalent(*this, c1)) | |
389 | { | |
390 | return true; | |
391 | } | |
392 | generic_code c2 = _domain->_generic_code(*this); | |
393 | if(c2.value() != errc::unknown && o._domain->_do_equivalent(o, c2)) | |
394 | { | |
395 | return true; | |
396 | } | |
397 | } | |
398 | // If we are both empty, we are equivalent, otherwise not equivalent | |
399 | return (!_domain && !o._domain); | |
400 | } | |
401 | //! True if the status code's are semantically equal via `equivalent()`. | |
1e59de90 | 402 | template <class DomainType1, class DomainType2> BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept |
92f5a8d4 TL |
403 | { |
404 | return a.equivalent(b); | |
405 | } | |
406 | //! True if the status code's are not semantically equal via `equivalent()`. | |
1e59de90 | 407 | template <class DomainType1, class DomainType2> BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept |
92f5a8d4 TL |
408 | { |
409 | return !a.equivalent(b); | |
410 | } | |
411 | //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. | |
1e59de90 TL |
412 | BOOST_OUTCOME_SYSTEM_ERROR2_TEMPLATE(class DomainType1, class T, // |
413 | class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found | |
414 | BOOST_OUTCOME_SYSTEM_ERROR2_TREQUIRES(BOOST_OUTCOME_SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code | |
415 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const T &b) | |
92f5a8d4 TL |
416 | { |
417 | return a.equivalent(make_status_code(b)); | |
418 | } | |
419 | //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. | |
1e59de90 TL |
420 | BOOST_OUTCOME_SYSTEM_ERROR2_TEMPLATE(class T, class DomainType1, // |
421 | class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found | |
422 | BOOST_OUTCOME_SYSTEM_ERROR2_TREQUIRES(BOOST_OUTCOME_SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code | |
423 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const T &a, const status_code<DomainType1> &b) | |
92f5a8d4 TL |
424 | { |
425 | return b.equivalent(make_status_code(a)); | |
426 | } | |
427 | //! True if the status code's are not semantically equal via `equivalent()` to `make_status_code(T)`. | |
1e59de90 TL |
428 | BOOST_OUTCOME_SYSTEM_ERROR2_TEMPLATE(class DomainType1, class T, // |
429 | class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found | |
430 | BOOST_OUTCOME_SYSTEM_ERROR2_TREQUIRES(BOOST_OUTCOME_SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code | |
431 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const T &b) | |
92f5a8d4 TL |
432 | { |
433 | return !a.equivalent(make_status_code(b)); | |
434 | } | |
435 | //! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`. | |
1e59de90 TL |
436 | BOOST_OUTCOME_SYSTEM_ERROR2_TEMPLATE(class T, class DomainType1, // |
437 | class MakeStatusCodeResult = typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found | |
438 | BOOST_OUTCOME_SYSTEM_ERROR2_TREQUIRES(BOOST_OUTCOME_SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code | |
439 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const T &a, const status_code<DomainType1> &b) | |
92f5a8d4 TL |
440 | { |
441 | return !b.equivalent(make_status_code(a)); | |
442 | } | |
20effc67 TL |
443 | //! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`. |
444 | template <class DomainType1, class T, // | |
445 | class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated | |
446 | > | |
1e59de90 | 447 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const T &b) |
20effc67 TL |
448 | { |
449 | return a.equivalent(QuickStatusCodeType(b)); | |
450 | } | |
451 | //! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`. | |
452 | template <class T, class DomainType1, // | |
453 | class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated | |
454 | > | |
1e59de90 | 455 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const T &a, const status_code<DomainType1> &b) |
20effc67 TL |
456 | { |
457 | return b.equivalent(QuickStatusCodeType(a)); | |
458 | } | |
459 | //! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`. | |
460 | template <class DomainType1, class T, // | |
461 | class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated | |
462 | > | |
1e59de90 | 463 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const T &b) |
20effc67 TL |
464 | { |
465 | return !a.equivalent(QuickStatusCodeType(b)); | |
466 | } | |
467 | //! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`. | |
468 | template <class T, class DomainType1, // | |
469 | class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated | |
470 | > | |
1e59de90 | 471 | BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const T &a, const status_code<DomainType1> &b) |
20effc67 TL |
472 | { |
473 | return !b.equivalent(QuickStatusCodeType(a)); | |
474 | } | |
475 | ||
92f5a8d4 TL |
476 | |
477 | BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END | |
478 | ||
479 | #endif |