Alien-libpanda

 view release on metacpan or  search on metacpan

src/panda/expected.h  view on Meta::CPAN

        if (ex._has_val) construct_val(ex._val);
        else             construct_err(ex._err);
    }

    template <class T2, class E2>
    explicit expected (expected<T2,E2>&& ex) {
        if (ex._has_val) construct_val(std::move(ex._val));
        else             construct_err(std::move(ex._err));
    }

    template <class T2, typename = typename std::enable_if<std::is_constructible<T, T2>::value>::type>
    expected (T2&& v) {
        construct_val(std::forward<T2>(v));
    }

    template <class E2>
    expected (const unexpected<E2>& uex) {
        construct_err(uex.value());
    }

    template <class E2>
    expected (unexpected<E2>&& uex) {
        construct_err(std::move(uex.value()));
    }

    ~expected () {
        if (_has_val) _val.~T();
        else          _err.~E();
    }

    expected& operator= (const expected& ex) {
        if (ex._has_val) set_val(ex._val);
        else             set_err(ex._err);
        return *this;
    }

    expected& operator= (expected&& ex) {
        if (ex._has_val) set_val(std::move(ex._val));
        else             set_err(std::move(ex._err));
        return *this;
    }

    template <class T2>
    expected& operator= (T2&& v) {
        set_val(std::forward<T2>(v));
    }

    template <class E2>
    expected& operator= (const unexpected<E2>& uex) {
        set_err(uex.value());
    }

    template <class E2>
    expected& operator= (unexpected<E2>&& uex) {
        set_err(std::move(uex.value()));
    }

    constexpr bool     has_value     () const noexcept { return _has_val; }
    constexpr explicit operator bool () const noexcept { return _has_val; }

    const T&  value () const &  { if (!_has_val) throw bad_expected_access<E>(_err); return _val; }
          T&  value ()       &  { if (!_has_val) throw bad_expected_access<E>(_err); return _val; }
    const T&& value () const && { if (!_has_val) throw bad_expected_access<E>(_err); return std::move(_val); }
          T&& value ()       && { if (!_has_val) throw bad_expected_access<E>(_err); return std::move(_val); }

    template <class T2> constexpr T value_or (T2&& v) const & { return bool(*this) ? this->_val : static_cast<T>(std::forward<T2>(v)); }
    template <class T2> constexpr T value_or (T2&& v)      && { return bool(*this) ? std::move(this->_val) : static_cast<T>(std::forward<T2>(v)); }

    const E&  error () const &  { return _err; }
          E&  error ()       &  { return _err; }
    const E&& error () const && { return std::move(_err); }
          E&& error ()       && { return std::move(_err); }

    const T* operator-> () const { return &_val; }
          T* operator-> ()       { return &_val; }

    const T&  operator* () const &  { return _val; }
          T&  operator* ()       &  { return _val; }
    const T&& operator* () const && { return std::move(_val); }
          T&& operator* ()       && { return std::move(_val); }

    template <class...Args>
    void emplace (Args&&... args) {
        if (_has_val) _val = T(std::forward<Args>(args)...);
        else {
            auto tmp = std::move(_err);
            _err.~E();
            try {
                ::new (&_val) T(std::forward<Args>(args)...);
                _has_val = true;
            } catch (...) {
                new (&_err) E(std::move(tmp));
                throw;
            }
        }
    }

    template <class F>
    auto and_then (F&& f) const & -> decltype(f(std::declval<T>())) {
        if (!_has_val) return unexpected_type(_err);
        return f(_val);
    }

    template <class F>
    auto and_then (F&& f) const && -> decltype(f(std::declval<T>())) {
        if (!_has_val) return unexpected_type(std::move(_err));
        return f(std::move(_val));
    }

    template <class F>
    auto or_else (F&& f) const & -> decltype(f(std::declval<E>())) {
        if (_has_val) return *this;
        return f(_err);
    }

    template <class F>
    auto or_else (F&& f) const && -> decltype(f(std::declval<E>())) {
        if (_has_val) return std::move(*this);
        return f(std::move(_err));
    }

    template <class F>
    auto map (F&& f) const & -> expected<decltype(f(std::declval<T>())), E> {
        if (!_has_val) return unexpected_type(_err);
        return f(_val);
    }

    template <class F>
    auto map (F&& f) const && -> expected<decltype(f(std::declval<T>())), E> {
        if (!_has_val) return unexpected_type(std::move(_err));
        return f(std::move(_val));
    }

    template <class F>
    auto map_error (F&& f) const & -> expected<T, decltype(f(std::declval<E>()))> {
        if (_has_val) return _val;
        return make_unexpected(f(_err));
    }

    template <class F>
    auto map_error (F&& f) const && -> expected<T, decltype(f(std::declval<E>()))> {
        if (_has_val) return std::move(_val);
        return make_unexpected(f(std::move(_err)));
    }

    template <class T2 = T>
    void swap (expected& ex) {
        if (_has_val) {
            if (ex._has_val) std::swap(_val, ex._val);
            else {
                auto tmp = std::move(ex._err);
                ex._err.~E();
                ex._has_val = true;



( run in 0.813 second using v1.01-cache-2.11-cpan-d7f47b0818f )