Skip to content
Merged
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
1 change: 0 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,3 @@ updates:
directory: /
schedule:
interval: daily

37 changes: 20 additions & 17 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,42 @@ repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files

# Clang-format for C++
# This brings in a portable version of clang-format.
# See also: https://github.com/ssciwr/clang-format-wheel
# Clang-format for C++
# This brings in a portable version of clang-format.
# See also: https://github.com/ssciwr/clang-format-wheel
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v21.1.8
hooks:
- id: clang-format
types_or: [c++, c]
- id: clang-format
types_or: [c++, c]

# CMake linting and formatting
# CMake linting and formatting
- repo: https://github.com/BlankSpruce/gersemi
rev: 0.25.1
hooks:
- id: gersemi
name: CMake linting
exclude: ^.*/tests/.*/data/ # Exclude test data directories
- id: gersemi
name: CMake linting
exclude: ^.*/tests/.*/data/ # Exclude test data directories

# Markdown linting
# Config file: .markdownlint.yaml
# Commented out to disable this by default. Uncomment to enable markdown linting.
# Markdown linting
# Config file: .markdownlint.yaml
# Commented out to disable this by default.
# Uncomment to enable markdown linting.
# - repo: https://github.com/igorshubovych/markdownlint-cli
# rev: v0.42.0
# hooks:
# - id: markdownlint
# - id: markdownlint

- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies:
- tomli

exclude: 'cookiecutter/|infra/'
4 changes: 3 additions & 1 deletion include/beman/expected/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@

target_sources(
beman.expected
PUBLIC FILE_SET HEADERS FILES expected.hpp unexpected.hpp
PUBLIC
FILE_SET HEADERS
FILES expected.hpp unexpected.hpp bad_expected_access.hpp
)
51 changes: 51 additions & 0 deletions include/beman/expected/bad_expected_access.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// beman/expected/bad_expected_access.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef BEMAN_EXPECTED_BAD_EXPECTED_ACCESS
#define BEMAN_EXPECTED_BAD_EXPECTED_ACCESS

/***
22.8.4 Class template bad_expected_access[expected.bad]

namespace std {
template<class E>
class bad_expected_access : public bad_expected_access<void> {
public:
constexpr explicit bad_expected_access(E);
constexpr const char* what() const noexcept override;
constexpr E& error() & noexcept;
constexpr const E& error() const & noexcept;
constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;

private:
E unex; // exposition only
};
}
*/

/***
22.8.5 Class template specialization bad_expected_access<void>[expected.bad.void]
namespace std {
template<>
class bad_expected_access<void> : public exception {
protected:
constexpr bad_expected_access() noexcept;
constexpr bad_expected_access(const bad_expected_access&) noexcept;
constexpr bad_expected_access(bad_expected_access&&) noexcept;
constexpr bad_expected_access& operator=(const bad_expected_access&) noexcept;
constexpr bad_expected_access& operator=(bad_expected_access&&) noexcept;
constexpr ~bad_expected_access();

public:
constexpr const char* what() const noexcept override;
};
}
pcc*/
namespace beman {
namespace expected {


}
}

#endif
245 changes: 245 additions & 0 deletions include/beman/expected/expected.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,251 @@
#ifndef BEMAN_EXPECTED_EXPECTED_HPP
#define BEMAN_EXPECTED_EXPECTED_HPP

#include <beman/expected/unexpected.hpp>
#include <beman/expected/bad_expected_access.hpp>

/***
22.8.2 Header <expected> synopsis[expected.syn]

// mostly freestanding
namespace std {
// [expected.unexpected], class template unexpected
template<class E> class unexpected;

// [expected.bad], class template bad_expected_access
template<class E> class bad_expected_access;

// [expected.bad.void], specialization for void
template<> class bad_expected_access<void>;

// in-place construction of unexpected values
struct unexpect_t {
explicit unexpect_t() = default;
};
inline constexpr unexpect_t unexpect{};

// [expected.expected], class template expected
template<class T, class E> class expected; // partially freestanding

// [expected.void], partial specialization of expected for void types
template<class T, class E> requires is_void_v<T> class expected<T, E>; // partially freestanding
}
*/

/***
22.8.6 Class template expected[expected.expected]
22.8.6.1 General[expected.object.general]
namespace std {
template<class T, class E>
class expected {
public:
using value_type = T;
using error_type = E;
using unexpected_type = unexpected<E>;

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

// [expected.object.cons], constructors
constexpr expected();
constexpr expected(const expected&);
constexpr expected(expected&&) noexcept(see below);
template<class U, class G>
constexpr explicit(see below) expected(const expected<U, G>&);
template<class U, class G>
constexpr explicit(see below) expected(expected<U, G>&&);

template<class U = remove_cv_t<T>>
constexpr explicit(see below) expected(U&& v);

template<class G>
constexpr explicit(see below) expected(const unexpected<G>&);
template<class G>
constexpr explicit(see below) expected(unexpected<G>&&);

template<class... Args>
constexpr explicit expected(in_place_t, Args&&...);
template<class U, class... Args>
constexpr explicit expected(in_place_t, initializer_list<U>, Args&&...);
template<class... Args>
constexpr explicit expected(unexpect_t, Args&&...);
template<class U, class... Args>
constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...);

// [expected.object.dtor], destructor
constexpr ~expected();

// [expected.object.assign], assignment
constexpr expected& operator=(const expected&);
constexpr expected& operator=(expected&&) noexcept(see below);
template<class U = remove_cv_t<T>> constexpr expected& operator=(U&&);
template<class G>
constexpr expected& operator=(const unexpected<G>&);
template<class G>
constexpr expected& operator=(unexpected<G>&&);

template<class... Args>
constexpr T& emplace(Args&&...) noexcept;
template<class U, class... Args>
constexpr T& emplace(initializer_list<U>, Args&&...) noexcept;

// [expected.object.swap], swap
constexpr void swap(expected&) noexcept(see below);
friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));

// [expected.object.obs], observers
constexpr const T* operator->() const noexcept;
constexpr T* operator->() noexcept;
constexpr const T& operator*() const & noexcept;
constexpr T& operator*() & noexcept;
constexpr const T&& operator*() const && noexcept;
constexpr T&& operator*() && noexcept;
constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
constexpr const T& value() const &; // freestanding-deleted
constexpr T& value() &; // freestanding-deleted
constexpr const T&& value() const &&; // freestanding-deleted
constexpr T&& value() &&; // freestanding-deleted
constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
constexpr const E&& error() const && noexcept;
constexpr E&& error() && noexcept;
template<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &;
template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&;
template<class G = E> constexpr E error_or(G&&) const &;
template<class G = E> constexpr E error_or(G&&) &&;

// [expected.object.monadic], monadic operations
template<class F> constexpr auto and_then(F&& f) &;
template<class F> constexpr auto and_then(F&& f) &&;
template<class F> constexpr auto and_then(F&& f) const &;
template<class F> constexpr auto and_then(F&& f) const &&;
template<class F> constexpr auto or_else(F&& f) &;
template<class F> constexpr auto or_else(F&& f) &&;
template<class F> constexpr auto or_else(F&& f) const &;
template<class F> constexpr auto or_else(F&& f) const &&;
template<class F> constexpr auto transform(F&& f) &;
template<class F> constexpr auto transform(F&& f) &&;
template<class F> constexpr auto transform(F&& f) const &;
template<class F> constexpr auto transform(F&& f) const &&;
template<class F> constexpr auto transform_error(F&& f) &;
template<class F> constexpr auto transform_error(F&& f) &&;
template<class F> constexpr auto transform_error(F&& f) const &;
template<class F> constexpr auto transform_error(F&& f) const &&;

// [expected.object.eq], equality operators
template<class T2, class E2> requires (!is_void_v<T2>)
friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
template<class T2>
friend constexpr bool operator==(const expected&, const T2&);
template<class E2>
friend constexpr bool operator==(const expected&, const unexpected<E2>&);

private:
bool has_val; // exposition only
union {
T val; // exposition only
E unex; // exposition only
};
};
}
*/

/***
22.8.7 Partial specialization of expected for void types[expected.void]
22.8.7.1 General[expected.void.general]
template<class T, class E> requires is_void_v<T>
class expected<T, E> {
public:
using value_type = T;
using error_type = E;
using unexpected_type = unexpected<E>;

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

// [expected.void.cons], constructors
constexpr expected() noexcept;
constexpr expected(const expected&);
constexpr expected(expected&&) noexcept(see below);
template<class U, class G>
constexpr explicit(see below) expected(const expected<U, G>&);
template<class U, class G>
constexpr explicit(see below) expected(expected<U, G>&&);

template<class G>
constexpr explicit(see below) expected(const unexpected<G>&);
template<class G>
constexpr explicit(see below) expected(unexpected<G>&&);

constexpr explicit expected(in_place_t) noexcept;
template<class... Args>
constexpr explicit expected(unexpect_t, Args&&...);
template<class U, class... Args>
constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...);


// [expected.void.dtor], destructor
constexpr ~expected();

// [expected.void.assign], assignment
constexpr expected& operator=(const expected&);
constexpr expected& operator=(expected&&) noexcept(see below);
template<class G>
constexpr expected& operator=(const unexpected<G>&);
template<class G>
constexpr expected& operator=(unexpected<G>&&);
constexpr void emplace() noexcept;

// [expected.void.swap], swap
constexpr void swap(expected&) noexcept(see below);
friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));

// [expected.void.obs], observers
constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
constexpr void operator*() const noexcept;
constexpr void value() const &; // freestanding-deleted
constexpr void value() &&; // freestanding-deleted
constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
constexpr const E&& error() const && noexcept;
constexpr E&& error() && noexcept;
template<class G = E> constexpr E error_or(G&&) const &;
template<class G = E> constexpr E error_or(G&&) &&;

// [expected.void.monadic], monadic operations
template<class F> constexpr auto and_then(F&& f) &;
template<class F> constexpr auto and_then(F&& f) &&;
template<class F> constexpr auto and_then(F&& f) const &;
template<class F> constexpr auto and_then(F&& f) const &&;
template<class F> constexpr auto or_else(F&& f) &;
template<class F> constexpr auto or_else(F&& f) &&;
template<class F> constexpr auto or_else(F&& f) const &;
template<class F> constexpr auto or_else(F&& f) const &&;
template<class F> constexpr auto transform(F&& f) &;
template<class F> constexpr auto transform(F&& f) &&;
template<class F> constexpr auto transform(F&& f) const &;
template<class F> constexpr auto transform(F&& f) const &&;
template<class F> constexpr auto transform_error(F&& f) &;
template<class F> constexpr auto transform_error(F&& f) &&;
template<class F> constexpr auto transform_error(F&& f) const &;
template<class F> constexpr auto transform_error(F&& f) const &&;

// [expected.void.eq], equality operators
template<class T2, class E2> requires is_void_v<T2>
friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
template<class E2>
friend constexpr bool operator==(const expected&, const unexpected<E2>&);

private:
bool has_val; // exposition only
union {
E unex; // exposition only
};
};
*/

namespace beman {
namespace expected {}
} // namespace beman
Expand Down
Loading
Loading