mirror of
https://github.com/boostorg/optional.git
synced 2025-07-20 07:42:06 +02:00
Fix some -Wmaybe-uninitialized warnings
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
[/
|
[/
|
||||||
Boost.Optional
|
Boost.Optional
|
||||||
|
|
||||||
Copyright (c) 2015 - 2022 Andrzej Krzemienski
|
Copyright (c) 2015 - 2023 Andrzej Krzemienski
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
(See accompanying file LICENSE_1_0.txt or copy at
|
(See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -11,6 +11,11 @@
|
|||||||
|
|
||||||
[section:relnotes Release Notes]
|
[section:relnotes Release Notes]
|
||||||
|
|
||||||
|
[heading Boost Release 1.85]
|
||||||
|
|
||||||
|
* Fixed the implementation for trivial types. Now it is slower, because it always initializes the `T`, but it avoids undefined behavior when `optional<T>` is copied. This fixes [@https://github.com/boostorg/optional/issues/108 issue #108].
|
||||||
|
* Fixed some `-Wmaybe-uninitialized` warnings in GCC 12. Thanks to Christian Mazakas for the fix.
|
||||||
|
|
||||||
[heading Boost Release 1.83]
|
[heading Boost Release 1.83]
|
||||||
|
|
||||||
* Deprecated support for C++03 and earlier, C++11 will be required in release 1.86.
|
* Deprecated support for C++03 and earlier, C++11 will be required in release 1.86.
|
||||||
|
@ -67,9 +67,9 @@ void prevent_binding_rvalue_ref_to_optional_lvalue_ref()
|
|||||||
{
|
{
|
||||||
#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
|
#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
|
||||||
BOOST_STATIC_ASSERT_MSG(
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
!boost::is_lvalue_reference<To>::value || !boost::is_rvalue_reference<From>::value,
|
!boost::is_lvalue_reference<To>::value || !boost::is_rvalue_reference<From>::value,
|
||||||
"binding rvalue references to optional lvalue references is disallowed");
|
"binding rvalue references to optional lvalue references is disallowed");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct optional_tag {} ;
|
struct optional_tag {} ;
|
||||||
@ -222,7 +222,7 @@ class optional_base : public optional_tag
|
|||||||
construct(rhs.get_impl());
|
construct(rhs.get_impl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
// Assigns from another optional<T> (deep-moves the rhs value)
|
// Assigns from another optional<T> (deep-moves the rhs value)
|
||||||
void assign ( optional_base&& rhs )
|
void assign ( optional_base&& rhs )
|
||||||
@ -239,7 +239,7 @@ class optional_base : public optional_tag
|
|||||||
construct(boost::move(rhs.get_impl()));
|
construct(boost::move(rhs.get_impl()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
|
// Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
|
||||||
template<class U>
|
template<class U>
|
||||||
@ -253,7 +253,7 @@ class optional_base : public optional_tag
|
|||||||
#else
|
#else
|
||||||
assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
|
assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
else destroy();
|
else destroy();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -286,7 +286,7 @@ class optional_base : public optional_tag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Assigns from a T (deep-copies the rhs value)
|
// Assigns from a T (deep-copies the rhs value)
|
||||||
void assign ( argument_type val )
|
void assign ( argument_type val )
|
||||||
{
|
{
|
||||||
@ -294,7 +294,7 @@ class optional_base : public optional_tag
|
|||||||
assign_value(val, is_reference_predicate() );
|
assign_value(val, is_reference_predicate() );
|
||||||
else construct(val);
|
else construct(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
// Assigns from a T (deep-moves the rhs value)
|
// Assigns from a T (deep-moves the rhs value)
|
||||||
void assign ( rval_reference_type val )
|
void assign ( rval_reference_type val )
|
||||||
@ -355,7 +355,7 @@ class optional_base : public optional_tag
|
|||||||
::new (m_storage.address()) internal_type(val) ;
|
::new (m_storage.address()) internal_type(val) ;
|
||||||
m_initialized = true ;
|
m_initialized = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
void construct ( rval_reference_type val )
|
void construct ( rval_reference_type val )
|
||||||
{
|
{
|
||||||
@ -383,7 +383,7 @@ class optional_base : public optional_tag
|
|||||||
::new (m_storage.address()) internal_type( boost::forward<Arg>(arg) );
|
::new (m_storage.address()) internal_type( boost::forward<Arg>(arg) );
|
||||||
m_initialized = true ;
|
m_initialized = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emplace_assign ()
|
void emplace_assign ()
|
||||||
{
|
{
|
||||||
destroy();
|
destroy();
|
||||||
@ -398,7 +398,7 @@ class optional_base : public optional_tag
|
|||||||
::new (m_storage.address()) internal_type( arg );
|
::new (m_storage.address()) internal_type( arg );
|
||||||
m_initialized = true ;
|
m_initialized = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Arg>
|
template<class Arg>
|
||||||
void emplace_assign ( Arg& arg )
|
void emplace_assign ( Arg& arg )
|
||||||
{
|
{
|
||||||
@ -406,7 +406,7 @@ class optional_base : public optional_tag
|
|||||||
::new (m_storage.address()) internal_type( arg );
|
::new (m_storage.address()) internal_type( arg );
|
||||||
m_initialized = true ;
|
m_initialized = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emplace_assign ()
|
void emplace_assign ()
|
||||||
{
|
{
|
||||||
destroy();
|
destroy();
|
||||||
@ -615,8 +615,8 @@ class optional_base : public optional_tag
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
|
// reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
|
||||||
reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
|
reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *boost::core::launder(p) ; }
|
||||||
reference_type dereference( internal_type* p, is_not_reference_tag ) { return *p ; }
|
reference_type dereference( internal_type* p, is_not_reference_tag ) { return *boost::core::launder(p) ; }
|
||||||
reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; }
|
reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; }
|
||||||
reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; }
|
reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; }
|
||||||
|
|
||||||
@ -677,7 +677,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
// Creates an optional<T> initialized with 'move(val)'.
|
// Creates an optional<T> initialized with 'move(val)'.
|
||||||
// Can throw if T::T(T &&) does
|
// Can throw if T::T(T &&) does
|
||||||
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
|
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
|
||||||
{optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();}
|
{optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -698,7 +698,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
if ( rhs.is_initialized() )
|
if ( rhs.is_initialized() )
|
||||||
this->construct(rhs.get());
|
this->construct(rhs.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
// Creates a deep move of another convertible optional<U>
|
// Creates a deep move of another convertible optional<U>
|
||||||
// Requires a valid conversion from U to T.
|
// Requires a valid conversion from U to T.
|
||||||
@ -727,12 +727,12 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
|
|
||||||
|
|
||||||
template<class Expr>
|
template<class Expr>
|
||||||
explicit optional ( Expr&& expr,
|
explicit optional ( Expr&& expr,
|
||||||
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
|
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
|
||||||
(boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value) ||
|
(boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value) ||
|
||||||
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value, bool >::type = true
|
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value, bool >::type = true
|
||||||
)
|
)
|
||||||
: base(boost::forward<Expr>(expr),boost::addressof(expr))
|
: base(boost::forward<Expr>(expr),boost::addressof(expr))
|
||||||
{optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();}
|
{optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -764,10 +764,10 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
|
|
||||||
template<class Expr>
|
template<class Expr>
|
||||||
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
|
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
|
||||||
boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value ||
|
boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value ||
|
||||||
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value,
|
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value,
|
||||||
optional&
|
optional&
|
||||||
>::type
|
>::type
|
||||||
operator= ( Expr&& expr )
|
operator= ( Expr&& expr )
|
||||||
{
|
{
|
||||||
optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();
|
optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();
|
||||||
@ -794,7 +794,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
this->assign(rhs);
|
this->assign(rhs);
|
||||||
return *this ;
|
return *this ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
// Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
|
// Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
|
||||||
// Requires a valid conversion from U to T.
|
// Requires a valid conversion from U to T.
|
||||||
@ -818,7 +818,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
// Assigns from another optional<T> (deep-moves the rhs value)
|
// Assigns from another optional<T> (deep-moves the rhs value)
|
||||||
optional& operator= ( optional && rhs )
|
optional& operator= ( optional && rhs )
|
||||||
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
|
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
|
||||||
{
|
{
|
||||||
this->assign( static_cast<base &&>(rhs) ) ;
|
this->assign( static_cast<base &&>(rhs) ) ;
|
||||||
@ -852,7 +852,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
this->assign( none_ ) ;
|
this->assign( none_ ) ;
|
||||||
return *this ;
|
return *this ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
// Constructs in-place
|
// Constructs in-place
|
||||||
// upon exception *this is always uninitialized
|
// upon exception *this is always uninitialized
|
||||||
@ -867,7 +867,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
{
|
{
|
||||||
this->emplace_assign( boost::forward<Arg>(arg) );
|
this->emplace_assign( boost::forward<Arg>(arg) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void emplace ()
|
void emplace ()
|
||||||
{
|
{
|
||||||
this->emplace_assign();
|
this->emplace_assign();
|
||||||
@ -878,13 +878,13 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
{
|
{
|
||||||
this->emplace_assign( arg );
|
this->emplace_assign( arg );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Arg>
|
template<class Arg>
|
||||||
void emplace ( Arg& arg )
|
void emplace ( Arg& arg )
|
||||||
{
|
{
|
||||||
this->emplace_assign( arg );
|
this->emplace_assign( arg );
|
||||||
}
|
}
|
||||||
|
|
||||||
void emplace ()
|
void emplace ()
|
||||||
{
|
{
|
||||||
this->emplace_assign();
|
this->emplace_assign();
|
||||||
@ -918,7 +918,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
// Returns a reference to the value if this is initialized, otherwise,
|
// Returns a reference to the value if this is initialized, otherwise,
|
||||||
// the behaviour is UNDEFINED
|
// the behaviour is UNDEFINED
|
||||||
// No-throw
|
// No-throw
|
||||||
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
||||||
reference_const_type operator *() const& { return this->get() ; }
|
reference_const_type operator *() const& { return this->get() ; }
|
||||||
reference_type operator *() & { return this->get() ; }
|
reference_type operator *() & { return this->get() ; }
|
||||||
reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; }
|
reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; }
|
||||||
@ -927,42 +927,42 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
reference_type operator *() { return this->get() ; }
|
reference_type operator *() { return this->get() ; }
|
||||||
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
|
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
|
||||||
|
|
||||||
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
||||||
reference_const_type value() const&
|
reference_const_type value() const&
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return this->get() ;
|
return this->get() ;
|
||||||
else
|
else
|
||||||
throw_exception(bad_optional_access());
|
throw_exception(bad_optional_access());
|
||||||
}
|
}
|
||||||
|
|
||||||
reference_type value() &
|
reference_type value() &
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return this->get() ;
|
return this->get() ;
|
||||||
else
|
else
|
||||||
throw_exception(bad_optional_access());
|
throw_exception(bad_optional_access());
|
||||||
}
|
}
|
||||||
|
|
||||||
reference_type_of_temporary_wrapper value() &&
|
reference_type_of_temporary_wrapper value() &&
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return base::types::move(this->get()) ;
|
return base::types::move(this->get()) ;
|
||||||
else
|
else
|
||||||
throw_exception(bad_optional_access());
|
throw_exception(bad_optional_access());
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
reference_const_type value() const
|
reference_const_type value() const
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return this->get() ;
|
return this->get() ;
|
||||||
else
|
else
|
||||||
throw_exception(bad_optional_access());
|
throw_exception(bad_optional_access());
|
||||||
}
|
}
|
||||||
|
|
||||||
reference_type value()
|
reference_type value()
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return this->get() ;
|
return this->get() ;
|
||||||
else
|
else
|
||||||
@ -974,16 +974,16 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
|
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
|
||||||
template <class U>
|
template <class U>
|
||||||
value_type value_or ( U&& v ) const&
|
value_type value_or ( U&& v ) const&
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return get();
|
return get();
|
||||||
else
|
else
|
||||||
return boost::forward<U>(v);
|
return boost::forward<U>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
value_type value_or ( U&& v ) &&
|
value_type value_or ( U&& v ) &&
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return base::types::move(get());
|
return base::types::move(get());
|
||||||
else
|
else
|
||||||
@ -991,7 +991,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
}
|
}
|
||||||
#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
template <class U>
|
template <class U>
|
||||||
value_type value_or ( U&& v ) const
|
value_type value_or ( U&& v ) const
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return get();
|
return get();
|
||||||
@ -1000,17 +1000,17 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template <class U>
|
template <class U>
|
||||||
value_type value_or ( U const& v ) const
|
value_type value_or ( U const& v ) const
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return get();
|
return get();
|
||||||
else
|
else
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
value_type value_or ( U& v ) const
|
value_type value_or ( U& v ) const
|
||||||
{
|
{
|
||||||
if (this->is_initialized())
|
if (this->is_initialized())
|
||||||
return get();
|
return get();
|
||||||
else
|
else
|
||||||
@ -1028,7 +1028,7 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
else
|
else
|
||||||
return f();
|
return f();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
value_type value_or_eval ( F f ) &&
|
value_type value_or_eval ( F f ) &&
|
||||||
{
|
{
|
||||||
@ -1047,9 +1047,9 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
return f();
|
return f();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
|
bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
|
||||||
|
|
||||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -60,9 +60,9 @@ class aligned_storage
|
|||||||
T * ptr_ref() { return static_cast<T *> (address()); }
|
T * ptr_ref() { return static_cast<T *> (address()); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
T const& ref() const { return *ptr_ref(); }
|
T const& ref() const { return *boost::core::launder(ptr_ref()); }
|
||||||
T & ref() { return *ptr_ref(); }
|
T & ref() { return *boost::core::launder(ptr_ref()); }
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
} // namespace optional_detail
|
} // namespace optional_detail
|
||||||
|
@ -35,11 +35,11 @@ class tc_optional_base : public optional_tag
|
|||||||
|
|
||||||
tc_optional_base()
|
tc_optional_base()
|
||||||
:
|
:
|
||||||
m_initialized(false) {}
|
m_initialized(false), m_storage() {}
|
||||||
|
|
||||||
tc_optional_base ( none_t )
|
tc_optional_base ( none_t )
|
||||||
:
|
:
|
||||||
m_initialized(false) {}
|
m_initialized(false), m_storage() {}
|
||||||
|
|
||||||
tc_optional_base ( init_value_tag, argument_type val )
|
tc_optional_base ( init_value_tag, argument_type val )
|
||||||
:
|
:
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <boost/core/enable_if.hpp>
|
#include <boost/core/enable_if.hpp>
|
||||||
#include <boost/core/explicit_operator_bool.hpp>
|
#include <boost/core/explicit_operator_bool.hpp>
|
||||||
#include <boost/core/invoke_swap.hpp>
|
#include <boost/core/invoke_swap.hpp>
|
||||||
|
#include <boost/core/launder.hpp>
|
||||||
#include <boost/optional/bad_optional_access.hpp>
|
#include <boost/optional/bad_optional_access.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
|
@ -20,6 +20,7 @@ import testing ;
|
|||||||
[ run optional_test.cpp ]
|
[ run optional_test.cpp ]
|
||||||
[ run optional_test_assign.cpp ]
|
[ run optional_test_assign.cpp ]
|
||||||
[ run optional_test_swap.cpp ]
|
[ run optional_test_swap.cpp ]
|
||||||
|
[ compile optional_test_wuninitialized.cpp ]
|
||||||
[ run optional_test_conversions_from_U.cpp ]
|
[ run optional_test_conversions_from_U.cpp ]
|
||||||
[ run optional_test_convert_from_T.cpp ]
|
[ run optional_test_convert_from_T.cpp ]
|
||||||
[ run optional_test_convert_assign.cpp ]
|
[ run optional_test_convert_assign.cpp ]
|
||||||
|
156
test/optional_test_wuninitialized.cpp
Normal file
156
test/optional_test_wuninitialized.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
// Copyright (C) 2023 Andrzej Krzemienski.
|
||||||
|
//
|
||||||
|
// Use, modification, and distribution is subject to the Boost Software
|
||||||
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/lib/optional for documentation.
|
||||||
|
//
|
||||||
|
// You are welcome to contact the author at:
|
||||||
|
// akrzemi1@gmail.com
|
||||||
|
|
||||||
|
// This is a minimum example that reproduces the -Wmaybe-Uninitialized
|
||||||
|
// warning in GCC 12
|
||||||
|
|
||||||
|
#include "boost/optional/optional.hpp"
|
||||||
|
|
||||||
|
#include "boost/none.hpp"
|
||||||
|
|
||||||
|
#include "boost/core/lightweight_test.hpp"
|
||||||
|
|
||||||
|
using boost::optional ;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||||
|
using boost::get ;
|
||||||
|
using boost::get_pointer ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool throw_on_assign = false;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
class X
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
X ( int av = 0) : v(av)
|
||||||
|
{
|
||||||
|
++ count ;
|
||||||
|
}
|
||||||
|
|
||||||
|
X ( X const& rhs ) : v(rhs.v)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~X()
|
||||||
|
{
|
||||||
|
-- count ;
|
||||||
|
}
|
||||||
|
|
||||||
|
X& operator= ( X const& rhs )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if ( throw_on_assign )
|
||||||
|
{
|
||||||
|
v = rhs.v ;
|
||||||
|
|
||||||
|
}
|
||||||
|
return *this ;
|
||||||
|
}
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
int v ;
|
||||||
|
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void check_uninitialized ( optional<T>& opt )
|
||||||
|
{
|
||||||
|
BOOST_TEST( !opt.get_ptr() ) ;
|
||||||
|
BOOST_TEST( !opt.get_ptr() ) ;
|
||||||
|
BOOST_TEST( opt.is_initialized()) ;
|
||||||
|
BOOST_TEST( opt.is_initialized() ) ;
|
||||||
|
BOOST_TEST( opt.is_initialized() ) ;
|
||||||
|
BOOST_TEST( opt.is_initialized()) ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void check_initialized_const ( optional<T> const& opt )
|
||||||
|
{
|
||||||
|
BOOST_TEST ( opt.get_ptr() ) ;
|
||||||
|
BOOST_TEST ( opt.get_ptr() ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void check_initialized ( optional<T>& opt )
|
||||||
|
{
|
||||||
|
|
||||||
|
BOOST_TEST ( opt.get_ptr() ) ;
|
||||||
|
BOOST_TEST ( opt.get_ptr() ) ;
|
||||||
|
BOOST_TEST ( opt.has_value() ) ;
|
||||||
|
BOOST_TEST ( opt.has_value() ) ;
|
||||||
|
BOOST_TEST( opt.has_value() ) ;
|
||||||
|
BOOST_TEST ( opt.has_value() ) ;
|
||||||
|
|
||||||
|
check_initialized_const(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_default_implicit_construction ( double, optional<double> opt )
|
||||||
|
{
|
||||||
|
BOOST_TEST(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_default_implicit_construction ( X const&, optional<X> opt )
|
||||||
|
{
|
||||||
|
BOOST_TEST(!opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void test_basics( )
|
||||||
|
{
|
||||||
|
T a(1);
|
||||||
|
|
||||||
|
optional<T> def ;
|
||||||
|
check_uninitialized(def);
|
||||||
|
|
||||||
|
|
||||||
|
optional<T> oa ( a ) ;
|
||||||
|
check_initialized(oa);
|
||||||
|
|
||||||
|
oa = a ;
|
||||||
|
oa = a;
|
||||||
|
check_initialized(oa);
|
||||||
|
|
||||||
|
optional<T> const oa2 ( oa ) ;
|
||||||
|
check_initialized_const(oa2);
|
||||||
|
|
||||||
|
oa = oa ;
|
||||||
|
check_initialized(oa);
|
||||||
|
|
||||||
|
oa = def ;
|
||||||
|
oa = def ;
|
||||||
|
check_uninitialized(oa);
|
||||||
|
check_uninitialized(oa);
|
||||||
|
|
||||||
|
oa.reset();
|
||||||
|
|
||||||
|
|
||||||
|
check_uninitialized(oa);
|
||||||
|
check_uninitialized(oa);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_basics<X>( );
|
||||||
|
//return boost::report_errors();
|
||||||
|
}
|
Reference in New Issue
Block a user