mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-10 17:47:59 -06:00
* link: Collect WSL logs (recommended method) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Advanced Authoring Tests in C++ Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: CMake Documentation and Community Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Collect WSL logs for networking issues Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Collect WSL logs (recommended method) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: ; otherwise, Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: a Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: access Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: accessible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: across Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: actively Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: adapters Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: address Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: addresses Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: and Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: appropriate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: argument Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: associated Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: attach Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: available Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: beginning Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: between Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: binaries Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: bound Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: buffer Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: buffers Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: cannot Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: canonical Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: capabilities Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-insensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-sensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: certified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: command Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: committer Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: communication Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: complains Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: configuration Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: consumed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: continue Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: converted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: currently Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: customers Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: daemon Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: deferred Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: definitions Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: delimiter Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: delivered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: dellink Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: derived Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: descriptor Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destined Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destruct Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destructible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destructor Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: detach Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: differentiate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: directories Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: disassociate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: disposition Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: distribution Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: distro Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: duping Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: emitted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: empty Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: environment Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: every time Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: exclusive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: expected Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: expire Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: explicitly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: fall back Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: false Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: fastfail Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: filesystem Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: first Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: followed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: for Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: functionality Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: functionally Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: github Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: greater Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: guarantee Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: guaranteed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: handles Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hangup Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hierarchy Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hogwarts Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hydrated Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: icrnl Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: implementation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: implementing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: initialize Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instance Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instantiate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instantiations Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: intentionally Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: interpret Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: interpreter Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: irreversibly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: iteration Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: iterator Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: its Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: kernel Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: kmsg Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: knowledge Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: maximum Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: mirrored Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: msftconnecttest Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: multi Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: multiple Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: mutable Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: namespace Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: nonexistent Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: notifications Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: occurred Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: occurring Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: otherwise, Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: outstanding Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: overridden Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: partition Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: pass through Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: passthrough Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: performs Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: periodically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: positional Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: precedence Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preexisting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preferring Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: prepopulate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: previous Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: privileges Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: process Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: processes Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: programmatically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: protection Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: provided Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: reasonable Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: receive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: received Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: red hat Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: reentrant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: registered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: regularly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: relay Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: release Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: representing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: requests Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: response Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: resurrect Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: retention Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: returned Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: security Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: semaphore Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separator Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: service Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: set up Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: setup Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: severely Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: should Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: signal Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: similarly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: simple Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: simplified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: single Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: specified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: splitting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: standard Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: stress Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: succeed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: success Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: successfully Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: supplementary Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: synced Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: system Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: take Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: than Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: that opening Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: the Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: threadpool Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: to Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: true Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: truncate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: tunneling Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unexpected Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: uninitialize Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unique Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unprivileged Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unregistered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: untrusted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: upgrade Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: utility Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: validating Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variations Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: verify Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: visible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: whether Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: winget Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: worker Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: written Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: wslservice Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * format source --------- Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Co-authored-by: Ben Hillis <benhillis@gmail.com> Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
350 lines
10 KiB
C++
350 lines
10 KiB
C++
// Copyright (C) Microsoft Corporation. All rights reserved.
|
|
#pragma once
|
|
|
|
#include <optional>
|
|
|
|
#define P9_EXPECTED_STD std::
|
|
|
|
#include "result_macros.h"
|
|
|
|
namespace util {
|
|
|
|
// Represents an error condition with the specified type.
|
|
template <typename E>
|
|
struct Unexpected
|
|
{
|
|
// Creates anew instance with the specified error value.
|
|
// N.B. This constructor allows initialization without specifying the template argument.
|
|
Unexpected(const E& value) : Value{value}
|
|
{
|
|
}
|
|
|
|
E Value;
|
|
};
|
|
|
|
namespace details {
|
|
|
|
template <typename T, typename... Args>
|
|
void ConstructInPlace(T& value, Args&&... args)
|
|
{
|
|
new (P9_EXPECTED_STD addressof(value)) T(P9_EXPECTED_STD forward<Args>(args)...);
|
|
}
|
|
|
|
// Storage for the BasicExpected class for types that are trivially destructible.
|
|
template <typename T, typename E>
|
|
struct TrivialExpectedStorage
|
|
{
|
|
// Creates a new instance with a default initialized value.
|
|
constexpr TrivialExpectedStorage() : HasValue{true}, Value{}
|
|
{
|
|
}
|
|
|
|
// Creates a new instance by invoking a constructor on the value type.
|
|
template <typename... Args>
|
|
constexpr TrivialExpectedStorage(P9_EXPECTED_STD in_place_t, Args&&... args) :
|
|
HasValue{true}, Value{P9_EXPECTED_STD forward<Args>(args)...}
|
|
{
|
|
}
|
|
|
|
// Creates a new instance with the specified error.
|
|
constexpr TrivialExpectedStorage(const Unexpected<E>& error) : HasValue{false}, Error{error.Value}
|
|
{
|
|
}
|
|
|
|
// Move-constructs a new instance from an existing instance.
|
|
constexpr TrivialExpectedStorage(TrivialExpectedStorage&& other) : HasValue{other.HasValue}, NoInit{}
|
|
{
|
|
if (other.HasValue)
|
|
{
|
|
ConstructInPlace(Value, P9_EXPECTED_STD move(other.Value));
|
|
}
|
|
else
|
|
{
|
|
ConstructInPlace(Error, P9_EXPECTED_STD move(other.Error));
|
|
}
|
|
}
|
|
|
|
// Move-assigns the value of an existing instance.
|
|
TrivialExpectedStorage& operator=(TrivialExpectedStorage&& other)
|
|
{
|
|
if (P9_EXPECTED_STD addressof(other) != this)
|
|
{
|
|
if (other.HasValue)
|
|
{
|
|
if (HasValue)
|
|
{
|
|
Value = P9_EXPECTED_STD move(other.Value);
|
|
}
|
|
else
|
|
{
|
|
ConstructInPlace(Value, P9_EXPECTED_STD move(other.Value));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (HasValue)
|
|
{
|
|
ConstructInPlace(Error, P9_EXPECTED_STD move(other.Error));
|
|
}
|
|
else
|
|
{
|
|
Error = P9_EXPECTED_STD move(other.Error);
|
|
}
|
|
}
|
|
|
|
HasValue = other.HasValue;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Default destructor, because the value type is trivially destructible.
|
|
~TrivialExpectedStorage() = default;
|
|
|
|
bool HasValue;
|
|
|
|
union
|
|
{
|
|
T Value;
|
|
E Error;
|
|
char NoInit;
|
|
};
|
|
};
|
|
|
|
// Storage for the BasicExpected class for types that are not trivially destructible.
|
|
template <typename T, typename E>
|
|
struct NonTrivialExpectedStorage
|
|
{
|
|
// Creates a new instance with a default initialized value.
|
|
constexpr NonTrivialExpectedStorage() : HasValue{true}, Value{}
|
|
{
|
|
}
|
|
|
|
// Creates a new instance by invoking a constructor on the value type.
|
|
template <typename... Args>
|
|
constexpr NonTrivialExpectedStorage(P9_EXPECTED_STD in_place_t, Args&&... args) :
|
|
HasValue{true}, Value{P9_EXPECTED_STD forward<Args>(args)...}
|
|
{
|
|
}
|
|
|
|
// Creates a new instance with the specified error.
|
|
constexpr NonTrivialExpectedStorage(const Unexpected<E>& error) : HasValue{false}, Error{error.Value}
|
|
{
|
|
}
|
|
|
|
// Move-constructs a new instance from an existing instance.
|
|
constexpr NonTrivialExpectedStorage(NonTrivialExpectedStorage&& other) : HasValue{other.HasValue}, NoInit{}
|
|
{
|
|
if (other.HasValue)
|
|
{
|
|
ConstructInPlace(Value, P9_EXPECTED_STD move(other.Value));
|
|
}
|
|
else
|
|
{
|
|
ConstructInPlace(Error, P9_EXPECTED_STD move(other.Error));
|
|
}
|
|
}
|
|
|
|
// Move-assigns the value of an existing instance.
|
|
NonTrivialExpectedStorage& operator=(NonTrivialExpectedStorage&& other)
|
|
{
|
|
if (P9_EXPECTED_STD addressof(other) != this)
|
|
{
|
|
if (other.HasValue)
|
|
{
|
|
if (HasValue)
|
|
{
|
|
Value = P9_EXPECTED_STD move(other.Value);
|
|
}
|
|
else
|
|
{
|
|
Error.~E();
|
|
ConstructInPlace(Value, P9_EXPECTED_STD move(other.Value));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (HasValue)
|
|
{
|
|
Value.~T();
|
|
ConstructInPlace(Error, P9_EXPECTED_STD move(other.Error));
|
|
}
|
|
else
|
|
{
|
|
Error = P9_EXPECTED_STD move(other.Error);
|
|
}
|
|
}
|
|
|
|
HasValue = other.HasValue;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Explicitly destructs either the value or the error.
|
|
~NonTrivialExpectedStorage()
|
|
{
|
|
if (HasValue)
|
|
{
|
|
Value.~T();
|
|
}
|
|
else
|
|
{
|
|
Error.~E();
|
|
}
|
|
}
|
|
|
|
bool HasValue;
|
|
|
|
union
|
|
{
|
|
T Value;
|
|
E Error;
|
|
char NoInit;
|
|
};
|
|
};
|
|
|
|
// Class that helps to select between the storage for trivially and non-trivially destructible
|
|
// types.
|
|
template <typename T, typename E>
|
|
struct ExpectedStorage
|
|
{
|
|
using Type = P9_EXPECTED_STD conditional_t<
|
|
P9_EXPECTED_STD is_trivially_destructible<T>::value && P9_EXPECTED_STD is_trivially_destructible<E>::value,
|
|
TrivialExpectedStorage<T, E>,
|
|
NonTrivialExpectedStorage<T, E>>;
|
|
};
|
|
|
|
} // namespace details
|
|
|
|
// This is a simple implementation of the proposed standard std::excepted type, which can be
|
|
// used as the return type for functions that return either a value or an error.
|
|
// N.B. This is named BasicExpected so that consumers can create an Expected typedef with their
|
|
// most common error type.
|
|
template <typename T, typename E>
|
|
class BasicExpected
|
|
{
|
|
public:
|
|
// Creates a new instance with a default initialized value.
|
|
constexpr BasicExpected() = default;
|
|
|
|
// Creates a new instance holding the specified value.
|
|
constexpr BasicExpected(const T& value) : m_storage{P9_EXPECTED_STD in_place, value}
|
|
{
|
|
}
|
|
|
|
// Creates a new instance moving the specified value.
|
|
constexpr BasicExpected(T&& value) : m_storage{P9_EXPECTED_STD in_place, P9_EXPECTED_STD move(value)}
|
|
{
|
|
}
|
|
|
|
// Creates a new instance holding the specified error.
|
|
constexpr BasicExpected(const Unexpected<E>& error) : m_storage{error}
|
|
{
|
|
}
|
|
|
|
// Creates a new instance moving the specified error.
|
|
constexpr BasicExpected(Unexpected<E>&& error) : m_storage{P9_EXPECTED_STD move(error)}
|
|
{
|
|
}
|
|
|
|
// Move-constructs a new instance from an existing instance.
|
|
constexpr BasicExpected(BasicExpected&& other) : m_storage{P9_EXPECTED_STD move(other.m_storage)}
|
|
{
|
|
}
|
|
|
|
// Move-assigns from an existing instance.
|
|
BasicExpected& operator=(BasicExpected&& other)
|
|
{
|
|
if (P9_EXPECTED_STD addressof(other) != this)
|
|
{
|
|
m_storage = P9_EXPECTED_STD move(other.m_storage);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Tests whether or not the instance holds a value.
|
|
explicit operator bool() const
|
|
{
|
|
return m_storage.HasValue;
|
|
}
|
|
|
|
// Gets a reference to the contained value.
|
|
T& Get()
|
|
{
|
|
FAIL_FAST_IF(!m_storage.HasValue);
|
|
return m_storage.Value;
|
|
}
|
|
|
|
// Gets a const-reference to the contained value.
|
|
const T& Get() const
|
|
{
|
|
FAIL_FAST_IF(!m_storage.HasValue);
|
|
return m_storage.Value;
|
|
}
|
|
|
|
// Accesses members of the contained value.
|
|
// N.B. Behavior is undefined if the instance does not contain a value.
|
|
T* operator->()
|
|
{
|
|
return P9_EXPECTED_STD addressof(m_storage.Value);
|
|
}
|
|
|
|
// Accesses members of the contained value.
|
|
// N.B. Behavior is undefined if the instance does not contain a value.
|
|
const T* operator->() const
|
|
{
|
|
return P9_EXPECTED_STD addressof(m_storage.Value);
|
|
}
|
|
|
|
// Gets a reference to the contained value.
|
|
// N.B. Behavior is undefined if the instance does not contain a value.
|
|
T& operator*()
|
|
{
|
|
return m_storage.Value;
|
|
}
|
|
|
|
// Gets a const-reference to the contained value.
|
|
// N.B. Behavior is undefined if the instance does not contain a value.
|
|
const T& operator*() const
|
|
{
|
|
return m_storage.Value;
|
|
}
|
|
|
|
// Gets the contained error value.
|
|
// N.B. Behavior is undefined if the instance contains a value.
|
|
const E& Error() const
|
|
{
|
|
return m_storage.Error;
|
|
}
|
|
|
|
// Gets the contained error value if the instance contains an error.
|
|
// N.B. This function allows the RETURN_ macros to work without accessing their argument twice.
|
|
// N.B. This creates a copy of the error value, but since the error value is usually expected
|
|
// to be a trivial type (e.g. int) that should not be a problem.
|
|
P9_EXPECTED_STD optional<E> OptionalError() const
|
|
{
|
|
if (m_storage.HasValue)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return m_storage.Error;
|
|
}
|
|
|
|
// Gets the contained error value, wrapped in an Unexpected struct.
|
|
// N.B. This makes it easy to return the error in a function that also returns a BasicExpected type.
|
|
// N.B. Behavior is undefined if the instance contains a value.
|
|
Unexpected<E> Unexpected() const
|
|
{
|
|
FAIL_FAST_IF(m_storage.HasValue);
|
|
return m_storage.Error;
|
|
}
|
|
|
|
private:
|
|
typename details::ExpectedStorage<T, E>::Type m_storage;
|
|
};
|
|
|
|
} // namespace util
|