Skip to content

Commit

Permalink
create base storage type
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverlee committed Dec 29, 2023
1 parent 209eef5 commit 0790b35
Showing 1 changed file with 85 additions and 68 deletions.
153 changes: 85 additions & 68 deletions include/nonstd/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,77 +758,119 @@ typedef

#endif // optional_CONFIG_MAX_ALIGN_HACK

/// C++03 constructed union to hold value.

template< typename T >
struct storage_t
template <typename T, bool = false>
struct base_storage_t
{
//private:
// template< typename > friend class optional;

typedef T value_type;

~storage_t()
#if optional_CPP11_OR_GREATER

using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
aligned_storage_t data;

#elif optional_CONFIG_MAX_ALIGN_HACK

typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;

max_align_t hack;
aligned_storage_t data;

#else
typedef optional_ALIGN_AS(value_type) align_as_type;

typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
aligned_storage_t data;

# undef optional_ALIGN_AS

#endif // optional_CONFIG_MAX_ALIGN_HACK

bool has_value;

~base_storage_t()
{
if ( has_value )
{
destruct_value();
reinterpret_cast<T*>(&data)->~T();
}
}

storage_t() : has_value(false) {}
base_storage_t()
: has_value( false )
{}

explicit storage_t( value_type const & v )
{
construct_value( v );
}

void construct_value( value_type const & v )
#if !optional_CPP11_OR_GREATER

base_storage_t( value_type const & v )
: has_value( true )
{
::new( value_ptr() ) value_type( v );
has_value = true;
::new( &data ) value_type( v );
}

#if optional_CPP11_OR_GREATER
#else

explicit storage_t( value_type && v )
template< class... Args >
base_storage_t( nonstd_lite_in_place_t(T), Args&&... args)
: has_value( true )
{
construct_value( std::move( v ) );
::new( &data ) value_type( std::forward<Args>(args)... );
}

void construct_value( value_type && v )
#endif
};

/// C++03 constructed union to hold value.

template< typename T >
struct storage_t : base_storage_t<T>
{
//private:
// template< typename > friend class optional;

typedef T value_type;

storage_t() : base_storage_t<T>() {}

explicit storage_t( value_type const & v )
: base_storage_t<T>( v )
{}

void copy_construct_value( value_type const & v )
{
::new( const_cast<void *>(static_cast<const volatile void *>(value_ptr())) ) value_type( std::move( v ) );
has_value = true;
assert( not this->has_value );
::new( value_ptr() ) value_type( v );
this->has_value = true;
}

#if optional_CPP11_OR_GREATER

template< class... Args >
storage_t( nonstd_lite_in_place_t(T), Args&&... args )
{
emplace( std::forward<Args>(args)... );
}
: base_storage_t<T>( in_place, std::forward<Args>(args)... )
{}

template< class... Args >
void emplace( Args&&... args )
{
::new( const_cast<void *>(static_cast<const volatile void *>(value_ptr())) ) value_type( std::forward<Args>(args)... );
has_value = true;
this->has_value = true;
}

template< class U, class... Args >
void emplace( std::initializer_list<U> il, Args&&... args )
{
::new( const_cast<void *>(static_cast<const volatile void *>(value_ptr())) ) value_type( il, std::forward<Args>(args)... );
has_value = true;
this->has_value = true;
}

#endif

void destruct_value()
{
assert( has_value );
assert( this->has_value );
value_ptr()->~T();
has_value = false;
this->has_value = false;
}

optional_nodiscard value_type const * value_ptr() const
Expand All @@ -843,13 +885,13 @@ struct storage_t

optional_nodiscard value_type const & value() const optional_ref_qual
{
assert( has_value );
assert( this->has_value );
return * value_ptr();
}

value_type & value() optional_ref_qual
{
assert( has_value );
assert( this->has_value );
return * value_ptr();
}

Expand All @@ -867,39 +909,14 @@ struct storage_t

#endif

#if optional_CPP11_OR_GREATER

using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
aligned_storage_t data;

#elif optional_CONFIG_MAX_ALIGN_HACK

typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;

max_align_t hack;
aligned_storage_t data;

#else
typedef optional_ALIGN_AS(value_type) align_as_type;

typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
aligned_storage_t data;

# undef optional_ALIGN_AS

#endif // optional_CONFIG_MAX_ALIGN_HACK

bool has_value;

optional_nodiscard void * ptr() optional_noexcept
{
return &data;
return &this->data;
}

optional_nodiscard void const * ptr() const optional_noexcept
{
assert( has_value );
return &data;
return &this->data;
}

template <typename U>
Expand Down Expand Up @@ -1004,7 +1021,7 @@ class optional : detail::storage_t< T >
{
if ( other.has_value() )
{
contained().construct_value( other.contained().value() );
contained().copy_construct_value( other.contained().value() );
}
}

Expand All @@ -1023,7 +1040,7 @@ class optional : detail::storage_t< T >
{
if ( other.has_value() )
{
contained().construct_value( std::move( other.contained().value() ) );
contained().emplace( std::move( other.contained().value() ) );
}
}

Expand All @@ -1046,7 +1063,7 @@ class optional : detail::storage_t< T >
{
if ( other.has_value() )
{
contained().construct_value( T{ other.contained().value() } );
contained().emplace( T{ other.contained().value() } );
}
}
#endif // optional_CPP11_OR_GREATER
Expand All @@ -1073,7 +1090,7 @@ class optional : detail::storage_t< T >
{
if ( other.has_value() )
{
contained().construct_value( other.contained().value() );
contained().copy_construct_value( other.contained().value() );
}
}

Expand All @@ -1098,7 +1115,7 @@ class optional : detail::storage_t< T >
{
if ( other.has_value() )
{
contained().construct_value( T{ std::move( other.contained().value() ) } );
contained().emplace( T{ std::move( other.contained().value() ) } );
}
}

Expand All @@ -1122,7 +1139,7 @@ class optional : detail::storage_t< T >
{
if ( other.has_value() )
{
contained().construct_value( std::move( other.contained().value() ) );
contained().emplace( std::move( other.contained().value() ) );
}
}

Expand All @@ -1143,7 +1160,7 @@ class optional : detail::storage_t< T >
)
>
optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
: storage_type( T( il, std::forward<Args>(args)...) )
: storage_type( in_place, T( il, std::forward<Args>(args)...) )
{}

// 8a (C++11) - explicit move construct from value
Expand Down Expand Up @@ -1547,15 +1564,15 @@ class optional : detail::storage_t< T >
void initialize( V const & value )
{
assert( ! has_value() );
contained().construct_value( value );
contained().copy_construct_value( value );
}

#if optional_CPP11_OR_GREATER
template< typename V >
void initialize( V && value )
{
assert( ! has_value() );
contained().construct_value( std::forward<V>( value ) );
contained().emplace( std::forward<V>( value ) );
}

#endif
Expand Down

0 comments on commit 0790b35

Please sign in to comment.