mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 12:55:33 +08:00
noexcept adjustments in Optional<T>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#ifndef BLACKMISC_OPTIONAL_H
|
||||
#define BLACKMISC_OPTIONAL_H
|
||||
|
||||
#include "blackmisc/typetraits.h"
|
||||
#include <QtGlobal>
|
||||
#include <utility>
|
||||
|
||||
@@ -26,16 +27,20 @@ namespace BlackMisc
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
Optional() {}
|
||||
Optional() noexcept {}
|
||||
|
||||
//! 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.
|
||||
Optional(std::nullptr_t) {}
|
||||
Optional(std::nullptr_t) noexcept {}
|
||||
|
||||
//! 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); }
|
||||
m_isValid = other.m_isValid;
|
||||
@@ -49,14 +54,14 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
//! Assign a nullptr.
|
||||
Optional &operator =(std::nullptr_t)
|
||||
Optional &operator =(std::nullptr_t) noexcept
|
||||
{
|
||||
reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Copy assignment.
|
||||
Optional &operator =(const Optional &other)
|
||||
Optional &operator =(const Optional &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
|
||||
{
|
||||
reset();
|
||||
if (other.m_isValid) { new (m_data.bytes) T(*other); }
|
||||
@@ -65,7 +70,7 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
//! 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();
|
||||
if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
|
||||
@@ -77,7 +82,7 @@ namespace BlackMisc
|
||||
~Optional() { if (m_isValid) { (*this)->~T(); } }
|
||||
|
||||
//! 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.
|
||||
void reset() noexcept
|
||||
@@ -115,10 +120,9 @@ namespace BlackMisc
|
||||
|
||||
/*!
|
||||
* Efficient swap for two Optional objects.
|
||||
* \todo Make conditionally noexcept using C++17 std::is_nothrow_swappable.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#ifndef 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)
|
||||
#define BLACK_HAS_FIXED_CWG1558
|
||||
#endif
|
||||
@@ -38,6 +41,22 @@ namespace BlackMisc
|
||||
#endif
|
||||
//! \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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user