GithubHelp home page GithubHelp logo

martinmoene / expected-dark Goto Github PK

View Code? Open in Web Editor NEW
52.0 11.0 4.0 103 KB

Expected objects for C++11 and later (and later perhaps C++98 )

License: MIT License

CMake 5.91% C++ 94.09%
cpp11 header-only single-file no-dependencies expected-implementations

expected-dark's Introduction

expected lite - expected objects for C++11 and later

Language Standard License Build Status Build status Version download Try it online

expected lite is a single-file header-only library for objects that either represent a valid value or an error that you can pass by value. It is intended for use with C++11 and later. The library is based on the std::expected proposal [1] .

Contents

Example usage

#include "expected.hpp"

#include <cstdlib>
#include <iostream>
#include <string>

using namespace nonstd;
using namespace std::literals;

auto to_int( char const * const text ) -> expected<int, std::string> 
{
    char * pos = nullptr;
    auto value = strtol( text, &pos, 0 );

    if ( pos != text ) return value;
    else               return make_unexpected( "'"s + text + "' isn't a number" );
}

int main( int argc, char * argv[] )
{
    auto text = argc > 1 ? argv[1] : "42";

    auto ei = to_int( text );

    if ( ei ) std::cout << "'" << text << "' is " << *ei << ", ";
    else      std::cout << "Error: " << ei.error();
}

Compile and run

prompt> g++ -std=c++14 -Wall -I../include/nonstd -o 01-basic.exe 01-basic.cpp && 01-basic.exe 123 && 01-basic.exe abc
'123' is 123, Error: 'abc' isn't a number

In a nutshell

expected lite is a single-file header-only library to represent value objects that either contain a valid value or an error. The library is a partly implementation of the proposal for std::expected [1,2,3] for use with C++11 and later.

Some Features and properties of expected lite are ease of installation (single header), default and explicit construction of an expected, construction and assignment from a value that is convertible to the underlying type, copy- and move-construction and copy- and move-assignment from another expected of the same type, testing for the presence of a value, operators for unchecked access to the value or the error (pointer or reference), value() and value_or() for checked access to the value, relational operators, swap() and various factory functions.

Not provided are reference-type expecteds. expected lite doesn't handle overloaded address of operators.

For more examples, see [1].

License

expected lite uses the MIT license.

Dependencies

expected lite has no other dependencies than the C++ standard library.

Installation

expected lite is a single-file header-only library. Put expected.hpp directly into the project source tree or somewhere reachable from your project.

Synopsis

Contents

Configuration macros

-Dnsel_CONFIG_CONFIRMS_COMPILATION_ERRORS=0
Define this macro to 1 to experience the by-design compile-time errors of the library in the test suite. Default is 0.

Types in namespace nonstd

Purpose Type Object
To be, or not template< typename T, typename E = std::exception_ptr >
class expected;
 
Error type template< typename E >
class unexpected_type;
 
Traits template< typename E >
struct is_unexpected;
 
In-place value construction struct in_place_t; in_place_t in_place{};
In-place error construction struct in_place_unexpected_t; in_place_unexpected_t
unexpect{};
In-place error construction struct in_place_unexpected_t; in_place_unexpected_t
in_place_unexpected{};
Error reporting class bad_expected_access;  

Interface of expected

Kind Method Result
Construction [constexpr] expected() noexcept(...) an object with default value
  [constexpr] expected( expected const & other ) initialize to contents of other
  [constexpr] expected( expected && other ) move contents from other
  [constexpr] expected( value_type const & value ) initialize to value
  [constexpr] expected( value_type && value ) noexcept(...) move from value
  [constexpr] explicit expected( in_place_t, Args&&... args ) construct value in-place from args
  [constexpr] explicit expected( in_place_t,
 std::initializer_list<U> il, Args&&... args )
construct value in-place from args
  [constexpr] expected( unexpected_type const & error ) initialize to error
  [constexpr] expected( unexpected_type && error ) move from error
  [constexpr] explicit expected( in_place_unexpected_t,
 Args&&... args )
construct error in-place from args
  [constexpr] explicit expected( in_place_unexpected_t,
 std::initializer_list<U> il, Args&&... args )
construct error in-place from args
Destruction ~expected() destruct current content
Assignment expected operator=( expected const & other ) assign contents of other;
destruct current content, if any
  expected & operator=( expected && other ) noexcept(...) move contents of other
  expected & operator=( U && v ) move value from v
  expected & operator=( unexpected_type const & u ) initialize to unexpected
  expected & operator=( unexpected_type && u ) move from unexpected
  template< typename... Args >
void emplace( Args &&... args )
emplace from args
  template< typename U, typename... Args >
void emplace( std::initializer_list<U> il, Args &&... args )
emplace from args
Swap void swap( expected & other ) noexcept swap with other
Observers constexpr value_type const * operator->() const pointer to current content (const);
must contain value
  value_type * operator->() pointer to current content (non-const);
must contain value
  constexpr value_type const & operator *() const & the current content (const ref);
must contain value
  constexpr value_type && operator *() && the current content (non-const ref);
must contain value
  constexpr explicit operator bool() const noexcept true if contains value
  constexpr has_value() const noexcept true if contains value
  constexpr value_type const & value() const & current content (const ref);
see note 1
  value_type & value() & current content (non-const ref);
see note 1
  constexpr value_type && value() && move from current content;
see note 1
  constexpr error_type const & error() const & current error (const ref);
must contain error
  error_type & error() & current error (non-const ref);
must contain error
  constexpr error_type && error() && move from current error;
must contain error
  constexpr unexpected_type get_unexpected() const the error as unexpected<>;
must contain error
  template< typename Ex >
bool has_exception() const
true of contains exception (as base)
  value_type value_or( U && v ) const & value or move from v
  value_type value_or( U && v ) && move from value or move from v
  ...  

Note 1: checked access: if no content, for std::exception_ptr rethrows error(), otherwise throws bad_expected_access(error()).

Algorithms for expected

Kind Function
Relational operators  
== != < > <= >= template< typename T, typename E >
constexpr bool operator op(
 expected<T,E> const & x,
 expected<T,E> const & y )
Comparison with unexpected_type  
== != < > <= >= template< typename T, typename E >
constexpr bool operator op(
 expected<T,E> const & x,
 unexpected_type<E> const & u )
  template< typename T, typename E >
constexpr bool operator op(
 unexpected_type<E> const & u,
 expected<T,E> const & x )
Comparison with T  
== != < > <= >= template< typename T, typename E >
constexpr bool operator op(
 expected<T,E> const & x,
 T const & v )
  template< typename T, typename E >
constexpr bool operator op(
 T const & v,
 expected<T,E> const & x )
Specialized algorithms  
Swap template< typename T, typename E >
void swap(
 expected<T,E> & x,
 expected<T,E> & y ) noexcept( noexcept( x.swap(y) ) )
Make expected from  
 Value template< typename T>
constexpr auto make_expected( T && v ) ->
 expected< typename std::decay<T>::type >
 Nothing auto make_expected() -> expected<void>
 Current exception template< typename T>
constexpr auto make_expected_from_current_exception() -> expected<T>
 Exception template< typename T>
auto make_expected_from_exception( std::exception_ptr v ) -> expected<T>
 Error template< typename T, typename E >
constexpr auto make_expected_from_error( E e ) ->
 expected<T, typename std::decay<E>::type>
 Call template< typename F >
auto make_expected_from_call( F f ) ->
 expected< typename std::result_of<F()>::type >
 Call, void specialization template< typename F >
auto make_expected_from_call( F f ) -> expected<void>

Interface of unexpected_type

Kind Method Result
Construction unexpected_type() = delete; no default construction
  constexpr explicit unexpected_type( E const & error ) copy-constructed from an E
  constexpr explicit unexpected_type( E && error ) move-constructed from an E
Observers constexpr error_type const & value() const can observe contained error
  error_type & value() can modify contained error

Algorithms for unexpected_type

Kind Function
Relational operators  
== != < > <= >= template< typename E >
constexpr bool operator op(
 unexpected_type<E> const & x,
 unexpected_type<E> const & y )
== != < > <= >= constexpr bool operator op(
 unexpected_type<std::exception_ptr> const & x,
 unexpected_type<std::exception_ptr> const & y )
Specialized algorithms  
Make unexpected from  
 Current exception [constexpr] auto make_unexpected_from_current_exception() ->
 unexpected_type< std::exception_ptr >
 Error template< typename E>
[constexpr] auto make_unexpected( E && v) ->
 unexpected_type< typename std::decay<E>::type >

Comparison with like types

Feature
std::pair
std:: optional std:: expected nonstd:: expected Boost. Expected Nonco expected Andrei Expected Hagan required
More information see [14] see [5] see [1] this work see [4] see [7] see [8] see [13]
C++03 yes no no no/not yet no (union) no no yes
C++11 yes no no yes yes yes yes yes
C++14 yes no no yes yes yes yes yes
C++17 yes yes no yes yes yes yes yes
DefaultConstructible T param yes yes yes yes no no no
In-place construction no yes yes yes yes yes no no
Literal type yes yes yes yes yes no no no
Disengaged information possible no yes yes yes yes yes no
Vary disengaged type yes no yes yes yes no no no
Engaged nonuse throws no no no no error_traits no no yes
Disengaged use throws no yes, value() yes, value() yes, value() yes,
value()
yes,
get()
yes,
get()
n/a
Proxy (rel.ops) no yes yes yes yes no no no
References no yes no/not yet no/not yet no/not yet yes no no
Chained visitor(s) no no yes maybe yes no no no

Note 1: std::experimental::expected

Note 2: sources for Nonco expected, Andrei Expected and Hagan required can befound in the spike-expected repository.

Reported to work with

Implementation notes

Other implementations of expected

Notes and references

[1] Vicente J. Botet Escriba. p0323 - A proposal to add a utility class to represent expected object (latest) (PDF). (r6, r5, r4, r3, r2, r1, r0, draft).

[2] Vicente J. Botet Escriba. JASEL: Just a simple experimental library for C++. Reference implementation of expected.

[3] Vicente J. Botet Escriba. Expected - An exception-friendly Error Monad. C++Now 2014. 24 September 2014.

[4] Pierre Talbot. Boost.Expected. Unofficial Boost candidate. 5 May 2013. GitHub, GSoC 2013 Proposal, [email protected].

[5] Fernando Cacciola and Andrzej Krzemieński. A proposal to add a utility class to represent optional objects (Revision 4). ISO/IEC JTC1 SC22 WG21 N3672 2013-04-19.

[6] Andrzej Krzemieński, Optional library implementation in C++11.

[7] Anto Nonco. Extending expected to deal with references. 27 May 2013.

[8] Andrei Alexandrescu. Systematic Error Handling in C++. Prepared for The C++and Beyond Seminar 2012. Video. Slides.

[9] Andrei Alexandrescu. Choose your Poison: Exceptions or Error Codes? (PDF). ACCU Conference 2007.

[10] Andrei Alexandrescu. The Power of None (PPT). Northwest C++ Users' Group. May 17th, 2006.

[11] Jon Jagger. A Return Type That Doesn't Like Being Ignored. Overload issue 53, February 2003.

[12] Andrei Alexandrescu. Error Handling in C++: Are we inching towards a total solution?. ACCU Conference 2002.

[13] Ken Hagan et al. Exploding return codes. comp.lang.c++.moderated. 11 February 2000.

[14] std::pair. cppreference.com

[15] Niall Douglas. Outcome. Very lightweight outcome<T> and result<T> (non-Boost edition).

Appendix

A.1 expected lite test specification

unexpected_type<>: Disallows default construction
unexpected_type<>: Disallows default construction, std::exception_ptr specialization
unexpected_type<>: Allows to copy-construct from error_type
unexpected_type<>: Allows to copy-construct from error_type, std::exception_ptr specialization
unexpected_type<>: Allows to move-construct from error_type
unexpected_type<>: Allows to move-construct from error_type, std::exception_ptr specialization
unexpected_type<>: Allows to copy-construct from an exception, std::exception_ptr specialization
unexpected_type<>: Allows to observe its value
unexpected_type<>: Allows to observe its value, std::exception_ptr specialization
unexpected_type<>: Allows to modify its value
unexpected_type<>: Allows to modify its value, std::exception_ptr specialization
unexpected_type<>: Provides relational operators
unexpected_type<>: Provides relational operators, std::exception_ptr specialization
is_unexpected<X>: Is true for unexpected_type
is_unexpected<X>: Is false for non-unexpected_type (int)
make_unexpected(): Allows to create an unexpected_type<E> from an E
make_unexpected_from_current_exception(): Allows to create an unexpected_type<std::exception_ptr> from the current exception
bad_expected_access<>: Disallows default construction
bad_expected_access<>: Allows construction from error_type
bad_expected_access<>: Allows to observe its error
bad_expected_access<>: Allows to change its error
expected<>: Allows default construction
expected<>: Allows to copy-construct from value_type
expected<>: Allows to move-construct from value_type
expected<>: Allows to copy-construct from expected<>
expected<>: Allows to move-construct from expected<>
expected<>: Allows to in-place-construct value_type
expected<>: Allows to copy-construct from unexpected_type<>
expected<>: Allows to move-construct from unexpected_type<>
expected<>: Allows to in-place-construct unexpected_type<>
expected<>: Allows to copy-assign from expected<>
expected<>: Allows to move-assign from expected<>
expected<>: Allows to copy-assign from type convertible to value_type
expected<>: Allows to move-assign from type convertible to value_type
expected<>: Allows to be swapped
expected<>: Allows to observe its value via a pointer
expected<>: Allows to observe its value via a pointer to constant
expected<>: Allows to modify its value via a pointer
expected<>: Allows to observe its value via a reference
expected<>: Allows to observe its value via a r-value reference
expected<>: Allows to modify its value via a reference
expected<>: Allows to observe if it contains a value (or error)
expected<>: Allows to observe its value
expected<>: Allows to modify its value
expected<>: Allows to move its value
expected<>: Allows to observe its error
expected<>: Allows to modify its error
expected<>: Allows to move its error
expected<>: Allows to observe its error as unexpected<>
expected<>: Allows to observe its value if available, or obtain a specified value otherwise
expected<>: Allows to move its value if available, or obtain a specified value otherwise
expected<>: Provides relational operators
...

expected-dark's People

Contributors

hubslave avatar icedtoast avatar laszloashin avatar martinmoene avatar rnburn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

expected-dark's Issues

Update expected-lite to proposal p0323r6 (was 5)

Update expected-lite to proposal p0323r5 p0323r6.
Provide (some) backward compatibility through CMake variable EXPECTED_P0323R.

See also issues:

  • operator== Missing for void specialization, issue #29.

Plan:

  1. unexpected[_type]<E>:
  • constructors
  • destructor (not specified)
  • assignment
  • swap
  • observers
  • relational operators: deprecate less-than comparable (provide for EXPECTED_P0323R<= 2)
  • remove default template parameter std::exception_ptr (provide for EXPECTED_P0323R<= 2)
  • remove unexpected[_type]<std::exception_ptr> specialisation (provide for EXPECTED_P0323R<= 2)
  • alias unexpected_type&ltE> to unexpected<E> for C++17, however
    not for MSVC <= 14.1 due to clash with unexpected()
  1. unexpect tag:
  • struct unexpect_t
  • object unexpect (now inline for C++17)
  • in_place_unexpected_t kept as alias of unexpect_t
  • object in_place_unexpected kept (now inline for C++17)
  1. bad_expected_access:
  • bad_expected_access<T>
  • bad_expected_access<void>
  1. expected<T,E>:
  • constructors
  • destructor
  • assignment
  • swap
  • observers
  • relational operators: deprecate less-than comparable (provide for EXPECTED_P0323R<= 2)
  • comparison with T: deprecate less-than comparable (provide for EXPECTED_P0323R<= 2)
  • comparison with unexpected[_type]<E>: deprecate less-than comparable (provide for EXPECTED_P0323R<= 2)
  • specialised algorithms
  • remove default template parameter std::exception_ptr (provide for EXPECTED_P0323R<= 2)
  1. Traits:
  • is_unexpected<> (not in propsal; provide for EXPECTED_P0323R <= 3)
  • error_traits<E> (not in propsal; provide for EXPECTED_P0323R <= 3)
  • expected_traits<T,E> (not present in expected-lite; removed from proposal in r4)
  1. Factory functions
  • make_expected, deprecate, not useful with two template argument to specify
  • make_unexpected, keep
  1. Test specification
  • Test for all values of nsel_P0323R
  • Identify missing tests
  • Add missing tests
  1. Update documentation
  • Readme

value method is broken for non std::exception_ptr specializations

This code should work

#include "expected.hpp"
#include <system_error>

int main() {
  nonstd::expected<int, std::error_code> e = 12;
  (void)e.value();
  return 0;
}

But it gives this compilation error:

Ryans-MacBook-Pro:expected-lite ryanburn$ clang++ -std=c++11 main.cpp
In file included from main.cpp:1:
./expected.hpp:113:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in
      C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr value_type && value() &&
                            ^
                                    const
./expected.hpp:637:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in
      C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr value_type && operator *() &&
                            ^
                                         const
./expected.hpp:670:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in
      C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr value_type && value() &&
                            ^
                                    const
./expected.hpp:689:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in
      C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr error_type && error() &&
                            ^
                                    const
./expected.hpp:911:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in
      C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr error_type && error() &&
                            ^
                                    const
./expected.hpp:666:41: error: no viable conversion from 'error_type' (aka 'std::__1::error_code') to
      'std::exception_ptr'
            ? ( std::rethrow_exception( contained.error() ), contained.value() )
                                        ^~~~~~~~~~~~~~~~~
main.cpp:6:11: note: in instantiation of member function 'nonstd::expected<int, std::__1::error_code>::value'
      requested here
  (void)e.value();
          ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/exception:131:31: note:
      candidate constructor not viable: no known conversion from 'error_type' (aka 'std::__1::error_code') to
      'nullptr_t' for 1st argument
    _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
                              ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/exception:132:5: note:
      candidate constructor not viable: no known conversion from 'error_type' (aka 'std::__1::error_code') to
      'const std::exception_ptr &' for 1st argument
    exception_ptr(const exception_ptr&) _NOEXCEPT;
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/exception:148:65: note:
      passing argument to parameter here
    friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
                                                                ^
5 warnings and 1 error generated.

The believe the specializations for std::exception_ptr should be using std::enable_if instead of regular conditionals.

Omit unused parameters

Comment-out unused parameters in:

inline constexpr bool operator<( unexpected_type<std::exception_ptr> const & x, unexpected_type<std::exception_ptr> const & y )
inline constexpr bool operator>( unexpected_type<std::exception_ptr> const & x, unexpected_type<std::exception_ptr> const & y )

Change license to BSL

Plan:

  • Request contributors
  • Responses reveived
  • Apply change

$ git log --pretty="%an <%ae>%n%cn <%ce>" |sort |uniq |grep -v moene

std::swap noexcept workaround is inaccurate

The commit b74e3a9 fixes clang 4.0's complaint, but still exhibits a bug. The noexcept specification will check the noexceptness of std::swap(E&, E&), but inside the function, ADL is used, and so swap(E&,E&) may resolve to another swap function besides std::swap. This means that the noexceptness of the function does not match the noexcept declaration. This could cause serious failures.

Add const with constexpr if applicable

clang -std=c++11 warns "warning: 'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const'" for:

prog.cc:113:29:  constexpr value_type && value() &&
prog.cc:637:29: constexpr value_type && operator *() &&
prog.cc:665:29: constexpr value_type && value() &&
prog.cc:684:29: constexpr error_type && error() &&
prog.cc:901:29: constexpr error_type && error() &&

However, it shouldn't in these cases.

Breaks with clang-4.0 and higher.

This code won't compile with clang:

#include "expected.hpp"
#include <system_error>

int main() {
  nonstd::expected<void, std::error_code> e1, e2;
  e2 = e1;
  return 0;
}

It gives the error message:

./expected.hpp:869:67: error: exception specification of 'swap' uses itself
        std::is_nothrow_move_constructible<E>::value && noexcept( swap( std::declval<E&>(), std::declv...
                                                                  ^
./expected.hpp:869:67: note: in instantiation of exception specification for 'swap' requested here
./expected.hpp:842:25: note: in instantiation of exception specification for 'swap' requested here
        expected( rhs ).swap( *this );
                        ^
main.cpp:6:6: note: in instantiation of member function 'nonstd::expected<void,
      std::__1::error_code>::operator=' requested here
  e2 = e1;
     ^
In file included from main.cpp:1:
./expected.hpp:869:93: error: too many arguments to function call, expected single argument 'rhs', have 2
      arguments
  ...&& noexcept( swap( std::declval<E&>(), std::declval<E&>() ) )
                  ~~~~                      ^~~~~~~~~~~~~~~~~~
./expected.hpp:867:5: note: 'swap' declared here
    void swap( expected & rhs ) noexcept

expected<void> + return

Hi, I tried to compile something like that, but I got a compilation error (MSVC2017):

"error C2561: 'initialize': function must return a value"

The code :

nonstd::expected<void, int> initialize() {
if (true)
return; // <-- Compilation error here

        // Here some processing  

}

Any idea to solve this case ?

Compiles with warnings on clang

With the default compiler options, expected-lite generates these warnings when compiling with std=c++11

prog.cc:115:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr value_type && value() &&
                            ^
                                    const
prog.cc:670:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr value_type && operator *() &&
                            ^
                                         const
prog.cc:699:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr value_type && value() &&
                            ^
                                    const
prog.cc:716:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr error_type && error() &&
                            ^
                                    const
prog.cc:938:29: warning: 'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior [-Wconstexpr-not-const]
    constexpr error_type && error() &&
                            ^
                                    const
prog.cc:361:33: warning: unused variable 'unexpect' [-Wunused-const-variable]
constexpr in_place_unexpected_t unexpect{};
                                ^
prog.cc:362:33: warning: unused variable 'in_place_unexpected' [-Wunused-const-variable]
constexpr in_place_unexpected_t in_place_unexpected{};
                                ^
7 warnings generated.

See https://wandbox.org/permlink/EWLHIVPaknnsIS7T

Reference-type support

Is support for reference-type expected planned? I ran into the need, and the workarounds are not great.

operator== Missing for void specialization

When attempting to compare expected objects specialized with a void value type, I get the following error during compilation:

error: no match foroperator*’ (operand type is ‘const nonstd::expected<void, CUSTOM_ERROR_CODE>’) 
        return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;

Obviously this wouldn't compile as you can't compare as the void specialization of expected doesn't (can't) have an implementation of operator*.

Currently, the behavior of the operator== when T is not void is such that the values are compared if a value exists, else just the truthiness is compared, which makes sense. Reference.

Extending this logic to the void specialization would just require comparing the truthiness of the object, as all void expected objects should be equal:

template <typename E>
constexpr bool operator==( expected<void,E> const & x, expected<void,E> const & y )
{
    return bool(x) == bool(y);
}

Is there a reason why the equality operator hasn't been implemented for the void specialization?

Missing include for function

Compiling with clang++

Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

gives the error

expected-lite/include/nonstd/expected.hpp:1207:8: error: explicit specialization of non-template struct 'hash'
struct hash< nonstd::expected<T,E> >
       ^   ~~~~~~~~~~~~~~~~~~~~~~~~~

looks like expected.hpp is missing a #include <functional> which is where std::hash is defined.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.