expected-lite icon indicating copy to clipboard operation
expected-lite copied to clipboard

expected<bool, E> doesn't work correctly

Open vsuponev opened this issue 3 years ago • 1 comments

Move-constructor expected( U && value of expected calls contained.construct_value( std::forward<U>( value ) ); which leads to new(&m_value) value_type(std::forward<Args>(args)...); which degrades to calling new(&m_value) bool(std::forward<Args>(args)...); in the case of E=bool.

This means that if the expected object passed as rvalue has a value of false, the bool operator will still return true as it only checks has_value().

vsuponev avatar Dec 02 '20 12:12 vsuponev

A specialized version of storage_t seems to resolve this issue. I may have provided more member functions than required, but this is a fast fix as an inspiration. Also, I do not think we need placement new in such a trivial case.

Upd.: No idea what gh does with code formatting here...

/// discriminated union to hold bool and 'error'. template< typename E > union storage_t<bool, E> { friend class expected<bool,E>;

private: using error_type = E;

// no-op construction
storage_t() {}
~storage_t() {}

void construct_value(bool value)
{
    m_value = value;
}

void construct_value(const expected<bool,E> &value)
{
    m_value = value.value();
}

void construct_value(expected<bool,E> &&value)
{
    m_value = value.value();
}

void destruct_value() {}

void construct_error( error_type const & e )
{
    new( &m_error ) error_type( e );
}

void construct_error( error_type && e )
{
    new( &m_error ) error_type( std::move( e ) );
}

void destruct_error()
{
    m_error.~error_type();
}

constexpr bool const & value() const &
{
    return m_value;
}

bool & value() &
{
    return m_value;
}

constexpr bool const && value() const &&
{
    return std::move( m_value );
}

nsel_constexpr14 bool && value() &&
{
    return std::move( m_value );
}

bool const * value_ptr() const
{
    return &m_value;
}

bool * value_ptr()
{
    return &m_value;
}

error_type const & error() const
{
    return m_error;
}

error_type & error()
{
    return m_error;
}

private: bool m_value; error_type m_error; };

vsuponev avatar Dec 02 '20 16:12 vsuponev