mirror of
https://github.com/boostorg/optional.git
synced 2026-06-11 11:51:30 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f564e11dea |
@@ -23,13 +23,20 @@
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#ifndef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#endif
|
||||
|
||||
// This is needed for C++11, where constexpr functions must contain a single expression.
|
||||
// We want to assert and then return.
|
||||
#if defined NDEBUG
|
||||
# define BOOST_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
|
||||
#else
|
||||
# define BOOST_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{BOOST_ASSERT(!(#CHECK));}(), (EXPR)))
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_CXX14_CONSTEXPR
|
||||
#ifdef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
# define BOOST_OPTIONAL_DECAY(T) typename ::std::decay<T>::type
|
||||
# define BOOST_OPTIONAL_IS_TAGGED(TAG, U) ::std::is_base_of<TAG, BOOST_OPTIONAL_DECAY(U)>
|
||||
#else
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
#define BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP
|
||||
|
||||
#ifdef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
|
||||
#ifndef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifdef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
# define BOOST_OPTIONAL_TT_PREFIX ::std
|
||||
#else
|
||||
# define BOOST_OPTIONAL_TT_PREFIX boost
|
||||
@@ -135,27 +135,27 @@ public:
|
||||
typedef T* pointer_type;
|
||||
typedef T* pointer_const_type;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR optional() BOOST_NOEXCEPT : ptr_() {}
|
||||
BOOST_CXX14_CONSTEXPR optional(none_t) BOOST_NOEXCEPT : ptr_() {}
|
||||
BOOST_CONSTEXPR optional() BOOST_NOEXCEPT : ptr_() {}
|
||||
BOOST_CONSTEXPR optional(none_t) BOOST_NOEXCEPT : ptr_() {}
|
||||
|
||||
template <class U>
|
||||
BOOST_CXX14_CONSTEXPR explicit optional(const optional<U&>& rhs) BOOST_NOEXCEPT : ptr_(rhs.get_ptr()) {}
|
||||
BOOST_CXX14_CONSTEXPR optional(const optional& rhs) BOOST_NOEXCEPT : ptr_(rhs.get_ptr()) {}
|
||||
BOOST_CONSTEXPR explicit optional(const optional<U&>& rhs) BOOST_NOEXCEPT : ptr_(rhs.get_ptr()) {}
|
||||
BOOST_CONSTEXPR optional(const optional& rhs) BOOST_NOEXCEPT : ptr_(rhs.get_ptr()) {}
|
||||
|
||||
// the following two implement a 'conditionally explicit' constructor: condition is a hack for buggy compilers with screwed conversion construction from const int
|
||||
template <class U,
|
||||
BOOST_OPTIONAL_REQUIRES(detail::is_same_decayed<T, U>),
|
||||
BOOST_OPTIONAL_REQUIRES(detail::is_const_integral_bad_for_conversion<U>)>
|
||||
BOOST_CXX14_CONSTEXPR explicit
|
||||
optional(U& rhs) BOOST_NOEXCEPT
|
||||
: ptr_(boost::addressof(rhs)) {}
|
||||
BOOST_CONSTEXPR explicit
|
||||
optional(U& rhs) BOOST_NOEXCEPT
|
||||
: ptr_(boost::addressof(rhs)) {}
|
||||
|
||||
template <class U,
|
||||
BOOST_OPTIONAL_REQUIRES(detail::is_same_decayed<T, U>),
|
||||
BOOST_OPTIONAL_REQUIRES(!detail::is_const_integral_bad_for_conversion<U>)>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
optional(U& rhs) BOOST_NOEXCEPT
|
||||
: ptr_(boost::addressof(rhs)) {}
|
||||
BOOST_CONSTEXPR
|
||||
optional(U& rhs) BOOST_NOEXCEPT
|
||||
: ptr_(boost::addressof(rhs)) {}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR optional& operator=(const optional& rhs) BOOST_NOEXCEPT { ptr_ = rhs.get_ptr(); return *this; }
|
||||
template <class U>
|
||||
@@ -164,50 +164,47 @@ public:
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR void swap(optional& rhs) BOOST_NOEXCEPT { ::std::swap(ptr_, rhs.ptr_); }
|
||||
BOOST_CXX14_CONSTEXPR T& get() const { BOOST_ASSERT(ptr_); return *ptr_; }
|
||||
constexpr T& get() const { return BOOST_OPTIONAL_ASSERTED_EXPRESSION(ptr_, *ptr_); }
|
||||
|
||||
BOOST_CXX14_CONSTEXPR T* get_ptr() const BOOST_NOEXCEPT { return ptr_; }
|
||||
BOOST_CXX14_CONSTEXPR T* operator->() const { BOOST_ASSERT(ptr_); return ptr_; }
|
||||
BOOST_CXX14_CONSTEXPR T& operator*() const { BOOST_ASSERT(ptr_); return *ptr_; }
|
||||
constexpr T* get_ptr() const BOOST_NOEXCEPT { return ptr_; }
|
||||
constexpr T* operator->() const { return BOOST_OPTIONAL_ASSERTED_EXPRESSION(ptr_, ptr_); }
|
||||
constexpr T& operator*() const { return BOOST_OPTIONAL_ASSERTED_EXPRESSION(ptr_, *ptr_); }
|
||||
|
||||
BOOST_CXX14_CONSTEXPR T& value() const
|
||||
constexpr T& value() const
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return this->get();
|
||||
else
|
||||
boost::throw_exception(boost::bad_optional_access());
|
||||
return this->is_initialized() ?
|
||||
this->get() :
|
||||
(boost::throw_exception(boost::bad_optional_access()), this->get());
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT { return ptr_ != 0; }
|
||||
constexpr explicit operator bool() const BOOST_NOEXCEPT { return ptr_ != 0; }
|
||||
|
||||
BOOST_CXX14_CONSTEXPR void reset() BOOST_NOEXCEPT { ptr_ = 0; }
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool is_initialized() const BOOST_NOEXCEPT { return ptr_ != 0; }
|
||||
BOOST_CXX14_CONSTEXPR bool has_value() const BOOST_NOEXCEPT { return ptr_ != 0; }
|
||||
constexpr bool is_initialized() const BOOST_NOEXCEPT { return ptr_ != 0; }
|
||||
constexpr bool has_value() const BOOST_NOEXCEPT { return ptr_ != 0; }
|
||||
|
||||
template <typename F>
|
||||
BOOST_CXX14_CONSTEXPR optional<typename optional_detail::result_of<F, reference_const_type>::type>
|
||||
constexpr optional<typename optional_detail::result_of<F, reference_const_type>::type>
|
||||
map(F f) const
|
||||
{
|
||||
if (this->has_value())
|
||||
return f(this->get());
|
||||
else
|
||||
return none;
|
||||
return this->has_value() ?
|
||||
f(get()) :
|
||||
optional<typename optional_detail::result_of<F, reference_const_type>::type>();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
BOOST_CXX14_CONSTEXPR optional<typename optional_detail::result_value_type<F, reference_const_type>::type>
|
||||
constexpr optional<typename optional_detail::result_value_type<F, reference_const_type>::type>
|
||||
flat_map(F f) const
|
||||
{
|
||||
if (this->has_value())
|
||||
return f(get());
|
||||
else
|
||||
return none;
|
||||
return this->has_value() ?
|
||||
f(get()) :
|
||||
optional<typename optional_detail::result_value_type<F, reference_const_type>::type>();
|
||||
}
|
||||
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
|
||||
BOOST_CXX14_CONSTEXPR optional(T&& /* rhs */) BOOST_NOEXCEPT { detail::prevent_binding_rvalue<T&&>(); }
|
||||
optional(T&& /* rhs */) BOOST_NOEXCEPT { detail::prevent_binding_rvalue<T&&>(); }
|
||||
|
||||
template <class R, BOOST_OPTIONAL_REQUIRES(detail::no_unboxing_cond<T, R>)>
|
||||
BOOST_CXX14_CONSTEXPR optional(R&& r) BOOST_NOEXCEPT
|
||||
|
||||
@@ -25,32 +25,32 @@ namespace boost {
|
||||
//
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator == ( optional<T> const& x, optional<T> const& y )
|
||||
{ return bool(x) && bool(y) ? *x == *y : bool(x) == bool(y); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator < ( optional<T> const& x, optional<T> const& y )
|
||||
{ return !y ? false : (!x ? true : (*x) < (*y)); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator != ( optional<T> const& x, optional<T> const& y )
|
||||
{ return !( x == y ) ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator > ( optional<T> const& x, optional<T> const& y )
|
||||
{ return y < x ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator <= ( optional<T> const& x, optional<T> const& y )
|
||||
{ return !( y < x ) ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator >= ( optional<T> const& x, optional<T> const& y )
|
||||
{ return !( x < y ) ; }
|
||||
|
||||
@@ -59,32 +59,32 @@ bool operator >= ( optional<T> const& x, optional<T> const& y )
|
||||
// optional<T> vs T cases
|
||||
//
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator == ( optional<T> const& x, T const& y )
|
||||
{ return x && (*x == y); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator < ( optional<T> const& x, T const& y )
|
||||
{ return (!x) || (*x < y); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator != ( optional<T> const& x, T const& y )
|
||||
{ return !( x == y ) ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator > ( optional<T> const& x, T const& y )
|
||||
{ return y < x ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator <= ( optional<T> const& x, T const& y )
|
||||
{ return !( y < x ) ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator >= ( optional<T> const& x, T const& y )
|
||||
{ return !( x < y ) ; }
|
||||
|
||||
@@ -93,32 +93,32 @@ bool operator >= ( optional<T> const& x, T const& y )
|
||||
//
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator == ( T const& x, optional<T> const& y )
|
||||
{ return y && (x == *y); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator < ( T const& x, optional<T> const& y )
|
||||
{ return y && (x < *y); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator != ( T const& x, optional<T> const& y )
|
||||
{ return !( x == y ) ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator > ( T const& x, optional<T> const& y )
|
||||
{ return y < x ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator <= ( T const& x, optional<T> const& y )
|
||||
{ return !( y < x ) ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator >= ( T const& x, optional<T> const& y )
|
||||
{ return !( x < y ) ; }
|
||||
|
||||
@@ -128,32 +128,32 @@ bool operator >= ( T const& x, optional<T> const& y )
|
||||
//
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator == ( optional<T> const& x, none_t ) BOOST_NOEXCEPT
|
||||
{ return !x; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator < ( optional<T> const&, none_t ) BOOST_NOEXCEPT
|
||||
{ return false; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator != ( optional<T> const& x, none_t ) BOOST_NOEXCEPT
|
||||
{ return bool(x); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator > ( optional<T> const& x, none_t y ) BOOST_NOEXCEPT
|
||||
{ return y < x ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator <= ( optional<T> const& x, none_t y ) BOOST_NOEXCEPT
|
||||
{ return !( y < x ) ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator >= ( optional<T> const& x, none_t y ) BOOST_NOEXCEPT
|
||||
{ return !( x < y ) ; }
|
||||
|
||||
@@ -162,32 +162,32 @@ bool operator >= ( optional<T> const& x, none_t y ) BOOST_NOEXCEPT
|
||||
//
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator == ( none_t , optional<T> const& y ) BOOST_NOEXCEPT
|
||||
{ return !y; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator < ( none_t , optional<T> const& y ) BOOST_NOEXCEPT
|
||||
{ return bool(y); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator != ( none_t, optional<T> const& y ) BOOST_NOEXCEPT
|
||||
{ return bool(y); }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator > ( none_t x, optional<T> const& y ) BOOST_NOEXCEPT
|
||||
{ return y < x ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator <= ( none_t x, optional<T> const& y ) BOOST_NOEXCEPT
|
||||
{ return !( y < x ) ; }
|
||||
|
||||
template<class T>
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
inline BOOST_CONSTEXPR
|
||||
bool operator >= ( none_t x, optional<T> const& y ) BOOST_NOEXCEPT
|
||||
{ return !( x < y ) ; }
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2026 Andrzej Krzemieński.
|
||||
//
|
||||
// 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/libs/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
//
|
||||
// This header provides definitions required by any specialization of
|
||||
// optional<>.
|
||||
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_SELECT_IMPLEMENTATION_01FEB2026_HPP
|
||||
#define BOOST_OPTIONAL_DETAIL_OPTIONAL_SELECT_IMPLEMENTATION_01FEB2026_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && \
|
||||
!defined(BOOST_NO_CXX11_REF_QUALIFIERS) && \
|
||||
!defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && \
|
||||
!defined(BOOST_NO_CXX11_UNRESTRICTED_UNION) && \
|
||||
!defined(BOOST_NO_CXX11_NOEXCEPT) && \
|
||||
!defined(BOOST_NO_CXX11_DEFAULTED_MOVES)
|
||||
# define BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
|
||||
// In C++20 we have `std::construct_at()` which is a constexpr equivalent of
|
||||
// placement-new. We can then make more functions constexpr.
|
||||
// TBD: This additional constexpr-ication is left for the future.
|
||||
# define BOOST_OPTIONAL_CXX20_CONSTEXPR
|
||||
|
||||
#endif //BOOST_OPTIONAL_DETAIL_OPTIONAL_SELECT_IMPLEMENTATION_01FEB2026_HPP
|
||||
+136
-79
@@ -13,13 +13,12 @@
|
||||
// This header provides definitions required by any specialization of
|
||||
// optional<>.
|
||||
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_CONSTEXPR_OPTIONAL_01FEB2026_HPP
|
||||
#define BOOST_OPTIONAL_DETAIL_CONSTEXPR_OPTIONAL_01FEB2026_HPP
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_UNION_OPTIONAL_01FEB2026_HPP
|
||||
#define BOOST_OPTIONAL_DETAIL_UNION_OPTIONAL_01FEB2026_HPP
|
||||
|
||||
#include <initializer_list>
|
||||
//#include <initializer_list>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/invoke_swap.hpp>
|
||||
#include <boost/core/invoke_swap.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/optional/bad_optional_access.hpp>
|
||||
|
||||
@@ -30,12 +29,20 @@
|
||||
# define BOOST_OPTIONAL_REQUIRES(...) typename ::std::enable_if<__VA_ARGS__::value, bool>::type = false
|
||||
|
||||
|
||||
// In C++20 we have `std::construct_at()` which is a constexpr equivalent of
|
||||
// placement-new. We can then make more functions constexpr.
|
||||
// TBD: This additional constexpr-ication is left for the future.
|
||||
# define BOOST_OPTIONAL_CXX20_CONSTEXPR
|
||||
# ifdef __cpp_guaranteed_copy_elision
|
||||
# if __cpp_guaranteed_copy_elision
|
||||
# define BOOST_OPTIONAL_CONSTEXPR_COPY
|
||||
# endif
|
||||
# endif
|
||||
|
||||
|
||||
template <typename T, typename U>
|
||||
struct fail_hard_on_nonconvertible
|
||||
{
|
||||
static_assert(::std::is_convertible<U&&, T>::value, "The argument must be convertible to T");
|
||||
using type = bool;
|
||||
};
|
||||
|
||||
// Missing C++17 type traits
|
||||
namespace boost { namespace optional_detail {
|
||||
|
||||
@@ -47,7 +54,7 @@ struct conjunction<B1> : B1 {};
|
||||
|
||||
template <class B1, class... Bn>
|
||||
struct conjunction<B1, Bn...>
|
||||
: ::std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
|
||||
: ::std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
|
||||
|
||||
}}
|
||||
|
||||
@@ -108,13 +115,13 @@ struct constexpr_guarded_storage
|
||||
template <class... Args> explicit constexpr constexpr_guarded_storage(optional_ns::in_place_init_t, Args&&... args)
|
||||
: init_(true), storage_(forward_<Args>(args)...) {}
|
||||
|
||||
template <class U, class... Args, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
|
||||
constexpr explicit constexpr_guarded_storage(optional_ns::in_place_init_t, ::std::initializer_list<U> il, Args&&... args)
|
||||
: init_(true), storage_(il, forward_<Args>(args)...) {}
|
||||
// template <class U, class... Args, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
|
||||
// constexpr explicit constexpr_guarded_storage(optional_ns::in_place_init_t, ::std::initializer_list<U> il, Args&&... args)
|
||||
// : init_(true), storage_(il, forward_<Args>(args)...) {}
|
||||
|
||||
constexpr void reset () noexcept { init_ = false; }
|
||||
BOOST_CXX14_CONSTEXPR void reset () noexcept { init_ = false; }
|
||||
|
||||
~constexpr_guarded_storage() = default;
|
||||
//~constexpr_guarded_storage() = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -130,12 +137,12 @@ struct fallback_guarded_storage
|
||||
|
||||
explicit constexpr fallback_guarded_storage(T&& v) : init_(true), storage_(move_(v)) {}
|
||||
|
||||
template <class... Args> explicit fallback_guarded_storage(optional_ns::in_place_init_t, Args&&... args)
|
||||
template <class... Args> explicit constexpr fallback_guarded_storage(optional_ns::in_place_init_t, Args&&... args)
|
||||
: init_(true), storage_(forward_<Args>(args)...) {}
|
||||
|
||||
template <class U, class... Args, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
|
||||
explicit fallback_guarded_storage(optional_ns::in_place_init_t, ::std::initializer_list<U> il, Args&&... args)
|
||||
: init_(true), storage_(il, forward_<Args>(args)...) {}
|
||||
// template <class U, class... Args, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
|
||||
// explicit fallback_guarded_storage(optional_ns::in_place_init_t, ::std::initializer_list<U> il, Args&&... args)
|
||||
// : init_(true), storage_(il, forward_<Args>(args)...) {}
|
||||
|
||||
void reset() noexcept
|
||||
{
|
||||
@@ -169,16 +176,16 @@ namespace boost {
|
||||
{
|
||||
using storage_t = optional_detail::guarded_storage<T>;
|
||||
storage_t storage;
|
||||
static_assert( !::std::is_same<typename std::decay<T>::type, none_t>::value, "bad T" );
|
||||
static_assert( !::std::is_same<typename std::decay<T>::type, in_place_init_t>::value, "bad T" );
|
||||
static_assert( !::std::is_same<typename std::decay<T>::type, none_t>::value, "optional<none_t> is illegal" );
|
||||
static_assert( !::std::is_same<typename std::decay<T>::type, in_place_init_t>::value, "optional<in_place_init_t> is illegal" );
|
||||
static_assert( !::std::is_same<typename std::decay<T>::type, in_place_init_if_t>::value, "optional<in_place_init_if_t> is illegal" );
|
||||
|
||||
|
||||
constexpr typename ::std::remove_const<T>::type* dataptr() { return ::boost::addressof(storage.storage_.value_); }
|
||||
BOOST_CXX14_CONSTEXPR typename ::std::remove_const<T>::type* dataptr() { return ::boost::addressof(storage.storage_.value_); }
|
||||
constexpr const T* dataptr() const { return ::boost::addressof(storage.storage_.value_); }
|
||||
|
||||
constexpr const T& contained_val() const& { return storage.storage_.value_; }
|
||||
constexpr T&& contained_val() && { return optional_detail::move_(storage.storage_.value_); }
|
||||
constexpr T& contained_val() & { return storage.storage_.value_; }
|
||||
BOOST_CXX14_CONSTEXPR T&& contained_val() && { return optional_detail::move_(storage.storage_.value_); }
|
||||
BOOST_CXX14_CONSTEXPR T& contained_val() & { return storage.storage_.value_; }
|
||||
|
||||
template <typename... Args>
|
||||
BOOST_OPTIONAL_CXX20_CONSTEXPR void initialize(Args&&... args)
|
||||
@@ -209,6 +216,7 @@ namespace boost {
|
||||
constexpr optional(const T& v) : storage(v) {}
|
||||
constexpr optional(T&& v) : storage(optional_detail::move_(v)) {}
|
||||
|
||||
#ifdef BOOST_OPTIONAL_CONSTEXPR_COPY
|
||||
constexpr optional(bool cond, const T& v)
|
||||
: storage(cond ? storage_t(v) : storage_t())
|
||||
{}
|
||||
@@ -228,17 +236,77 @@ namespace boost {
|
||||
|
||||
template <typename U, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, U const&>)>
|
||||
constexpr explicit optional(optional<U> const& rhs)
|
||||
: storage(rhs.is_initialized() ? storage_t(*rhs) : storage_t())
|
||||
: storage(rhs.is_initialized() ? storage_t(in_place_init, *rhs) : storage_t())
|
||||
{}
|
||||
|
||||
template <typename U, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, U&&>)>
|
||||
constexpr explicit optional(optional<U> && rhs)
|
||||
: storage(rhs.is_initialized() ? storage_t(*optional_detail::move_(rhs)) : storage_t())
|
||||
: storage(rhs.is_initialized() ? storage_t(in_place_init, *optional_detail::move_(rhs)) : storage_t())
|
||||
{}
|
||||
|
||||
template <typename... Args>
|
||||
constexpr explicit optional( in_place_init_if_t, bool cond, Args&&... args )
|
||||
: storage( cond ? storage_t(in_place_init, optional_detail::forward_<Args>(args)...) : storage_t() )
|
||||
{}
|
||||
#else
|
||||
optional(bool cond, const T& v)
|
||||
: storage()
|
||||
{
|
||||
if (cond)
|
||||
initialize(v);
|
||||
}
|
||||
|
||||
optional(bool cond, T&& v)
|
||||
: storage()
|
||||
{
|
||||
if (cond)
|
||||
initialize(optional_detail::move_(v));
|
||||
}
|
||||
|
||||
optional(const optional& rhs)
|
||||
: storage()
|
||||
{
|
||||
if (rhs.is_initialized())
|
||||
initialize(*rhs);
|
||||
}
|
||||
|
||||
optional(optional&& rhs)
|
||||
noexcept(::std::is_nothrow_move_constructible<T>::value)
|
||||
: storage()
|
||||
{
|
||||
if (rhs.is_initialized())
|
||||
initialize(*optional_detail::move_(rhs));
|
||||
}
|
||||
|
||||
template <typename U, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, U const&>)>
|
||||
explicit optional(optional<U> const& rhs)
|
||||
: storage()
|
||||
{
|
||||
if (rhs.is_initialized())
|
||||
initialize(*rhs);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, U&&>)>
|
||||
explicit optional(optional<U> && rhs)
|
||||
: storage()
|
||||
{
|
||||
if (rhs.is_initialized())
|
||||
initialize(*optional_detail::move_(rhs));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
explicit optional( in_place_init_if_t, bool cond, Args&&... args )
|
||||
: storage()
|
||||
{
|
||||
if (cond)
|
||||
initialize(optional_detail::forward_<Args>(args)...);
|
||||
}
|
||||
#endif // BOOST_OPTIONAL_CONSTEXPR_COPY
|
||||
|
||||
template <typename FT,
|
||||
BOOST_OPTIONAL_REQUIRES(optional_detail::is_typed_in_place_factory<FT>)>
|
||||
constexpr explicit optional (FT&& factory)
|
||||
/*non-constexpr (deprecated)*/
|
||||
explicit optional (FT&& factory)
|
||||
: storage()
|
||||
{
|
||||
factory.apply(this->dataptr());
|
||||
@@ -247,7 +315,8 @@ namespace boost {
|
||||
|
||||
template <typename FT,
|
||||
BOOST_OPTIONAL_REQUIRES(optional_detail::is_in_place_factory<FT>)>
|
||||
constexpr explicit optional (FT&& factory)
|
||||
/*non-constexpr (deprecated)*/
|
||||
explicit optional (FT&& factory)
|
||||
: storage()
|
||||
{
|
||||
factory.template apply<T>(this->dataptr());
|
||||
@@ -265,12 +334,7 @@ namespace boost {
|
||||
: storage(in_place_init, optional_detail::forward_<Args>(args)...)
|
||||
{}
|
||||
|
||||
template <typename... Args>
|
||||
constexpr explicit optional( in_place_init_if_t, bool cond, Args&&... args )
|
||||
: storage( cond ? storage_t(in_place_init, optional_detail::forward_<Args>(args)...) : storage_t() )
|
||||
{}
|
||||
|
||||
constexpr void reset() noexcept
|
||||
BOOST_CXX14_CONSTEXPR void reset() noexcept
|
||||
{
|
||||
storage.reset();
|
||||
}
|
||||
@@ -283,13 +347,13 @@ namespace boost {
|
||||
template <typename... Args>
|
||||
BOOST_OPTIONAL_CXX20_CONSTEXPR void emplace(Args&&... args)
|
||||
{
|
||||
reset(); static_assert(noexcept(reset()));
|
||||
reset();
|
||||
// <-- now we are not containing a value
|
||||
initialize(optional_detail::forward_<Args>(args)...);
|
||||
}
|
||||
|
||||
|
||||
constexpr optional& operator=(none_t) noexcept
|
||||
BOOST_CXX14_CONSTEXPR optional& operator=(none_t) noexcept
|
||||
{
|
||||
reset();
|
||||
return *this;
|
||||
@@ -386,6 +450,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <class F, BOOST_OPTIONAL_REQUIRES(optional_detail::is_in_place_factory<F>)>
|
||||
/*non-constexpr (deprecated)*/
|
||||
optional& operator=(F&& factory)
|
||||
{
|
||||
reset();
|
||||
@@ -395,6 +460,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <class F, BOOST_OPTIONAL_REQUIRES(optional_detail::is_typed_in_place_factory<F>)>
|
||||
/*non-constexpr (deprecated)*/
|
||||
optional& operator=(F&& factory)
|
||||
{
|
||||
reset();
|
||||
@@ -406,7 +472,6 @@ namespace boost {
|
||||
BOOST_OPTIONAL_CXX20_CONSTEXPR
|
||||
void swap(optional& rhs)
|
||||
noexcept(::std::is_nothrow_move_constructible<T>::value && noexcept(boost::core::invoke_swap(*rhs, *rhs)))
|
||||
// I am cheating here. I need "swapabe" not "assignnable" trait. But this is best I can do in C++14
|
||||
{
|
||||
if (is_initialized())
|
||||
{
|
||||
@@ -428,8 +493,8 @@ namespace boost {
|
||||
constexpr bool has_value() const noexcept { return this->is_initialized(); }
|
||||
constexpr explicit operator bool() const noexcept { return this->is_initialized(); }
|
||||
|
||||
constexpr reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->contained_val(); }
|
||||
constexpr reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->contained_val(); }
|
||||
constexpr reference_const_type get() const { return BOOST_OPTIONAL_ASSERTED_EXPRESSION(this->is_initialized(), this->contained_val()); }
|
||||
BOOST_CXX14_CONSTEXPR reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->contained_val(); }
|
||||
|
||||
//BOOST_DEPRECATED("use `value_or(v)` instead")
|
||||
reference_const_type get_value_or (reference_const_type v) const { return this->is_initialized() ? this->contained_val() : v; }
|
||||
@@ -440,22 +505,19 @@ namespace boost {
|
||||
pointer_const_type get_ptr() const { return is_initialized() ? dataptr() : nullptr; }
|
||||
pointer_type get_ptr() { return is_initialized() ? dataptr() : nullptr; }
|
||||
|
||||
constexpr reference_const_type operator*() const& { return this->get(); }
|
||||
constexpr reference_type operator*() & { return this->get(); }
|
||||
constexpr reference_type_of_temporary_wrapper operator*() && { return optional_detail::move_(this->get()); }
|
||||
constexpr reference_const_type operator*() const& { return this->get(); }
|
||||
BOOST_CXX14_CONSTEXPR reference_type operator*() & { return this->get(); }
|
||||
BOOST_CXX14_CONSTEXPR reference_type_of_temporary_wrapper operator*() && { return optional_detail::move_(this->get()); }
|
||||
|
||||
constexpr pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->dataptr(); }
|
||||
constexpr pointer_type operator->() { BOOST_ASSERT(this->is_initialized()) ; return this->dataptr(); }
|
||||
constexpr pointer_const_type operator->() const { return BOOST_OPTIONAL_ASSERTED_EXPRESSION(this->is_initialized(), this->dataptr()); }
|
||||
BOOST_CXX14_CONSTEXPR pointer_type operator->() { BOOST_ASSERT(this->is_initialized()) ; return this->dataptr(); }
|
||||
|
||||
constexpr reference_const_type value() const&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return this->get();
|
||||
else
|
||||
boost::throw_exception(boost::bad_optional_access());
|
||||
return this->is_initialized() ? this->get() : (boost::throw_exception(boost::bad_optional_access()), this->get());
|
||||
}
|
||||
|
||||
constexpr reference_type value() &
|
||||
BOOST_CXX14_CONSTEXPR reference_type value() &
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return this->get();
|
||||
@@ -463,7 +525,7 @@ namespace boost {
|
||||
boost::throw_exception(boost::bad_optional_access());
|
||||
}
|
||||
|
||||
constexpr reference_type_of_temporary_wrapper value() &&
|
||||
BOOST_CXX14_CONSTEXPR reference_type_of_temporary_wrapper value() &&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return optional_detail::move_(this->get());
|
||||
@@ -471,17 +533,15 @@ namespace boost {
|
||||
boost::throw_exception(boost::bad_optional_access());
|
||||
}
|
||||
|
||||
template <class U = T>
|
||||
template <class U = typename ::std::remove_cv<T>::type,
|
||||
typename fail_hard_on_nonconvertible<T, U>::type = true>
|
||||
constexpr value_type value_or(U&& v) const&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return get();
|
||||
else
|
||||
return optional_detail::forward_<U>(v);
|
||||
return this->is_initialized() ? get() : T(optional_detail::forward_<U>(v));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
constexpr value_type value_or(U&& v) &&
|
||||
template <class U = typename ::std::remove_cv<T>::type>
|
||||
BOOST_CXX14_CONSTEXPR value_type value_or(U&& v) &&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return optional_detail::move_(get());
|
||||
@@ -489,17 +549,15 @@ namespace boost {
|
||||
return optional_detail::forward_<U>(v);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
template <typename F,
|
||||
typename fail_hard_on_nonconvertible<T, decltype(optional_detail::declval_<F>()())>::type = true>
|
||||
constexpr value_type value_or_eval(F f) const&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return get();
|
||||
else
|
||||
return f();
|
||||
return this->is_initialized() ? get() : value_type(f());
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr value_type value_or_eval ( F f ) &&
|
||||
BOOST_CXX14_CONSTEXPR value_type value_or_eval ( F f ) &&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return optional_detail::move_(get());
|
||||
@@ -508,7 +566,8 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr optional<typename optional_detail::result_of<F, reference_type>::type> map(F f) &
|
||||
BOOST_CXX14_CONSTEXPR optional<typename optional_detail::result_of<F, reference_type>::type>
|
||||
map(F f) &
|
||||
{
|
||||
if (this->has_value())
|
||||
return f(get());
|
||||
@@ -517,16 +576,17 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr optional<typename optional_detail::result_of<F, reference_const_type>::type> map(F f) const&
|
||||
constexpr optional<typename optional_detail::result_of<F, reference_const_type>::type>
|
||||
map(F f) const&
|
||||
{
|
||||
if (this->has_value())
|
||||
return f(get());
|
||||
else
|
||||
return none;
|
||||
return this->has_value() ?
|
||||
f(get()) :
|
||||
optional<typename optional_detail::result_of<F, reference_const_type>::type>();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr optional<typename optional_detail::result_of<F, reference_type_of_temporary_wrapper>::type> map(F f) &&
|
||||
BOOST_CXX14_CONSTEXPR optional<typename optional_detail::result_of<F, reference_type_of_temporary_wrapper>::type>
|
||||
map(F f) &&
|
||||
{
|
||||
if (this->has_value())
|
||||
return f(optional_detail::move_(this->get()));
|
||||
@@ -535,7 +595,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr optional<typename optional_detail::result_value_type<F, reference_type>::type>
|
||||
BOOST_CXX14_CONSTEXPR optional<typename optional_detail::result_value_type<F, reference_type>::type>
|
||||
flat_map(F f) &
|
||||
{
|
||||
if (this->has_value())
|
||||
@@ -548,14 +608,13 @@ namespace boost {
|
||||
constexpr optional<typename optional_detail::result_value_type<F, reference_const_type>::type>
|
||||
flat_map(F f) const&
|
||||
{
|
||||
if (this->has_value())
|
||||
return f(get());
|
||||
else
|
||||
return none;
|
||||
return this->has_value() ?
|
||||
f(get()) :
|
||||
optional<typename optional_detail::result_value_type<F, reference_const_type>::type>();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr optional<typename optional_detail::result_value_type<F, reference_type_of_temporary_wrapper>::type>
|
||||
BOOST_CXX14_CONSTEXPR optional<typename optional_detail::result_value_type<F, reference_type_of_temporary_wrapper>::type>
|
||||
flat_map(F f) &&
|
||||
{
|
||||
if (this->has_value())
|
||||
@@ -577,6 +636,4 @@ namespace boost {
|
||||
}
|
||||
|
||||
|
||||
// https://godbolt.org/z/ov1ahMsv6
|
||||
|
||||
#endif // BOOST_OPTIONAL_DETAIL_CONSTEXPR_OPTIONAL_01FEB2026_HPP
|
||||
#endif // BOOST_OPTIONAL_DETAIL_UNION_OPTIONAL_01FEB2026_HPP
|
||||
@@ -23,15 +23,7 @@
|
||||
#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR) && \
|
||||
!defined(BOOST_NO_CXX11_REF_QUALIFIERS) && \
|
||||
!defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && \
|
||||
!defined(BOOST_NO_CXX11_UNRESTRICTED_UNION)
|
||||
# ifdef BOOST_OPTIONAL_CONFIG_ENABLE_CONSTEXPR_IMPLEMENTATION // for now, only per manual request
|
||||
# define BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/optional/detail/optional_select_implementation.hpp>
|
||||
#include <boost/optional/detail/optional_common_defs.hpp>
|
||||
|
||||
|
||||
@@ -56,8 +48,8 @@ operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optiona
|
||||
#include <boost/none.hpp>
|
||||
|
||||
|
||||
#if defined BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#include <boost/optional/detail/constexpr_optional.hpp>
|
||||
#if defined BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
#include <boost/optional/detail/union_optional.hpp>
|
||||
#else
|
||||
|
||||
|
||||
|
||||
@@ -17,25 +17,32 @@
|
||||
#define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/invoke_swap.hpp>
|
||||
#include <boost/optional/detail/optional_select_implementation.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class T> class optional ;
|
||||
|
||||
// This forward is needed to refer to namespace scope swap from the member swap
|
||||
#ifdef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
template<class T> BOOST_OPTIONAL_CXX20_CONSTEXPR void swap ( optional<T>& , optional<T>& ) ;
|
||||
#ifdef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
template<class T> BOOST_OPTIONAL_CXX20_CONSTEXPR void swap ( optional<T>& lhs, optional<T>& rhs )
|
||||
noexcept(::std::is_nothrow_move_constructible<T>::value && noexcept(boost::core::invoke_swap(*lhs, *rhs)));
|
||||
#else
|
||||
template<class T> void swap ( optional<T>& , optional<T>& ) ;
|
||||
#endif // BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
template<class T> void swap ( optional<T>& , optional<T>& ) ;
|
||||
#endif // BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
|
||||
|
||||
template<class T> struct optional_swap_should_use_default_constructor ;
|
||||
|
||||
|
||||
#ifndef BOOST_OPTIONAL_CONFIG_DONT_SPECIALIZE_OPTIONAL_REFS
|
||||
|
||||
template<class T> class optional<T&> ;
|
||||
template<class T> class optional<T&> ;
|
||||
|
||||
template<class T> BOOST_CXX14_CONSTEXPR void swap ( optional<T&>& , optional<T&>& ) BOOST_NOEXCEPT;
|
||||
template<class T> BOOST_CXX14_CONSTEXPR void swap ( optional<T&>& , optional<T&>& ) BOOST_NOEXCEPT;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ run optional_test_assign.cpp ;
|
||||
run optional_test_swap.cpp ;
|
||||
compile optional_test_constexpr.cpp ;
|
||||
compile optional_test_wuninitialized.cpp ;
|
||||
compile optional_test_fwd_header.cpp ;
|
||||
run optional_test_conversions_from_U.cpp ;
|
||||
run optional_test_convert_from_T.cpp ;
|
||||
run optional_test_convert_assign.cpp ;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2021 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
|
||||
|
||||
template <typename U>
|
||||
struct wrapper {};
|
||||
|
||||
template <typename /*Tag*/, typename U>
|
||||
int get(wrapper<U> const&) { return 0; }
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
struct any_type_in_boost_namespace {};
|
||||
}
|
||||
|
||||
class tag; // user-defined tag
|
||||
|
||||
int main()
|
||||
{
|
||||
// the following tests if boost::get for optional<> does
|
||||
// not interfere with the global get
|
||||
return get<tag>(wrapper<boost::any_type_in_boost_namespace>());
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "boost/optional.hpp"
|
||||
|
||||
#ifdef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifdef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
|
||||
struct Record
|
||||
{
|
||||
@@ -23,40 +23,42 @@ struct Record
|
||||
namespace test_int
|
||||
{
|
||||
constexpr boost::optional<int> oN;
|
||||
static_assert(!oN);
|
||||
static_assert(oN == boost::none);
|
||||
static_assert(oN <= boost::none);
|
||||
static_assert(!(oN != boost::none));
|
||||
static_assert(oN == oN);
|
||||
static_assert(!oN.has_value());
|
||||
static_assert(oN.value_or({}) == 0);
|
||||
static_assert(oN.value_or(0) == 0);
|
||||
static_assert(oN.value_or_eval(Record(9)) == 9);
|
||||
static_assert(!oN, "");
|
||||
static_assert(oN == boost::none, "");
|
||||
static_assert(oN <= boost::none, "");
|
||||
static_assert(!(oN != boost::none), "");
|
||||
static_assert(oN == oN, "");
|
||||
static_assert(!oN.has_value(), "");
|
||||
static_assert(oN.value_or({}) == 0, "");
|
||||
static_assert(oN.value_or(0) == 0, "");
|
||||
static_assert(oN.value_or_eval(Record(9)) == 9, "");
|
||||
|
||||
constexpr boost::optional<int> o1 (1);
|
||||
constexpr boost::optional<int> o2 {2};
|
||||
|
||||
static_assert(o1, "");
|
||||
static_assert(o1.has_value(), "");
|
||||
static_assert(o1 != boost::none, "");
|
||||
static_assert(o1 != oN, "");
|
||||
static_assert(o1 > oN, "");
|
||||
static_assert(o1 >= oN, "");
|
||||
static_assert(*o1 == 1, "");
|
||||
static_assert(o1.value() == 1, "");
|
||||
static_assert(o1.value_or(0) == 1, "");
|
||||
static_assert(o1.value_or({}) == 1, "");
|
||||
static_assert(o1.value_or_eval(Record(9)) == 1, "");
|
||||
static_assert(o1 == 1, "");
|
||||
static_assert(o2, "");
|
||||
static_assert(o2 != o1, "");
|
||||
static_assert(o2 > o1, "");
|
||||
|
||||
#ifndef BOOST_NO_CXX14_CONSTEXPR
|
||||
constexpr boost::optional<int> oNc = oN;
|
||||
constexpr boost::optional<int> oNd = boost::none;
|
||||
constexpr boost::optional<int> oNe = {};
|
||||
static_assert(oNc == oN);
|
||||
static_assert(oNd == oN);
|
||||
static_assert(oNe == oN);
|
||||
|
||||
constexpr boost::optional<int> o1 = 1;
|
||||
constexpr boost::optional<int> o2 {2};
|
||||
|
||||
static_assert(o1);
|
||||
static_assert(o1.has_value());
|
||||
static_assert(o1 != boost::none);
|
||||
static_assert(o1 != oN);
|
||||
static_assert(o1 > oN);
|
||||
static_assert(o1 >= oN);
|
||||
static_assert(*o1 == 1);
|
||||
static_assert(o1.value() == 1);
|
||||
static_assert(o1.value_or(0) == 1);
|
||||
static_assert(o1.value_or({}) == 1);
|
||||
static_assert(o1.value_or_eval(Record(9)) == 1);
|
||||
static_assert(o1 == 1);
|
||||
static_assert(o2);
|
||||
static_assert(o2 != o1);
|
||||
static_assert(o2 > o1);
|
||||
static_assert(oNc == oN, "");
|
||||
static_assert(oNd == oN, "");
|
||||
static_assert(oNe == oN, "");
|
||||
|
||||
constexpr bool test_reset() {
|
||||
boost::optional<int> o = 1;
|
||||
@@ -66,31 +68,32 @@ namespace test_int
|
||||
return o == boost::none;
|
||||
}
|
||||
|
||||
static_assert(test_reset());
|
||||
static_assert(test_reset(), "");
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace test_record
|
||||
{
|
||||
constexpr boost::optional<Record> rN = boost::none;
|
||||
constexpr boost::optional<Record> r1 = Record(1);
|
||||
constexpr boost::optional<Record> rN (boost::none);
|
||||
constexpr boost::optional<Record> r1 (Record(1));
|
||||
constexpr boost::optional<Record> r2 (boost::in_place_init, 2);
|
||||
|
||||
static_assert(!rN);
|
||||
static_assert(rN == boost::none);
|
||||
static_assert(r1);
|
||||
static_assert(r1 != boost::none);
|
||||
static_assert(r2);
|
||||
static_assert(rN.value_or(Record(9)).i == 9);
|
||||
static_assert(r1->i == 1);
|
||||
static_assert(r2.value().i == 2);
|
||||
static_assert(!rN, "");
|
||||
static_assert(rN == boost::none, "");
|
||||
static_assert(r1, "");
|
||||
static_assert(r1 != boost::none, "");
|
||||
static_assert(r2, "");
|
||||
static_assert(rN.value_or(Record(9)).i == 9, "");
|
||||
static_assert(r1->i == 1, "");
|
||||
static_assert(r2.value().i == 2, "");
|
||||
}
|
||||
|
||||
namespace test_optional_ref
|
||||
{
|
||||
constexpr int gi = 9;
|
||||
constexpr boost::optional<const int&> iref = gi;
|
||||
static_assert(iref);
|
||||
static_assert(*iref == 9);
|
||||
static_assert(iref, "");
|
||||
static_assert(*iref == 9, "");
|
||||
}
|
||||
|
||||
#endif // BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#endif // BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
|
||||
@@ -55,5 +55,6 @@ int main()
|
||||
{
|
||||
// Invokes boost::optional copy constructor. Should not invoke wrapper constructor from U.
|
||||
boost::optional< wrapper< int > > res = foo();
|
||||
(void)res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -29,4 +29,3 @@ void test_implicit_conversion_to_bool()
|
||||
boost::optional<T> opt;
|
||||
opt.value_or(U());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2026 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
|
||||
|
||||
#include "boost/optional/optional_fwd.hpp"
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
void statically_test_basic_instantiations()
|
||||
{
|
||||
boost::optional<int> oN, o1(1);
|
||||
swap(oN, o1);
|
||||
|
||||
int i = 1;
|
||||
boost::optional<int> rN, ri(i);
|
||||
swap(rN, ri);
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "boost/type_traits/is_base_of.hpp"
|
||||
#include "boost/optional/detail/experimental_traits.hpp"
|
||||
|
||||
#ifndef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
|
||||
|
||||
struct PrivDefault
|
||||
@@ -136,11 +136,11 @@ void test_trivial_copyability()
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#endif // BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
|
||||
test_type_traits();
|
||||
test_trivial_copyability();
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace boost {
|
||||
// Compile time tweaking on whether or not swap should use the default constructor:
|
||||
//
|
||||
|
||||
#ifndef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
template <> struct optional_swap_should_use_default_constructor<
|
||||
optional_swap_test::class_whose_default_ctor_should_be_used> : true_type {} ;
|
||||
|
||||
@@ -219,7 +219,7 @@ template <> struct optional_swap_should_use_default_constructor<
|
||||
|
||||
template <class T> struct optional_swap_should_use_default_constructor<
|
||||
optional_swap_test::template_whose_default_ctor_should_be_used<T> > : true_type {} ;
|
||||
#endif // BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#endif // BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
|
||||
//
|
||||
// Specialization of boost::swap:
|
||||
@@ -353,14 +353,14 @@ void test_swap_member_function( T const* )
|
||||
void test_swap_tweaking()
|
||||
{
|
||||
( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) );
|
||||
#ifndef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
( test_swap_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
|
||||
( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
|
||||
( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
|
||||
( test_swap_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
|
||||
#endif
|
||||
( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) );
|
||||
#ifndef BOOST_OPTIONAL_USES_CONSTEXPR_IMPLEMENTATION
|
||||
#ifndef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
( test_swap_member_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
|
||||
( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
|
||||
( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
|
||||
|
||||
Reference in New Issue
Block a user