mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-04 08:55:43 +08:00
noexcept adjustments in Optional<T>
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
#ifndef BLACKMISC_OPTIONAL_H
|
#ifndef BLACKMISC_OPTIONAL_H
|
||||||
#define BLACKMISC_OPTIONAL_H
|
#define BLACKMISC_OPTIONAL_H
|
||||||
|
|
||||||
|
#include "blackmisc/typetraits.h"
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -26,16 +27,20 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Default constructor.
|
//! Default constructor.
|
||||||
Optional() {}
|
Optional() noexcept {}
|
||||||
|
|
||||||
//! Construct from a value.
|
//! Construct from a value.
|
||||||
Optional(T value) { new (m_data.bytes) T(std::move(value)); m_isValid = true; }
|
Optional(T value) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||||
|
{
|
||||||
|
new (m_data.bytes) T(std::move(value));
|
||||||
|
m_isValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
//! Construct from a nullptr, equivalent to default constructor.
|
//! Construct from a nullptr, equivalent to default constructor.
|
||||||
Optional(std::nullptr_t) {}
|
Optional(std::nullptr_t) noexcept {}
|
||||||
|
|
||||||
//! Copy constructor.
|
//! Copy constructor.
|
||||||
Optional(const Optional &other)
|
Optional(const Optional &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
|
||||||
{
|
{
|
||||||
if (other.m_isValid) { new (m_data.bytes) T(*other); }
|
if (other.m_isValid) { new (m_data.bytes) T(*other); }
|
||||||
m_isValid = other.m_isValid;
|
m_isValid = other.m_isValid;
|
||||||
@@ -49,14 +54,14 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Assign a nullptr.
|
//! Assign a nullptr.
|
||||||
Optional &operator =(std::nullptr_t)
|
Optional &operator =(std::nullptr_t) noexcept
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Copy assignment.
|
//! Copy assignment.
|
||||||
Optional &operator =(const Optional &other)
|
Optional &operator =(const Optional &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
if (other.m_isValid) { new (m_data.bytes) T(*other); }
|
if (other.m_isValid) { new (m_data.bytes) T(*other); }
|
||||||
@@ -65,7 +70,7 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Move assignment.
|
//! Move assignment.
|
||||||
Optional &operator =(Optional &&other) noexcept(std::is_nothrow_move_assignable<T>::value)
|
Optional &operator =(Optional &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
|
if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
|
||||||
@@ -77,7 +82,7 @@ namespace BlackMisc
|
|||||||
~Optional() { if (m_isValid) { (*this)->~T(); } }
|
~Optional() { if (m_isValid) { (*this)->~T(); } }
|
||||||
|
|
||||||
//! Explicit cast to bool, true if this Optional contains a value.
|
//! Explicit cast to bool, true if this Optional contains a value.
|
||||||
explicit operator bool() const { return m_isValid; }
|
explicit operator bool() const noexcept { return m_isValid; }
|
||||||
|
|
||||||
//! If object is valid, destroy to make it invalid.
|
//! If object is valid, destroy to make it invalid.
|
||||||
void reset() noexcept
|
void reset() noexcept
|
||||||
@@ -115,10 +120,9 @@ namespace BlackMisc
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Efficient swap for two Optional objects.
|
* Efficient swap for two Optional objects.
|
||||||
* \todo Make conditionally noexcept using C++17 std::is_nothrow_swappable.
|
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void swap(Optional<T> &a, Optional<T> &b)
|
void swap(Optional<T> &a, Optional<T> &b) noexcept(Private::is_nothrow_swappable<T, T>::value)
|
||||||
{
|
{
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
#ifndef BLACKMISC_TYPETRAITS_H
|
#ifndef BLACKMISC_TYPETRAITS_H
|
||||||
#define BLACKMISC_TYPETRAITS_H
|
#define BLACKMISC_TYPETRAITS_H
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility> // for std::swap
|
||||||
|
|
||||||
#if defined(Q_CC_CLANG) || (defined(Q_CC_GNU) && __GNUC__ >= 5)
|
#if defined(Q_CC_CLANG) || (defined(Q_CC_GNU) && __GNUC__ >= 5)
|
||||||
#define BLACK_HAS_FIXED_CWG1558
|
#define BLACK_HAS_FIXED_CWG1558
|
||||||
#endif
|
#endif
|
||||||
@@ -38,6 +41,22 @@ namespace BlackMisc
|
|||||||
#endif
|
#endif
|
||||||
//! \endcond
|
//! \endcond
|
||||||
|
|
||||||
|
namespace Private
|
||||||
|
{
|
||||||
|
//! \private Own implementation of C++17 std::is_nothrow_swappable.
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_nothrow_swappable
|
||||||
|
{
|
||||||
|
static constexpr bool impl()
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
return noexcept(swap(std::declval<T>(), std::declval<U>()))
|
||||||
|
&& noexcept(swap(std::declval<U>(), std::declval<T>()));
|
||||||
|
}
|
||||||
|
static constexpr bool value = impl();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Trait to detect whether T contains a member function toQString.
|
* Trait to detect whether T contains a member function toQString.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user