Template Class UnchangedOr#

Nested Relationships#

Nested Types#

Class Documentation#

template<typename T>
class UnchangedOr#

A structural-mutation result containing a replacement or an instruction to retain the original value.

An Unchanged result indicates that no replacement is needed. A stored replacement may also refer to the original object.

// resolves to the original when descent returned the Unchanged marker
copy->a = std::move(a).ValueOrUnchanged(std::move(copy->a));
// already known to contain a replacement, so no original is needed
copy->b = std::move(b).ValueUnchecked();

Note

In-place updates retain the input’s identity, so UnchangedOrSameAs may return true despite structural changes. If structural change detection is needed, track changes separately or disable in-place mutation.

Note

UnchangedOr is deliberately designed to only have rvalue-qualified value accessors, so the compiler forces a value to leave the container exactly once, via a move.

Template Parameters:

T – The replacement value type.

Public Functions

inline UnchangedOr(Unchanged unchanged) noexcept#

Construct an unchanged result from its tag.

Parameters:

unchanged – The unchanged tag.

inline UnchangedOr(T value)#

Construct a result containing a replacement value.

Parameters:

value – The replacement value.

template<typename U, typename = std::enable_if_t<!std::is_same_v<std::decay_t<U>, Unchanged> && !details::is_unchanged_or_v<std::decay_t<U>> && !details::is_expected_v<std::decay_t<U>> && !details::is_unexpected_v<std::decay_t<U>> && !std::is_base_of_v<Error, std::decay_t<U>> && std::is_convertible_v<U, T>>>
inline UnchangedOr(U &&value)#

Construct a result containing an implicitly convertible replacement value.

Template Parameters:

U – Source value type, implicitly convertible to T.

Parameters:

value – The replacement value to copy or move.

template<typename U, typename = std::enable_if_t<type_subsumes_v<T, U> || std::is_convertible_v<U, T>>>
inline UnchangedOr(UnchangedOr<U> other)#

Implicit converting constructor from another replacement type.

Template Parameters:

U – Source replacement type whose storage is subsumed by or implicitly convertible to T.

Parameters:

other – The result to convert, copied from an lvalue or moved from an rvalue.

~UnchangedOr() = default#
inline bool IsUnchanged() const & noexcept#

Whether this result holds the Unchanged marker, retaining the original value.

Returns:

Whether the result holds the Unchanged marker.

inline bool UnchangedOrSameAs(const T &original) const & noexcept#

Whether this result holds the Unchanged marker or a value that compares same_as to original.

Note

For objects, this checks identity, not contents or subtree changes.

Parameters:

original – The original value.

Returns:

Whether the original value may be retained without replacement.

inline T ValueOrUnchanged(const T &original) &&#

Move the replacement, or copy original when unchanged.

Note

Both mutable and const lvalues are borrowed. Use std::move(original) to transfer ownership.

Parameters:

original – The borrowed original value, which is left unmodified.

Returns:

The replacement or original value.

inline T ValueOrUnchanged(T &&original) &&#

Move the replacement, or move original when unchanged.

Note

The original is moved from only when the result is unchanged.

Parameters:

original – The owned original value.

Returns:

The replacement or original value.

template<typename U = T, typename = std::enable_if_t<std::is_same_v<T, Any> && std::is_same_v<U, T>>>
inline Any ValueOrUnchanged(AnyView original) &&#

Move the replacement, or materialize original when unchanged.

Template Parameters:

U – The replacement type, constrained to Any.

Parameters:

original – The borrowed original value.

Returns:

The replacement or original value.

inline T ValueUnchecked() &&#

Move the stored replacement value without checking its state.

Returns:

The replacement value.

Pre:

!IsUnchanged().

template<typename U, typename = std::enable_if_t<TypeTraits<U>::storage_enabled || std::is_same_v<U, Any>>>
inline std::optional<U> as() &&#

Strictly cast the stored result, moving it on success.

Note

Unchanged succeeds for an UnchangedOr target. No fallback conversions are run.

Template Parameters:

U – The exact target type, including any UnchangedOr wrapper.

Returns:

The cast value, or std::nullopt on a type mismatch.

template<typename U, typename = std::enable_if_t<TypeTraits<U>::storage_enabled || std::is_same_v<U, Any>>>
inline U as_or_throw() &&#

Strictly cast the stored result, moving it on success, or throw.

Note

Unchanged succeeds for an UnchangedOr target. No fallback conversions are run.

Template Parameters:

U – The exact target type, including any UnchangedOr wrapper.

Throws:

Error – on a type mismatch.

Returns:

The cast value.