Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This is for working *on* libfn; to *use* the library, see the [README](README.md

## Development environment

Building and testing libfn needs a C++20 toolchain (with one exception). `pfn` polyfills the C++23 standard-library utilities that `fn` builds on (`pfn::expected`, `pfn::invoke_r`, `pfn::unreachable`). The minimum supported compilers are [gcc 12][gcc-standard-support] and [clang 16][clang-standard-support]; if your OS does not ship one recent enough, use the [devcontainer] or [Nix][nix] (see [nix/README.md][nixmd]). You may also use Apple Clang 16.0 or Microsoft Visual Studio 2022 or newer.
Building and testing libfn needs a C++20 toolchain (with one exception). `pfn` polyfills C++23/26 standard-library utilities (`pfn::expected`, `pfn::optional`, `pfn::invoke_r`, `pfn::unreachable`); `fn` builds on `pfn` rather than the newer standard library. The minimum supported compilers are [gcc 12][gcc-standard-support] and [clang 16][clang-standard-support]; if your OS does not ship one recent enough, use the [devcontainer] or [Nix][nix] (see [nix/README.md][nixmd]). You may also use Apple Clang 16.0 or Microsoft Visual Studio 2022 or newer.

When working with `tests/pfn/expected.cpp` you will need a C++23 compiler, in order to enable the `VALIDATE_CXX23` option for `expected_validation.cpp` tests.

Expand Down
32 changes: 16 additions & 16 deletions include/fn/expected.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ struct expected_policy {
// Storage layer for ::fn::expected. Inherits the standard-conformant base from
// pfn, then hides the four monadic static helpers with sum-widening variants
// that materialise their result via `expected_policy::template type<U, G>`.
template <typename T, typename E> struct _storage : ::pfn::detail::_storage<T, E, expected_policy> {
using _pfn_base = ::pfn::detail::_storage<T, E, expected_policy>;
template <typename T, typename E> struct _expected_base : ::pfn::detail::_expected_base<T, E, expected_policy> {
using _pfn_base = ::pfn::detail::_expected_base<T, E, expected_policy>;
using _pfn_base::_pfn_base;

// and_then, non-void value type
Expand Down Expand Up @@ -248,18 +248,18 @@ template <typename T, typename E> struct _storage : ::pfn::detail::_storage<T, E
} // namespace detail

// Primary template - non-void value type
template <typename T, typename Err> struct expected : private detail::_storage<T, Err> {
using _base = detail::_storage<T, Err>;
template <typename T, typename Err> struct expected : private detail::_expected_base<T, Err> {
using _base = detail::_expected_base<T, Err>;
using value_type = T;
using error_type = Err;
using unexpected_type = ::pfn::unexpected<Err>;
static_assert(not ::std::is_same_v<value_type, ::fn::sum<>>);

template <class U> using rebind = expected<U, error_type>;

// Allow sibling _storage instantiations to downcast into the private base.
template <class, class, class> friend struct ::pfn::detail::_storage;
template <class, class> friend struct ::fn::detail::_storage;
// Allow sibling _expected_base instantiations to downcast into the private base.
template <class, class, class> friend struct ::pfn::detail::_expected_base;
template <class, class> friend struct ::fn::detail::_expected_base;

// Constructors. Explicit forwarders to the base mirror pfn::expected.
constexpr expected() noexcept(::std::is_nothrow_default_constructible_v<T>)
Expand Down Expand Up @@ -414,7 +414,7 @@ template <typename T, typename Err> struct expected : private detail::_storage<T
return *this;
}

// Observers inherited from _storage
// Observers inherited from _expected_base
using _base::operator*;
using _base::operator->;
using _base::operator bool;
Expand All @@ -425,10 +425,10 @@ template <typename T, typename Err> struct expected : private detail::_storage<T
using _base::value;
using _base::value_or;

// Emplace inherited from _storage
// Emplace inherited from _expected_base
using _base::emplace;

// Swap; body delegates to _storage helper
// Swap; body delegates to _expected_base helper
constexpr void
swap(expected &rhs) noexcept(::std::is_nothrow_move_constructible_v<T> && ::std::is_nothrow_swappable_v<T>
&& ::std::is_nothrow_move_constructible_v<Err> && ::std::is_nothrow_swappable_v<Err>)
Expand All @@ -439,7 +439,7 @@ template <typename T, typename Err> struct expected : private detail::_storage<T
this->_swap_with(rhs);
}

// Monadic operations. Bodies delegate to _storage static helpers, which perform sum-widening.
// Monadic operations. Bodies delegate to _expected_base static helpers, which perform sum-widening.
template <class F>
constexpr auto and_then(F &&f) & //
noexcept(noexcept(_base::_and_then(*this, FWD(f)))) // extension
Expand Down Expand Up @@ -636,16 +636,16 @@ template <typename T, typename Err> struct expected : private detail::_storage<T
}
};

template <typename Err> struct expected<void, Err> : private detail::_storage<void, Err> {
using _base = detail::_storage<void, Err>;
template <typename Err> struct expected<void, Err> : private detail::_expected_base<void, Err> {
using _base = detail::_expected_base<void, Err>;
using value_type = void;
using error_type = Err;
using unexpected_type = ::pfn::unexpected<Err>;

template <class U> using rebind = expected<U, error_type>;

template <class, class, class> friend struct ::pfn::detail::_storage;
template <class, class> friend struct ::fn::detail::_storage;
template <class, class, class> friend struct ::pfn::detail::_expected_base;
template <class, class> friend struct ::fn::detail::_expected_base;

constexpr expected() noexcept : _base(::std::in_place) {}

Expand Down Expand Up @@ -766,7 +766,7 @@ template <typename Err> struct expected<void, Err> : private detail::_storage<vo
using _base::has_value;
using _base::value;

// Monadic operations. Bodies delegate to _storage static helpers, which perform sum-widening.
// Monadic operations. Bodies delegate to _expected_base static helpers, which perform sum-widening.
template <class F>
constexpr auto and_then(F &&f) & //
noexcept(noexcept(_base::_and_then(*this, FWD(f)))) // extension
Expand Down
Loading