2
0
mirror of https://github.com/boostorg/outcome.git synced 2026-01-19 04:22:13 +00:00

Bug fix: The status enumeration used to track state internally did

not list all possible enum values. This caused static analysers to complain.
This commit is contained in:
Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)
2024-08-14 18:00:39 +01:00
parent 60147ab314
commit 6cf2d4345a
6 changed files with 326 additions and 771 deletions

View File

@@ -18,6 +18,9 @@ with display of `strerror()` if the code domain is POSIX or generic.
### Bug fixes:
- The `status` enumeration used to track state internally did not list all possible enum
values. This caused static analysers to complain.
---
## v2.2.9 15th April 2024 (Boost 1.85) [[release]](https://github.com/ned14/outcome/releases/tag/v2.2.9)

View File

@@ -22,6 +22,6 @@ Distributed under the Boost Software License, Version 1.0.
*/
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define OUTCOME_PREVIOUS_COMMIT_REF f5a45b6909e732174fe98e59548914bcaa67d847
#define OUTCOME_PREVIOUS_COMMIT_DATE "2024-06-21 11:40:22 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE f5a45b69
#define OUTCOME_PREVIOUS_COMMIT_REF 60147ab3146f0418b10a6a4671ea0802cb514432
#define OUTCOME_PREVIOUS_COMMIT_DATE "2024-08-14 16:41:50 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 60147ab3

View File

@@ -248,10 +248,10 @@ namespace detail
to change the value to one of the enum's values. This is stupid to look at in source code,
but it make clang's optimiser do the right thing, so it's worth it.
*/
#define OUTCOME_USE_CONSTEXPR_ENUM_STATUS 0
enum class status : uint16_t
{
// WARNING: These bits are not tracked by abi-dumper, but changing them will break ABI!
// bits 0-5 in use.
none = 0,
have_value = (1U << 0U),
@@ -261,6 +261,7 @@ namespace detail
// failed to complete a strong swap
have_lost_consistency = (1U << 3U),
have_value_lost_consistency = (1U << 0U) | (1U << 3U),
have_error_lost_consistency = (1U << 1U) | (1U << 3U),
have_exception_lost_consistency = (2U << 1U) | (1U << 3U),
@@ -268,6 +269,7 @@ namespace detail
// can errno be set from this error?
have_error_is_errno = (1U << 4U),
have_error_error_is_errno = (1U << 1U) | (1U << 4U),
have_error_exception_error_is_errno = (3U << 1U) | (1U << 4U),
@@ -275,7 +277,24 @@ namespace detail
have_error_exception_lost_consistency_error_is_errno = (3U << 1U) | (1U << 3U) | (1U << 4U),
// value has been moved from
have_moved_from = (1U << 5U)
have_moved_from = (1U << 5U),
have_value_moved_from = (1U << 0U) | (1U << 5U),
have_error_moved_from = (1U << 1U) | (1U << 5U),
have_exception_moved_from = (2U << 1U) | (1U << 5U),
have_error_exception_moved_from = (3U << 1U) | (1U << 5U),
have_value_lost_consistency_moved_from = (1U << 0U) | (1U << 3U) | (1U << 5U),
have_error_lost_consistency_moved_from = (1U << 1U) | (1U << 3U) | (1U << 5U),
have_exception_lost_consistency_moved_from = (2U << 1U) | (1U << 3U) | (1U << 5U),
have_error_exception_lost_consistency_moved_from = (3U << 1U) | (1U << 3U) | (1U << 5U),
have_error_is_errno_moved_from = (1U << 4U) | (1U << 5U),
have_error_error_is_errno_moved_from = (1U << 1U) | (1U << 4U) | (1U << 5U),
have_error_exception_error_is_errno_moved_from = (3U << 1U) | (1U << 4U) | (1U << 5U),
have_error_lost_consistency_error_is_errno_moved_from = (1U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
have_error_exception_lost_consistency_error_is_errno_moved_from = (3U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
};
struct status_bitfield_type
{
@@ -298,523 +317,53 @@ namespace detail
constexpr status_bitfield_type &operator=(status_bitfield_type &&) = default;
//~status_bitfield_type() = default; // Do NOT uncomment this, it breaks older clangs!
constexpr bool have_value() const noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
return (status_value == status::have_value) //
|| (status_value == status::have_value_lost_consistency) //
;
#else
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0;
#endif
}
constexpr bool have_error() const noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
return (status_value == status::have_error) //
|| (status_value == status::have_error_exception) //
|| (status_value == status::have_error_lost_consistency) //
|| (status_value == status::have_error_exception_lost_consistency) //
|| (status_value == status::have_error_error_is_errno) //
|| (status_value == status::have_error_exception_error_is_errno) //
|| (status_value == status::have_error_lost_consistency_error_is_errno) //
|| (status_value == status::have_error_exception_lost_consistency_error_is_errno) //
;
#else
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0;
#endif
}
constexpr bool have_exception() const noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
return (status_value == status::have_exception) //
|| (status_value == status::have_error_exception) //
|| (status_value == status::have_exception_lost_consistency) //
|| (status_value == status::have_error_exception_lost_consistency) //
|| (status_value == status::have_error_exception_error_is_errno) //
|| (status_value == status::have_error_exception_lost_consistency_error_is_errno) //
;
#else
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0;
#endif
}
constexpr bool have_value() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0; }
constexpr bool have_error() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0; }
constexpr bool have_exception() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0; }
constexpr bool have_lost_consistency() const noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
return (status_value == status::have_value_lost_consistency) //
|| (status_value == status::have_error_lost_consistency) //
|| (status_value == status::have_exception_lost_consistency) //
|| (status_value == status::have_error_lost_consistency_error_is_errno) //
|| (status_value == status::have_error_exception_lost_consistency_error_is_errno) //
;
#else
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_lost_consistency)) != 0;
#endif
}
constexpr bool have_error_is_errno() const noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
return (status_value == status::have_error_error_is_errno) //
|| (status_value == status::have_error_exception_error_is_errno) //
|| (status_value == status::have_error_lost_consistency_error_is_errno) //
|| (status_value == status::have_error_exception_lost_consistency_error_is_errno) //
;
#else
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error_is_errno)) != 0;
#endif
}
constexpr bool have_moved_from() const noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
#error Fixme
#else
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0;
#endif
}
constexpr bool have_moved_from() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0; }
constexpr status_bitfield_type &set_have_value(bool v) noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
switch(status_value)
{
case status::none:
if(v)
{
status_value = status::have_value;
}
break;
case status::have_value:
if(!v)
{
status_value = status::none;
}
break;
case status::have_error:
if(v)
{
make_ub(*this);
}
break;
case status::have_exception:
if(v)
{
make_ub(*this);
}
break;
case status::have_error_exception:
if(v)
{
make_ub(*this);
}
break;
case status::have_value_lost_consistency:
if(!v)
{
status_value = status::none;
}
break;
case status::have_error_lost_consistency:
if(v)
{
make_ub(*this);
}
break;
case status::have_exception_lost_consistency:
if(v)
{
make_ub(*this);
}
break;
case status::have_error_exception_lost_consistency:
if(v)
{
make_ub(*this);
}
break;
case status::have_error_error_is_errno:
if(v)
{
make_ub(*this);
}
break;
case status::have_error_exception_error_is_errno:
if(v)
{
make_ub(*this);
}
break;
case status::have_error_lost_consistency_error_is_errno:
if(v)
{
make_ub(*this);
}
break;
case status::have_error_exception_lost_consistency_error_is_errno:
if(v)
{
make_ub(*this);
}
break;
}
#else
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_value)) :
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_value)));
#endif
return *this;
}
constexpr status_bitfield_type &set_have_error(bool v) noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
switch(status_value)
{
case status::none:
if(v)
{
status_value = status::have_error;
}
break;
case status::have_value:
if(v)
{
make_ub(*this);
}
break;
case status::have_error:
if(!v)
{
status_value = status::none;
}
break;
case status::have_exception:
if(v)
{
status_value = status::have_error_exception;
}
break;
case status::have_error_exception:
if(!v)
{
status_value = status::have_exception;
}
break;
case status::have_value_lost_consistency:
if(v)
{
make_ub(*this);
}
break;
case status::have_error_lost_consistency:
if(!v)
{
status_value = status::none;
}
break;
case status::have_exception_lost_consistency:
if(v)
{
status_value = status::have_error_exception_lost_consistency;
}
break;
case status::have_error_exception_lost_consistency:
if(!v)
{
status_value = status::have_exception_lost_consistency;
}
break;
case status::have_error_error_is_errno:
if(!v)
{
status_value = status::none;
}
break;
case status::have_error_exception_error_is_errno:
if(!v)
{
status_value = status::have_exception;
}
break;
case status::have_error_lost_consistency_error_is_errno:
if(!v)
{
status_value = status::none;
}
break;
case status::have_error_exception_lost_consistency_error_is_errno:
if(!v)
{
status_value = status::have_exception_lost_consistency;
}
break;
}
#else
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_error)) :
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_error)));
#endif
return *this;
}
constexpr status_bitfield_type &set_have_exception(bool v) noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
switch(status_value)
{
case status::none:
if(v)
{
status_value = status::have_exception;
}
break;
case status::have_value:
if(v)
{
make_ub(*this);
}
break;
case status::have_error:
if(v)
{
status_value = status::have_error_exception;
}
break;
case status::have_exception:
if(!v)
{
status_value = status::none;
}
break;
case status::have_error_exception:
if(!v)
{
status_value = status::have_error;
}
break;
case status::have_value_lost_consistency:
if(v)
{
make_ub(*this);
}
break;
case status::have_error_lost_consistency:
if(v)
{
status_value = status::have_error_exception_lost_consistency;
}
break;
case status::have_exception_lost_consistency:
if(!v)
{
status_value = status::none;
}
break;
case status::have_error_exception_lost_consistency:
if(!v)
{
status_value = status::have_error_lost_consistency;
}
break;
case status::have_error_error_is_errno:
if(v)
{
status_value = status::have_error_exception_error_is_errno;
}
break;
case status::have_error_exception_error_is_errno:
if(!v)
{
status_value = status::have_error_error_is_errno;
}
break;
case status::have_error_lost_consistency_error_is_errno:
if(v)
{
status_value = status::have_error_exception_lost_consistency_error_is_errno;
}
break;
case status::have_error_exception_lost_consistency_error_is_errno:
if(!v)
{
status_value = status::have_error_lost_consistency_error_is_errno;
}
break;
}
#else
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_exception)) :
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_exception)));
#endif
return *this;
}
constexpr status_bitfield_type &set_have_error_is_errno(bool v) noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
switch(status_value)
{
case status::none:
make_ub(*this);
break;
case status::have_value:
make_ub(*this);
break;
case status::have_error:
if(v)
{
status_value = status::have_error_error_is_errno;
}
break;
case status::have_exception:
make_ub(*this);
break;
case status::have_error_exception:
if(v)
{
status_value = status::have_error_exception_error_is_errno;
}
break;
case status::have_value_lost_consistency:
make_ub(*this);
break;
case status::have_error_lost_consistency:
if(v)
{
status_value = status::have_error_lost_consistency_error_is_errno;
}
break;
case status::have_exception_lost_consistency:
make_ub(*this);
break;
case status::have_error_exception_lost_consistency:
if(v)
{
status_value = status::have_error_exception_lost_consistency_error_is_errno;
}
break;
case status::have_error_error_is_errno:
if(!v)
{
status_value = status::have_error;
}
break;
case status::have_error_exception_error_is_errno:
if(!v)
{
status_value = status::have_error_exception;
}
break;
case status::have_error_lost_consistency_error_is_errno:
if(!v)
{
status_value = status::have_error_lost_consistency;
}
break;
case status::have_error_exception_lost_consistency_error_is_errno:
if(!v)
{
status_value = status::have_error_exception_lost_consistency;
}
break;
}
#else
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_error_is_errno)) :
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_error_is_errno)));
#endif
return *this;
}
constexpr status_bitfield_type &set_have_lost_consistency(bool v) noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
switch(status_value)
{
case status::none:
if(v)
{
make_ub(*this);
}
break;
case status::have_value:
if(v)
{
status_value = status::have_value_lost_consistency;
}
break;
case status::have_error:
if(v)
{
status_value = status::have_error_lost_consistency;
}
break;
case status::have_exception:
if(v)
{
status_value = status::have_exception_lost_consistency;
}
break;
case status::have_error_exception:
if(v)
{
status_value = status::have_error_exception_lost_consistency;
}
break;
case status::have_value_lost_consistency:
if(!v)
{
status_value = status::have_value;
}
break;
case status::have_error_lost_consistency:
if(!v)
{
status_value = status::have_error;
}
break;
case status::have_exception_lost_consistency:
if(!v)
{
status_value = status::have_exception;
}
break;
case status::have_error_exception_lost_consistency:
if(!v)
{
status_value = status::have_error_exception;
}
break;
case status::have_error_error_is_errno:
if(v)
{
status_value = status::have_error_lost_consistency_error_is_errno;
}
break;
case status::have_error_exception_error_is_errno:
if(v)
{
status_value = status::have_error_exception_lost_consistency_error_is_errno;
}
break;
case status::have_error_lost_consistency_error_is_errno:
if(!v)
{
status_value = status::have_error_exception_error_is_errno;
}
break;
case status::have_error_exception_lost_consistency_error_is_errno:
if(!v)
{
status_value = status::have_error_exception_error_is_errno;
}
break;
}
#else
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_lost_consistency)) :
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_lost_consistency)));
#endif
return *this;
}
constexpr status_bitfield_type &set_have_moved_from(bool v) noexcept
{
#if OUTCOME_USE_CONSTEXPR_ENUM_STATUS
#error Fixme
#else
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_moved_from)) :
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_moved_from)));
#endif
return *this;
}
};

View File

@@ -1019,9 +1019,9 @@ Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt)
*/
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define OUTCOME_PREVIOUS_COMMIT_REF 571f9c930e672950e99d5d30f743603aaaf8014c
#define OUTCOME_PREVIOUS_COMMIT_DATE "2024-03-13 20:29:49 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 571f9c93
#define OUTCOME_PREVIOUS_COMMIT_REF 60147ab3146f0418b10a6a4671ea0802cb514432
#define OUTCOME_PREVIOUS_COMMIT_DATE "2024-08-14 16:41:50 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 60147ab3
#define OUTCOME_V2 (QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2))
#ifdef _DEBUG
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2d)))
@@ -2138,15 +2138,11 @@ namespace detail
// Void does nothing
template <> struct move_assign_to_empty<void, false, false>
{
move_assign_to_empty(void *, void *) noexcept
{ /* nothing to assign */
}
move_assign_to_empty(void *, void *) noexcept { /* nothing to assign */ }
};
template <> struct move_assign_to_empty<const void, false, false>
{
move_assign_to_empty(const void *, const void *) noexcept
{ /* nothing to assign */
}
move_assign_to_empty(const void *, const void *) noexcept { /* nothing to assign */ }
};
// Helpers for copy assigning to empty storage
template <class T, bool isCopyConstructible = std::is_copy_constructible<T>::value,
@@ -2173,15 +2169,11 @@ namespace detail
// Void does nothing
template <> struct copy_assign_to_empty<void, false, false>
{
copy_assign_to_empty(void *, void *) noexcept
{ /* nothing to assign */
}
copy_assign_to_empty(void *, void *) noexcept { /* nothing to assign */ }
};
template <> struct copy_assign_to_empty<const void, false, false>
{
copy_assign_to_empty(const void *, const void *) noexcept
{ /* nothing to assign */
}
copy_assign_to_empty(const void *, const void *) noexcept { /* nothing to assign */ }
};
template <class T, bool nothrow> struct strong_swap_impl
{
@@ -2309,9 +2301,10 @@ namespace detail
#ifdef _MSC_VER
__declspec(noreturn)
#elif defined(__GNUC__) || defined(__clang__)
__attribute__((noreturn))
__attribute__((noreturn))
#endif
void make_ub(T && /*unused*/)
void
make_ub(T && /*unused*/)
{
OUTCOME_ASSERT(false); // NOLINT
#if defined(__GNUC__) || defined(__clang__)
@@ -2332,10 +2325,10 @@ namespace detail
to change the value to one of the enum's values. This is stupid to look at in source code,
but it make clang's optimiser do the right thing, so it's worth it.
*/
#define OUTCOME_USE_CONSTEXPR_ENUM_STATUS 0
enum class status : uint16_t
{
// WARNING: These bits are not tracked by abi-dumper, but changing them will break ABI!
// bits 0-5 in use.
none = 0,
have_value = (1U << 0U),
have_error = (1U << 1U),
@@ -2354,7 +2347,20 @@ namespace detail
have_error_lost_consistency_error_is_errno = (1U << 1U) | (1U << 3U) | (1U << 4U),
have_error_exception_lost_consistency_error_is_errno = (3U << 1U) | (1U << 3U) | (1U << 4U),
// value has been moved from
have_moved_from = (1U << 5U)
have_moved_from = (1U << 5U),
have_value_moved_from = (1U << 0U) | (1U << 5U),
have_error_moved_from = (1U << 1U) | (1U << 5U),
have_exception_moved_from = (2U << 1U) | (1U << 5U),
have_error_exception_moved_from = (3U << 1U) | (1U << 5U),
have_value_lost_consistency_moved_from = (1U << 0U) | (1U << 3U) | (1U << 5U),
have_error_lost_consistency_moved_from = (1U << 1U) | (1U << 3U) | (1U << 5U),
have_exception_lost_consistency_moved_from = (2U << 1U) | (1U << 3U) | (1U << 5U),
have_error_exception_lost_consistency_moved_from = (3U << 1U) | (1U << 3U) | (1U << 5U),
have_error_is_errno_moved_from = (1U << 4U) | (1U << 5U),
have_error_error_is_errno_moved_from = (1U << 1U) | (1U << 4U) | (1U << 5U),
have_error_exception_error_is_errno_moved_from = (3U << 1U) | (1U << 4U) | (1U << 5U),
have_error_lost_consistency_error_is_errno_moved_from = (1U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
have_error_exception_lost_consistency_error_is_errno_moved_from = (3U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
};
struct status_bitfield_type
{
@@ -2375,18 +2381,9 @@ namespace detail
constexpr status_bitfield_type &operator=(const status_bitfield_type &) = default;
constexpr status_bitfield_type &operator=(status_bitfield_type &&) = default;
//~status_bitfield_type() = default; // Do NOT uncomment this, it breaks older clangs!
constexpr bool have_value() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0;
}
constexpr bool have_error() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0;
}
constexpr bool have_exception() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0;
}
constexpr bool have_value() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0; }
constexpr bool have_error() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0; }
constexpr bool have_exception() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0; }
constexpr bool have_lost_consistency() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_lost_consistency)) != 0;
@@ -2395,10 +2392,7 @@ namespace detail
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error_is_errno)) != 0;
}
constexpr bool have_moved_from() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0;
}
constexpr bool have_moved_from() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0; }
constexpr status_bitfield_type &set_have_value(bool v) noexcept
{
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_value)) :
@@ -2884,11 +2878,11 @@ namespace detail
// value/value
if(_status.have_value() && o._status.have_value())
{
struct _
struct some_type
{
status_bitfield_type &a, &b;
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -2897,19 +2891,19 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status};
strong_swap(_.all_good, _value, o._value);
} some_type_value{_status, o._status};
strong_swap(some_type_value.all_good, _value, o._value);
swap(_status, o._status);
return;
}
// error/error
if(_status.have_error() && o._status.have_error())
{
struct _
struct some_type
{
status_bitfield_type &a, &b;
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -2918,8 +2912,8 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status};
strong_swap(_.all_good, _error, o._error);
} some_type_value{_status, o._status};
strong_swap(some_type_value.all_good, _error, o._error);
swap(_status, o._status);
return;
}
@@ -2969,13 +2963,13 @@ namespace detail
return;
}
// It can now only be value/error, or error/value
struct _
struct some_type
{
status_bitfield_type &a, &b;
_value_type_ *value, *o_value;
_error_type_ *error, *o_error;
bool all_good{true};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -2984,21 +2978,21 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status, OUTCOME_ADDRESS_OF(_value), OUTCOME_ADDRESS_OF(o._value), OUTCOME_ADDRESS_OF(_error), OUTCOME_ADDRESS_OF(o._error)};
} some_type_value{_status, o._status, OUTCOME_ADDRESS_OF(_value), OUTCOME_ADDRESS_OF(o._value), OUTCOME_ADDRESS_OF(_error), OUTCOME_ADDRESS_OF(o._error)};
if(_status.have_value() && o._status.have_error())
{
strong_placement(_.all_good, _.o_value, _.value, [&_] { //
strong_placement(_.all_good, _.error, _.o_error, [&_] { //
swap(_.a, _.b); //
strong_placement(some_type_value.all_good, some_type_value.o_value, some_type_value.value, [&some_type_value] { //
strong_placement(some_type_value.all_good, some_type_value.error, some_type_value.o_error, [&some_type_value] { //
swap(some_type_value.a, some_type_value.b); //
});
});
return;
}
if(_status.have_error() && o._status.have_value())
{
strong_placement(_.all_good, _.o_error, _.error, [&_] { //
strong_placement(_.all_good, _.value, _.o_value, [&_] { //
swap(_.a, _.b); //
strong_placement(some_type_value.all_good, some_type_value.o_error, some_type_value.error, [&some_type_value] { //
strong_placement(some_type_value.all_good, some_type_value.value, some_type_value.o_value, [&some_type_value] { //
swap(some_type_value.a, some_type_value.b); //
});
});
return;
@@ -3069,12 +3063,12 @@ namespace detail
constexpr
#endif
value_storage_nontrivial_move_assignment &
operator=(value_storage_nontrivial_move_assignment &&o) noexcept(
std::is_nothrow_move_assignable<value_type>::value &&
std::is_nothrow_move_assignable<error_type>::value && noexcept(move_assign_to_empty<value_type>(
static_cast<value_type *>(nullptr),
static_cast<value_type *>(nullptr))) && noexcept(move_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr)))) // NOLINT
operator=(value_storage_nontrivial_move_assignment &&o) noexcept(std::is_nothrow_move_assignable<value_type>::value &&
std::is_nothrow_move_assignable<error_type>::value &&
noexcept(move_assign_to_empty<value_type>(static_cast<value_type *>(nullptr),
static_cast<value_type *>(nullptr))) &&
noexcept(move_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr)))) // NOLINT
{
using _value_type_ = typename Base::_value_type_;
using _error_type_ = typename Base::_error_type_;
@@ -3173,10 +3167,9 @@ namespace detail
#endif
value_storage_nontrivial_copy_assignment &
operator=(const value_storage_nontrivial_copy_assignment &o) noexcept(
std::is_nothrow_copy_assignable<value_type>::value &&
std::is_nothrow_copy_assignable<error_type>::value && noexcept(copy_assign_to_empty<value_type>(
static_cast<value_type *>(nullptr), static_cast<value_type *>(nullptr))) && noexcept(copy_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr))))
std::is_nothrow_copy_assignable<value_type>::value && std::is_nothrow_copy_assignable<error_type>::value &&
noexcept(copy_assign_to_empty<value_type>(static_cast<value_type *>(nullptr), static_cast<value_type *>(nullptr))) &&
noexcept(copy_assign_to_empty<error_type>(static_cast<error_type *>(nullptr), static_cast<error_type *>(nullptr))))
{
using _value_type_ = typename Base::_value_type_;
using _error_type_ = typename Base::_error_type_;
@@ -3908,41 +3901,44 @@ namespace detail
} // namespace detail
OUTCOME_V2_NAMESPACE_END
#endif
/* Inline GDB pretty printer for result
(C) 2024 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
File Created: Jun 2024
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
// Inline GDB pretty printer for result
// (C) 2024 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
// File Created: Jun 2024
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License in the accompanying file
// Licence.txt or at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file Licence.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Generated on 2024-08-12T21:44:07
#ifndef OUTCOME_INLINE_GDB_PRETTY_PRINTER_H
#define OUTCOME_INLINE_GDB_PRETTY_PRINTER_H
#ifndef OUTCOME_DISABLE_INLINE_GDB_PRETTY_PRINTERS
#if defined(__ELF__)
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverlength-strings"
#endif
__asm__(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n"
".byte 4 /* Python Text */\n"
".ascii \"gdb.inlined-script\\n\"\n"
".ascii \"\\4gdb.inlined-script.OUTCOME_INLINE_GDB_PRETTY_PRINTER_H\\n\"\n"
".ascii \"import gdb.printing\\n\"\n"
".ascii \"import os\\n\"\n"
".ascii \"def synthesise_gdb_value_from_string(s):\\n\"\n"
".ascii \" '''For when you want to return a synthetic string from children()'''\\n\"\n"
".ascii \" return gdb.Value(s + '\\0').cast(gdb.lookup_type('char').pointer())\\n\"\n"
".ascii \" return gdb.Value(s + '\\\\0').cast(gdb.lookup_type('char').pointer())\\n\"\n"
".ascii \"class OutcomeBasicOutcomePrinter(object):\\n\"\n"
".ascii \" '''Print an outcome::basic_outcome<T> and outcome::basic_result<T>'''\\n\"\n"
".ascii \" def __init__(self, val):\\n\"\n"
@@ -4036,9 +4032,12 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n"
".ascii \"register_printers(gdb.current_objfile())\\n\"\n"
".byte 0\n"
".popsection\n");
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
#endif
#endif // defined(__ELF__)
#endif // !defined(OUTCOME_DISABLE_INLINE_GDB_PRETTY_PRINTERS)
#endif // !defined(OUTCOME_INLINE_GDB_PRETTY_PRINTER_H)
/* Policies for result and outcome
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (13 commits)
File Created: Oct 2017
@@ -6064,12 +6063,12 @@ SIGNATURE NOT RECOGNISED
swap(this->_ptr, o._ptr);
return;
}
struct _
struct some_type
{
basic_outcome &a, &b;
bool exceptioned{false};
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -6110,11 +6109,11 @@ SIGNATURE NOT RECOGNISED
check(&this->b);
}
}
} _{*this, o};
strong_swap(_.all_good, this->_ptr, o._ptr);
_.exceptioned = true;
} some_type_value{*this, o};
strong_swap(some_type_value.all_good, this->_ptr, o._ptr);
some_type_value.exceptioned = true;
this->_state.swap(o._state);
_.exceptioned = false;
some_type_value.exceptioned = false;
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View File

@@ -1044,9 +1044,9 @@ Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt)
*/
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define OUTCOME_PREVIOUS_COMMIT_REF 571f9c930e672950e99d5d30f743603aaaf8014c
#define OUTCOME_PREVIOUS_COMMIT_DATE "2024-03-13 20:29:49 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 571f9c93
#define OUTCOME_PREVIOUS_COMMIT_REF 60147ab3146f0418b10a6a4671ea0802cb514432
#define OUTCOME_PREVIOUS_COMMIT_DATE "2024-08-14 16:41:50 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 60147ab3
#define OUTCOME_V2 (QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2))
#ifdef _DEBUG
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2d)))
@@ -2163,15 +2163,11 @@ namespace detail
// Void does nothing
template <> struct move_assign_to_empty<void, false, false>
{
move_assign_to_empty(void *, void *) noexcept
{ /* nothing to assign */
}
move_assign_to_empty(void *, void *) noexcept { /* nothing to assign */ }
};
template <> struct move_assign_to_empty<const void, false, false>
{
move_assign_to_empty(const void *, const void *) noexcept
{ /* nothing to assign */
}
move_assign_to_empty(const void *, const void *) noexcept { /* nothing to assign */ }
};
// Helpers for copy assigning to empty storage
template <class T, bool isCopyConstructible = std::is_copy_constructible<T>::value,
@@ -2198,15 +2194,11 @@ namespace detail
// Void does nothing
template <> struct copy_assign_to_empty<void, false, false>
{
copy_assign_to_empty(void *, void *) noexcept
{ /* nothing to assign */
}
copy_assign_to_empty(void *, void *) noexcept { /* nothing to assign */ }
};
template <> struct copy_assign_to_empty<const void, false, false>
{
copy_assign_to_empty(const void *, const void *) noexcept
{ /* nothing to assign */
}
copy_assign_to_empty(const void *, const void *) noexcept { /* nothing to assign */ }
};
template <class T, bool nothrow> struct strong_swap_impl
{
@@ -2334,9 +2326,10 @@ namespace detail
#ifdef _MSC_VER
__declspec(noreturn)
#elif defined(__GNUC__) || defined(__clang__)
__attribute__((noreturn))
__attribute__((noreturn))
#endif
void make_ub(T && /*unused*/)
void
make_ub(T && /*unused*/)
{
OUTCOME_ASSERT(false); // NOLINT
#if defined(__GNUC__) || defined(__clang__)
@@ -2357,10 +2350,10 @@ namespace detail
to change the value to one of the enum's values. This is stupid to look at in source code,
but it make clang's optimiser do the right thing, so it's worth it.
*/
#define OUTCOME_USE_CONSTEXPR_ENUM_STATUS 0
enum class status : uint16_t
{
// WARNING: These bits are not tracked by abi-dumper, but changing them will break ABI!
// bits 0-5 in use.
none = 0,
have_value = (1U << 0U),
have_error = (1U << 1U),
@@ -2379,7 +2372,20 @@ namespace detail
have_error_lost_consistency_error_is_errno = (1U << 1U) | (1U << 3U) | (1U << 4U),
have_error_exception_lost_consistency_error_is_errno = (3U << 1U) | (1U << 3U) | (1U << 4U),
// value has been moved from
have_moved_from = (1U << 5U)
have_moved_from = (1U << 5U),
have_value_moved_from = (1U << 0U) | (1U << 5U),
have_error_moved_from = (1U << 1U) | (1U << 5U),
have_exception_moved_from = (2U << 1U) | (1U << 5U),
have_error_exception_moved_from = (3U << 1U) | (1U << 5U),
have_value_lost_consistency_moved_from = (1U << 0U) | (1U << 3U) | (1U << 5U),
have_error_lost_consistency_moved_from = (1U << 1U) | (1U << 3U) | (1U << 5U),
have_exception_lost_consistency_moved_from = (2U << 1U) | (1U << 3U) | (1U << 5U),
have_error_exception_lost_consistency_moved_from = (3U << 1U) | (1U << 3U) | (1U << 5U),
have_error_is_errno_moved_from = (1U << 4U) | (1U << 5U),
have_error_error_is_errno_moved_from = (1U << 1U) | (1U << 4U) | (1U << 5U),
have_error_exception_error_is_errno_moved_from = (3U << 1U) | (1U << 4U) | (1U << 5U),
have_error_lost_consistency_error_is_errno_moved_from = (1U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
have_error_exception_lost_consistency_error_is_errno_moved_from = (3U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
};
struct status_bitfield_type
{
@@ -2400,18 +2406,9 @@ namespace detail
constexpr status_bitfield_type &operator=(const status_bitfield_type &) = default;
constexpr status_bitfield_type &operator=(status_bitfield_type &&) = default;
//~status_bitfield_type() = default; // Do NOT uncomment this, it breaks older clangs!
constexpr bool have_value() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0;
}
constexpr bool have_error() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0;
}
constexpr bool have_exception() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0;
}
constexpr bool have_value() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0; }
constexpr bool have_error() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0; }
constexpr bool have_exception() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0; }
constexpr bool have_lost_consistency() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_lost_consistency)) != 0;
@@ -2420,10 +2417,7 @@ namespace detail
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error_is_errno)) != 0;
}
constexpr bool have_moved_from() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0;
}
constexpr bool have_moved_from() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0; }
constexpr status_bitfield_type &set_have_value(bool v) noexcept
{
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_value)) :
@@ -2909,11 +2903,11 @@ namespace detail
// value/value
if(_status.have_value() && o._status.have_value())
{
struct _
struct some_type
{
status_bitfield_type &a, &b;
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -2922,19 +2916,19 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status};
strong_swap(_.all_good, _value, o._value);
} some_type_value{_status, o._status};
strong_swap(some_type_value.all_good, _value, o._value);
swap(_status, o._status);
return;
}
// error/error
if(_status.have_error() && o._status.have_error())
{
struct _
struct some_type
{
status_bitfield_type &a, &b;
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -2943,8 +2937,8 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status};
strong_swap(_.all_good, _error, o._error);
} some_type_value{_status, o._status};
strong_swap(some_type_value.all_good, _error, o._error);
swap(_status, o._status);
return;
}
@@ -2994,13 +2988,13 @@ namespace detail
return;
}
// It can now only be value/error, or error/value
struct _
struct some_type
{
status_bitfield_type &a, &b;
_value_type_ *value, *o_value;
_error_type_ *error, *o_error;
bool all_good{true};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -3009,21 +3003,21 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status, OUTCOME_ADDRESS_OF(_value), OUTCOME_ADDRESS_OF(o._value), OUTCOME_ADDRESS_OF(_error), OUTCOME_ADDRESS_OF(o._error)};
} some_type_value{_status, o._status, OUTCOME_ADDRESS_OF(_value), OUTCOME_ADDRESS_OF(o._value), OUTCOME_ADDRESS_OF(_error), OUTCOME_ADDRESS_OF(o._error)};
if(_status.have_value() && o._status.have_error())
{
strong_placement(_.all_good, _.o_value, _.value, [&_] { //
strong_placement(_.all_good, _.error, _.o_error, [&_] { //
swap(_.a, _.b); //
strong_placement(some_type_value.all_good, some_type_value.o_value, some_type_value.value, [&some_type_value] { //
strong_placement(some_type_value.all_good, some_type_value.error, some_type_value.o_error, [&some_type_value] { //
swap(some_type_value.a, some_type_value.b); //
});
});
return;
}
if(_status.have_error() && o._status.have_value())
{
strong_placement(_.all_good, _.o_error, _.error, [&_] { //
strong_placement(_.all_good, _.value, _.o_value, [&_] { //
swap(_.a, _.b); //
strong_placement(some_type_value.all_good, some_type_value.o_error, some_type_value.error, [&some_type_value] { //
strong_placement(some_type_value.all_good, some_type_value.value, some_type_value.o_value, [&some_type_value] { //
swap(some_type_value.a, some_type_value.b); //
});
});
return;
@@ -3094,12 +3088,12 @@ namespace detail
constexpr
#endif
value_storage_nontrivial_move_assignment &
operator=(value_storage_nontrivial_move_assignment &&o) noexcept(
std::is_nothrow_move_assignable<value_type>::value &&
std::is_nothrow_move_assignable<error_type>::value && noexcept(move_assign_to_empty<value_type>(
static_cast<value_type *>(nullptr),
static_cast<value_type *>(nullptr))) && noexcept(move_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr)))) // NOLINT
operator=(value_storage_nontrivial_move_assignment &&o) noexcept(std::is_nothrow_move_assignable<value_type>::value &&
std::is_nothrow_move_assignable<error_type>::value &&
noexcept(move_assign_to_empty<value_type>(static_cast<value_type *>(nullptr),
static_cast<value_type *>(nullptr))) &&
noexcept(move_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr)))) // NOLINT
{
using _value_type_ = typename Base::_value_type_;
using _error_type_ = typename Base::_error_type_;
@@ -3198,10 +3192,9 @@ namespace detail
#endif
value_storage_nontrivial_copy_assignment &
operator=(const value_storage_nontrivial_copy_assignment &o) noexcept(
std::is_nothrow_copy_assignable<value_type>::value &&
std::is_nothrow_copy_assignable<error_type>::value && noexcept(copy_assign_to_empty<value_type>(
static_cast<value_type *>(nullptr), static_cast<value_type *>(nullptr))) && noexcept(copy_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr))))
std::is_nothrow_copy_assignable<value_type>::value && std::is_nothrow_copy_assignable<error_type>::value &&
noexcept(copy_assign_to_empty<value_type>(static_cast<value_type *>(nullptr), static_cast<value_type *>(nullptr))) &&
noexcept(copy_assign_to_empty<error_type>(static_cast<error_type *>(nullptr), static_cast<error_type *>(nullptr))))
{
using _value_type_ = typename Base::_value_type_;
using _error_type_ = typename Base::_error_type_;
@@ -3933,41 +3926,44 @@ namespace detail
} // namespace detail
OUTCOME_V2_NAMESPACE_END
#endif
/* Inline GDB pretty printer for result
(C) 2024 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
File Created: Jun 2024
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
// Inline GDB pretty printer for result
// (C) 2024 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
// File Created: Jun 2024
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License in the accompanying file
// Licence.txt or at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file Licence.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Generated on 2024-08-12T21:44:07
#ifndef OUTCOME_INLINE_GDB_PRETTY_PRINTER_H
#define OUTCOME_INLINE_GDB_PRETTY_PRINTER_H
#ifndef OUTCOME_DISABLE_INLINE_GDB_PRETTY_PRINTERS
#if defined(__ELF__)
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverlength-strings"
#endif
__asm__(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n"
".byte 4 /* Python Text */\n"
".ascii \"gdb.inlined-script\\n\"\n"
".ascii \"\\4gdb.inlined-script.OUTCOME_INLINE_GDB_PRETTY_PRINTER_H\\n\"\n"
".ascii \"import gdb.printing\\n\"\n"
".ascii \"import os\\n\"\n"
".ascii \"def synthesise_gdb_value_from_string(s):\\n\"\n"
".ascii \" '''For when you want to return a synthetic string from children()'''\\n\"\n"
".ascii \" return gdb.Value(s + '\\0').cast(gdb.lookup_type('char').pointer())\\n\"\n"
".ascii \" return gdb.Value(s + '\\\\0').cast(gdb.lookup_type('char').pointer())\\n\"\n"
".ascii \"class OutcomeBasicOutcomePrinter(object):\\n\"\n"
".ascii \" '''Print an outcome::basic_outcome<T> and outcome::basic_result<T>'''\\n\"\n"
".ascii \" def __init__(self, val):\\n\"\n"
@@ -4061,9 +4057,12 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n"
".ascii \"register_printers(gdb.current_objfile())\\n\"\n"
".byte 0\n"
".popsection\n");
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
#endif
#endif // defined(__ELF__)
#endif // !defined(OUTCOME_DISABLE_INLINE_GDB_PRETTY_PRINTERS)
#endif // !defined(OUTCOME_INLINE_GDB_PRETTY_PRINTER_H)
/* Policies for result and outcome
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (13 commits)
File Created: Oct 2017
@@ -6089,12 +6088,12 @@ SIGNATURE NOT RECOGNISED
swap(this->_ptr, o._ptr);
return;
}
struct _
struct some_type
{
basic_outcome &a, &b;
bool exceptioned{false};
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -6135,11 +6134,11 @@ SIGNATURE NOT RECOGNISED
check(&this->b);
}
}
} _{*this, o};
strong_swap(_.all_good, this->_ptr, o._ptr);
_.exceptioned = true;
} some_type_value{*this, o};
strong_swap(some_type_value.all_good, this->_ptr, o._ptr);
some_type_value.exceptioned = true;
this->_state.swap(o._state);
_.exceptioned = false;
some_type_value.exceptioned = false;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
@@ -8128,16 +8127,19 @@ namespace traits
SYSTEM_ERROR2_NAMESPACE_END
#ifndef SYSTEM_ERROR2_DISABLE_INLINE_GDB_PRETTY_PRINTERS
#if defined(__ELF__)
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverlength-strings"
#endif
__asm__(
".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n"
".byte 4 /* Python Text */\n"
".ascii \"gdb.inlined-script\\n\"\n"
".ascii \"\\4gdb.inlined-script.SYSTEM_ERROR2_INLINE_GDB_PRETTY_PRINTERS_H\\n\"\n"
".ascii \"import gdb.printing\\n\"\n"
".ascii \"import gdb\\n\"\n"
".ascii \"import os\\n\"\n"
".ascii \"def synthesise_gdb_value_from_string(s):\\n\"\n"
".ascii \" '''For when you want to return a synthetic string from children()'''\\n\"\n"
".ascii \" return gdb.Value(s + '\\0').cast(gdb.lookup_type('char').pointer())\\n\"\n"
".ascii \" return gdb.Value(s + '\\\\0').cast(gdb.lookup_type('char').pointer())\\n\"\n"
".ascii \"class StatusCodePrinter(object):\\n\"\n"
".ascii \" '''Print a system_error2::status_code<T>'''\\n\"\n"
".ascii \" def __init__(self, val):\\n\"\n"
@@ -8165,8 +8167,11 @@ __asm__(
".ascii \"register_printers(gdb.current_objfile())\\n\"\n"
".byte 0\n"
".popsection\n");
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
#endif // defined(__ELF__)
#endif // !defined(SYSTEM_ERROR2_DISABLE_INLINE_GDB_PRETTY_PRINTERS)
#endif
#include <exception> // for std::exception
SYSTEM_ERROR2_NAMESPACE_BEGIN

View File

@@ -1043,9 +1043,9 @@ Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt)
*/
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define OUTCOME_PREVIOUS_COMMIT_REF 571f9c930e672950e99d5d30f743603aaaf8014c
#define OUTCOME_PREVIOUS_COMMIT_DATE "2024-03-13 20:29:49 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 571f9c93
#define OUTCOME_PREVIOUS_COMMIT_REF 60147ab3146f0418b10a6a4671ea0802cb514432
#define OUTCOME_PREVIOUS_COMMIT_DATE "2024-08-14 16:41:50 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 60147ab3
#define OUTCOME_V2 (QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2))
#ifdef _DEBUG
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2d)))
@@ -3075,15 +3075,11 @@ namespace detail
// Void does nothing
template <> struct move_assign_to_empty<void, false, false>
{
move_assign_to_empty(void *, void *) noexcept
{ /* nothing to assign */
}
move_assign_to_empty(void *, void *) noexcept { /* nothing to assign */ }
};
template <> struct move_assign_to_empty<const void, false, false>
{
move_assign_to_empty(const void *, const void *) noexcept
{ /* nothing to assign */
}
move_assign_to_empty(const void *, const void *) noexcept { /* nothing to assign */ }
};
// Helpers for copy assigning to empty storage
template <class T, bool isCopyConstructible = std::is_copy_constructible<T>::value,
@@ -3110,15 +3106,11 @@ namespace detail
// Void does nothing
template <> struct copy_assign_to_empty<void, false, false>
{
copy_assign_to_empty(void *, void *) noexcept
{ /* nothing to assign */
}
copy_assign_to_empty(void *, void *) noexcept { /* nothing to assign */ }
};
template <> struct copy_assign_to_empty<const void, false, false>
{
copy_assign_to_empty(const void *, const void *) noexcept
{ /* nothing to assign */
}
copy_assign_to_empty(const void *, const void *) noexcept { /* nothing to assign */ }
};
template <class T, bool nothrow> struct strong_swap_impl
{
@@ -3246,9 +3238,10 @@ namespace detail
#ifdef _MSC_VER
__declspec(noreturn)
#elif defined(__GNUC__) || defined(__clang__)
__attribute__((noreturn))
__attribute__((noreturn))
#endif
void make_ub(T && /*unused*/)
void
make_ub(T && /*unused*/)
{
OUTCOME_ASSERT(false); // NOLINT
#if defined(__GNUC__) || defined(__clang__)
@@ -3269,10 +3262,10 @@ namespace detail
to change the value to one of the enum's values. This is stupid to look at in source code,
but it make clang's optimiser do the right thing, so it's worth it.
*/
#define OUTCOME_USE_CONSTEXPR_ENUM_STATUS 0
enum class status : uint16_t
{
// WARNING: These bits are not tracked by abi-dumper, but changing them will break ABI!
// bits 0-5 in use.
none = 0,
have_value = (1U << 0U),
have_error = (1U << 1U),
@@ -3291,7 +3284,20 @@ namespace detail
have_error_lost_consistency_error_is_errno = (1U << 1U) | (1U << 3U) | (1U << 4U),
have_error_exception_lost_consistency_error_is_errno = (3U << 1U) | (1U << 3U) | (1U << 4U),
// value has been moved from
have_moved_from = (1U << 5U)
have_moved_from = (1U << 5U),
have_value_moved_from = (1U << 0U) | (1U << 5U),
have_error_moved_from = (1U << 1U) | (1U << 5U),
have_exception_moved_from = (2U << 1U) | (1U << 5U),
have_error_exception_moved_from = (3U << 1U) | (1U << 5U),
have_value_lost_consistency_moved_from = (1U << 0U) | (1U << 3U) | (1U << 5U),
have_error_lost_consistency_moved_from = (1U << 1U) | (1U << 3U) | (1U << 5U),
have_exception_lost_consistency_moved_from = (2U << 1U) | (1U << 3U) | (1U << 5U),
have_error_exception_lost_consistency_moved_from = (3U << 1U) | (1U << 3U) | (1U << 5U),
have_error_is_errno_moved_from = (1U << 4U) | (1U << 5U),
have_error_error_is_errno_moved_from = (1U << 1U) | (1U << 4U) | (1U << 5U),
have_error_exception_error_is_errno_moved_from = (3U << 1U) | (1U << 4U) | (1U << 5U),
have_error_lost_consistency_error_is_errno_moved_from = (1U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
have_error_exception_lost_consistency_error_is_errno_moved_from = (3U << 1U) | (1U << 3U) | (1U << 4U) | (1U << 5U),
};
struct status_bitfield_type
{
@@ -3312,18 +3318,9 @@ namespace detail
constexpr status_bitfield_type &operator=(const status_bitfield_type &) = default;
constexpr status_bitfield_type &operator=(status_bitfield_type &&) = default;
//~status_bitfield_type() = default; // Do NOT uncomment this, it breaks older clangs!
constexpr bool have_value() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0;
}
constexpr bool have_error() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0;
}
constexpr bool have_exception() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0;
}
constexpr bool have_value() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0; }
constexpr bool have_error() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0; }
constexpr bool have_exception() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0; }
constexpr bool have_lost_consistency() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_lost_consistency)) != 0;
@@ -3332,10 +3329,7 @@ namespace detail
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error_is_errno)) != 0;
}
constexpr bool have_moved_from() const noexcept
{
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0;
}
constexpr bool have_moved_from() const noexcept { return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0; }
constexpr status_bitfield_type &set_have_value(bool v) noexcept
{
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_value)) :
@@ -3821,11 +3815,11 @@ namespace detail
// value/value
if(_status.have_value() && o._status.have_value())
{
struct _
struct some_type
{
status_bitfield_type &a, &b;
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -3834,19 +3828,19 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status};
strong_swap(_.all_good, _value, o._value);
} some_type_value{_status, o._status};
strong_swap(some_type_value.all_good, _value, o._value);
swap(_status, o._status);
return;
}
// error/error
if(_status.have_error() && o._status.have_error())
{
struct _
struct some_type
{
status_bitfield_type &a, &b;
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -3855,8 +3849,8 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status};
strong_swap(_.all_good, _error, o._error);
} some_type_value{_status, o._status};
strong_swap(some_type_value.all_good, _error, o._error);
swap(_status, o._status);
return;
}
@@ -3906,13 +3900,13 @@ namespace detail
return;
}
// It can now only be value/error, or error/value
struct _
struct some_type
{
status_bitfield_type &a, &b;
_value_type_ *value, *o_value;
_error_type_ *error, *o_error;
bool all_good{true};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -3921,21 +3915,21 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status, OUTCOME_ADDRESS_OF(_value), OUTCOME_ADDRESS_OF(o._value), OUTCOME_ADDRESS_OF(_error), OUTCOME_ADDRESS_OF(o._error)};
} some_type_value{_status, o._status, OUTCOME_ADDRESS_OF(_value), OUTCOME_ADDRESS_OF(o._value), OUTCOME_ADDRESS_OF(_error), OUTCOME_ADDRESS_OF(o._error)};
if(_status.have_value() && o._status.have_error())
{
strong_placement(_.all_good, _.o_value, _.value, [&_] { //
strong_placement(_.all_good, _.error, _.o_error, [&_] { //
swap(_.a, _.b); //
strong_placement(some_type_value.all_good, some_type_value.o_value, some_type_value.value, [&some_type_value] { //
strong_placement(some_type_value.all_good, some_type_value.error, some_type_value.o_error, [&some_type_value] { //
swap(some_type_value.a, some_type_value.b); //
});
});
return;
}
if(_status.have_error() && o._status.have_value())
{
strong_placement(_.all_good, _.o_error, _.error, [&_] { //
strong_placement(_.all_good, _.value, _.o_value, [&_] { //
swap(_.a, _.b); //
strong_placement(some_type_value.all_good, some_type_value.o_error, some_type_value.error, [&some_type_value] { //
strong_placement(some_type_value.all_good, some_type_value.value, some_type_value.o_value, [&some_type_value] { //
swap(some_type_value.a, some_type_value.b); //
});
});
return;
@@ -4006,12 +4000,12 @@ namespace detail
constexpr
#endif
value_storage_nontrivial_move_assignment &
operator=(value_storage_nontrivial_move_assignment &&o) noexcept(
std::is_nothrow_move_assignable<value_type>::value &&
std::is_nothrow_move_assignable<error_type>::value && noexcept(move_assign_to_empty<value_type>(
static_cast<value_type *>(nullptr),
static_cast<value_type *>(nullptr))) && noexcept(move_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr)))) // NOLINT
operator=(value_storage_nontrivial_move_assignment &&o) noexcept(std::is_nothrow_move_assignable<value_type>::value &&
std::is_nothrow_move_assignable<error_type>::value &&
noexcept(move_assign_to_empty<value_type>(static_cast<value_type *>(nullptr),
static_cast<value_type *>(nullptr))) &&
noexcept(move_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr)))) // NOLINT
{
using _value_type_ = typename Base::_value_type_;
using _error_type_ = typename Base::_error_type_;
@@ -4110,10 +4104,9 @@ namespace detail
#endif
value_storage_nontrivial_copy_assignment &
operator=(const value_storage_nontrivial_copy_assignment &o) noexcept(
std::is_nothrow_copy_assignable<value_type>::value &&
std::is_nothrow_copy_assignable<error_type>::value && noexcept(copy_assign_to_empty<value_type>(
static_cast<value_type *>(nullptr), static_cast<value_type *>(nullptr))) && noexcept(copy_assign_to_empty<error_type>(static_cast<error_type *>(nullptr),
static_cast<error_type *>(nullptr))))
std::is_nothrow_copy_assignable<value_type>::value && std::is_nothrow_copy_assignable<error_type>::value &&
noexcept(copy_assign_to_empty<value_type>(static_cast<value_type *>(nullptr), static_cast<value_type *>(nullptr))) &&
noexcept(copy_assign_to_empty<error_type>(static_cast<error_type *>(nullptr), static_cast<error_type *>(nullptr))))
{
using _value_type_ = typename Base::_value_type_;
using _error_type_ = typename Base::_error_type_;
@@ -4845,41 +4838,44 @@ namespace detail
} // namespace detail
OUTCOME_V2_NAMESPACE_END
#endif
/* Inline GDB pretty printer for result
(C) 2024 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
File Created: Jun 2024
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
// Inline GDB pretty printer for result
// (C) 2024 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
// File Created: Jun 2024
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License in the accompanying file
// Licence.txt or at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file Licence.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Generated on 2024-08-12T21:44:07
#ifndef OUTCOME_INLINE_GDB_PRETTY_PRINTER_H
#define OUTCOME_INLINE_GDB_PRETTY_PRINTER_H
#ifndef OUTCOME_DISABLE_INLINE_GDB_PRETTY_PRINTERS
#if defined(__ELF__)
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverlength-strings"
#endif
__asm__(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n"
".byte 4 /* Python Text */\n"
".ascii \"gdb.inlined-script\\n\"\n"
".ascii \"\\4gdb.inlined-script.OUTCOME_INLINE_GDB_PRETTY_PRINTER_H\\n\"\n"
".ascii \"import gdb.printing\\n\"\n"
".ascii \"import os\\n\"\n"
".ascii \"def synthesise_gdb_value_from_string(s):\\n\"\n"
".ascii \" '''For when you want to return a synthetic string from children()'''\\n\"\n"
".ascii \" return gdb.Value(s + '\\0').cast(gdb.lookup_type('char').pointer())\\n\"\n"
".ascii \" return gdb.Value(s + '\\\\0').cast(gdb.lookup_type('char').pointer())\\n\"\n"
".ascii \"class OutcomeBasicOutcomePrinter(object):\\n\"\n"
".ascii \" '''Print an outcome::basic_outcome<T> and outcome::basic_result<T>'''\\n\"\n"
".ascii \" def __init__(self, val):\\n\"\n"
@@ -4973,9 +4969,12 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n"
".ascii \"register_printers(gdb.current_objfile())\\n\"\n"
".byte 0\n"
".popsection\n");
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
#endif
#endif // defined(__ELF__)
#endif // !defined(OUTCOME_DISABLE_INLINE_GDB_PRETTY_PRINTERS)
#endif // !defined(OUTCOME_INLINE_GDB_PRETTY_PRINTER_H)
/* Policies for result and outcome
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (13 commits)
File Created: Oct 2017
@@ -7599,12 +7598,12 @@ SIGNATURE NOT RECOGNISED
swap(this->_ptr, o._ptr);
return;
}
struct _
struct some_type
{
basic_outcome &a, &b;
bool exceptioned{false};
bool all_good{false};
~_()
~some_type()
{
if(!this->all_good)
{
@@ -7645,11 +7644,11 @@ SIGNATURE NOT RECOGNISED
check(&this->b);
}
}
} _{*this, o};
strong_swap(_.all_good, this->_ptr, o._ptr);
_.exceptioned = true;
} some_type_value{*this, o};
strong_swap(some_type_value.all_good, this->_ptr, o._ptr);
some_type_value.exceptioned = true;
this->_state.swap(o._state);
_.exceptioned = false;
some_type_value.exceptioned = false;
#ifdef _MSC_VER
#pragma warning(pop)
#endif