forked from OSchip/llvm-project
Implement N4606 optional
Summary: Adapt implementation of Library Fundamentals TS optional into an implementation of N4606 optional. - Update relational operators per http://wg21.link/P0307 - Update to requirements of http://wg21.link/P0032 - Extension: Implement trivial copy/move construction/assignment for `optional<T>` when `T` is trivially copyable. Audit P/Rs for optional LWG issues: - 2756 "C++ WP optional<T> should 'forward' T's implicit conversions" Implemented, which also resolves 2753 "Optional's constructors and assignments need constraints" (modulo my refusal to explicitly delete the move operations, which is a design error that I'm working on correcting in the 2756 P/R). - 2736 "nullopt_t insufficiently constrained" Already conforming. I've added a test ensuring that `nullopt_t` is not copy-initializable from an empty braced-init-list, which I believe is the root intent of the issue, to avoid regression. - 2740 "constexpr optional<T>::operator->" Already conforming. - 2746 "Inconsistency between requirements for emplace between optional and variant" No P/R, but note that the author's '"suggested resolution" is already implemented. - 2748 "swappable traits for optionals" Already conforming. - 2753 "Optional's constructors and assignments need constraints" Implemented. Most of the work for this patch was done by Casey Carter @ Microsoft. Thank you Casey! Reviewers: mclow.lists, CaseyCarter, EricWF Differential Revision: https://reviews.llvm.org/D22741 llvm-svn: 283980
This commit is contained in:
parent
90d990e034
commit
a9e659619f
|
@ -56,3 +56,6 @@ target/
|
|||
# MSVC libraries test harness
|
||||
env.lst
|
||||
keep.lst
|
||||
|
||||
# Editor by-products
|
||||
.vscode/
|
||||
|
|
|
@ -914,6 +914,10 @@ extern "C" void __sanitizer_annotate_contiguous_container(
|
|||
#define _LIBCPP_SAFE_STATIC
|
||||
#endif
|
||||
|
||||
#if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700
|
||||
#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
|
||||
#endif
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _LIBCPP_CONFIG
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -425,7 +425,7 @@ template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp
|
|||
#endif
|
||||
|
||||
// addressof
|
||||
#if __has_builtin(__builtin_addressof) || _GNUC_VER >= 700
|
||||
#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
|
@ -446,7 +446,7 @@ addressof(_Tp& __x) _NOEXCEPT
|
|||
return (_Tp*)&reinterpret_cast<const volatile char&>(__x);
|
||||
}
|
||||
|
||||
#endif // __has_builtin(__builtin_addressof)
|
||||
#endif // _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
|
||||
|
||||
#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF)
|
||||
// Objective-C++ Automatic Reference Counting uses qualified pointers
|
||||
|
|
|
@ -7,18 +7,18 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "optional"
|
||||
#include "experimental/optional"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
|
||||
|
||||
#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
|
||||
bad_optional_access::~bad_optional_access() _NOEXCEPT {}
|
||||
|
||||
#else
|
||||
namespace std
|
||||
{
|
||||
|
||||
bad_optional_access::~bad_optional_access() _NOEXCEPT = default;
|
||||
|
||||
#endif
|
||||
} // std
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
|
||||
|
||||
bad_optional_access::~bad_optional_access() _NOEXCEPT = default;
|
||||
|
||||
_LIBCPP_END_NAMESPACE_EXPERIMENTAL
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// XFAIL: libcpp-no-exceptions
|
||||
// <optional>
|
||||
|
||||
// optional<T>& operator=(const optional<T>& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X {};
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y() = default;
|
||||
Y& operator=(const Y&) { return *this; }
|
||||
};
|
||||
|
||||
struct Z1
|
||||
{
|
||||
Z1() = default;
|
||||
Z1(Z1&&) = default;
|
||||
Z1(const Z1&) = default;
|
||||
Z1& operator=(Z1&&) = default;
|
||||
Z1& operator=(const Z1&) = delete;
|
||||
};
|
||||
|
||||
struct Z2
|
||||
{
|
||||
Z2() = default;
|
||||
Z2(Z2&&) = default;
|
||||
Z2(const Z2&) = delete;
|
||||
Z2& operator=(Z2&&) = default;
|
||||
Z2& operator=(const Z2&) = default;
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201402
|
||||
template <class T>
|
||||
constexpr bool
|
||||
test()
|
||||
{
|
||||
optional<T> opt;
|
||||
optional<T> opt2;
|
||||
opt = opt2;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
using T = int;
|
||||
static_assert((std::is_trivially_copy_assignable<optional<T>>::value), "");
|
||||
#if __cplusplus >= 201402
|
||||
static_assert(test<T>(), "");
|
||||
#endif
|
||||
}
|
||||
{
|
||||
using T = X;
|
||||
static_assert((std::is_trivially_copy_assignable<optional<T>>::value), "");
|
||||
#if __cplusplus >= 201402
|
||||
static_assert(test<T>(), "");
|
||||
#endif
|
||||
}
|
||||
static_assert(!(std::is_trivially_copy_assignable<optional<Y>>::value), "");
|
||||
static_assert(!(std::is_trivially_copy_assignable<optional<std::string>>::value), "");
|
||||
|
||||
static_assert(!(std::is_copy_assignable<optional<Z1>>::value), "");
|
||||
static_assert(!(std::is_copy_assignable<optional<Z2>>::value), "");
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// XFAIL: libcpp-no-exceptions
|
||||
// <optional>
|
||||
|
||||
// optional<T>& operator=(optional<T>&& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X {};
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y() = default;
|
||||
Y& operator=(Y&&) { return *this; }
|
||||
};
|
||||
|
||||
struct Z1
|
||||
{
|
||||
Z1() = default;
|
||||
Z1(Z1&&) = default;
|
||||
Z1& operator=(Z1&&) = delete;
|
||||
};
|
||||
|
||||
struct Z2
|
||||
{
|
||||
Z2() = default;
|
||||
Z2(Z2&&) = delete;
|
||||
Z2& operator=(Z2&&) = default;
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201402
|
||||
template <class T>
|
||||
constexpr bool
|
||||
test()
|
||||
{
|
||||
optional<T> opt;
|
||||
optional<T> opt2;
|
||||
opt = std::move(opt2);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
using T = int;
|
||||
static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
|
||||
#if __cplusplus >= 201402
|
||||
static_assert(test<T>(), "");
|
||||
#endif
|
||||
}
|
||||
{
|
||||
using T = X;
|
||||
static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
|
||||
#if __cplusplus >= 201402
|
||||
static_assert(test<T>(), "");
|
||||
#endif
|
||||
}
|
||||
static_assert(!(std::is_trivially_move_assignable<optional<Y>>::value), "");
|
||||
static_assert(!(std::is_trivially_move_assignable<optional<std::string>>::value), "");
|
||||
|
||||
static_assert(!(std::is_move_assignable<optional<Z1>>::value), "");
|
||||
static_assert(!(std::is_move_assignable<optional<Z2>>::value), "");
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// XFAIL: libcpp-no-exceptions
|
||||
// <optional>
|
||||
|
||||
// optional(const optional<T>& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X {};
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y() = default;
|
||||
Y(const Y&) {}
|
||||
};
|
||||
|
||||
struct Z
|
||||
{
|
||||
Z() = default;
|
||||
Z(Z&&) = delete;
|
||||
Z(const Z&) = delete;
|
||||
Z& operator=(Z&&) = delete;
|
||||
Z& operator=(const Z&) = delete;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
using T = int;
|
||||
static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
|
||||
constexpr optional<T> opt;
|
||||
constexpr optional<T> opt2 = opt;
|
||||
(void)opt2;
|
||||
}
|
||||
{
|
||||
using T = X;
|
||||
static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
|
||||
constexpr optional<T> opt;
|
||||
constexpr optional<T> opt2 = opt;
|
||||
(void)opt2;
|
||||
}
|
||||
static_assert(!(std::is_trivially_copy_constructible<optional<Y>>::value), "");
|
||||
static_assert(!(std::is_trivially_copy_constructible<optional<std::string>>::value), "");
|
||||
|
||||
static_assert(!(std::is_copy_constructible<optional<Z>>::value), "");
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// XFAIL: libcpp-no-exceptions
|
||||
// <optional>
|
||||
|
||||
// optional(optional<T>&& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X {};
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y() = default;
|
||||
Y(Y&&) {}
|
||||
};
|
||||
|
||||
struct Z
|
||||
{
|
||||
Z() = default;
|
||||
Z(Z&&) = delete;
|
||||
Z(const Z&) = delete;
|
||||
Z& operator=(Z&&) = delete;
|
||||
Z& operator=(const Z&) = delete;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
using T = int;
|
||||
static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
|
||||
constexpr optional<T> opt;
|
||||
constexpr optional<T> opt2 = std::move(opt);
|
||||
(void)opt2;
|
||||
}
|
||||
{
|
||||
using T = X;
|
||||
static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
|
||||
constexpr optional<T> opt;
|
||||
constexpr optional<T> opt2 = std::move(opt);
|
||||
(void)opt2;
|
||||
}
|
||||
static_assert(!(std::is_trivially_move_constructible<optional<Y>>::value), "");
|
||||
static_assert(!(std::is_trivially_move_constructible<optional<std::string>>::value), "");
|
||||
|
||||
static_assert(!(std::is_move_constructible<optional<Z>>::value), "");
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "archetypes.hpp"
|
||||
|
||||
template <class T>
|
||||
struct SpecialMemberTest {
|
||||
using O = std::optional<T>;
|
||||
|
||||
template <template <class> class TestMF>
|
||||
static constexpr bool check_same() {
|
||||
return TestMF<O>::value == TestMF<T>::value;
|
||||
}
|
||||
|
||||
// Test that optional inherits the correct trivial/non-trivial members
|
||||
static_assert(check_same<std::is_trivially_destructible>(), "");
|
||||
static_assert(check_same<std::is_trivially_copyable>(), "");
|
||||
};
|
||||
|
||||
template <class ...Args> static void sink(Args&&...) {}
|
||||
|
||||
template <class ...TestTypes>
|
||||
struct DoTestsMetafunction {
|
||||
DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
|
||||
};
|
||||
|
||||
struct TrivialMoveNonTrivialCopy {
|
||||
TrivialMoveNonTrivialCopy() = default;
|
||||
TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
|
||||
TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
|
||||
TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
|
||||
TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
|
||||
};
|
||||
|
||||
struct TrivialCopyNonTrivialMove {
|
||||
TrivialCopyNonTrivialMove() = default;
|
||||
TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
|
||||
TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
|
||||
TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
|
||||
TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
sink(
|
||||
ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
|
||||
ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
|
||||
NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
|
||||
NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
|
||||
DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
|
||||
);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <optional>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#ifndef _LIBCPP_VERSION
|
||||
#error _LIBCPP_VERSION not defined
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
|
@ -59,7 +59,7 @@ int main()
|
|||
!std::is_nothrow_swappable_with<A&, A&>::value, "");
|
||||
}
|
||||
{
|
||||
// test that hetrogenius swap is allowed only if both 'swap(A, B)' and
|
||||
// test that heterogeneous swap is allowed only if both 'swap(A, B)' and
|
||||
// 'swap(B, A)' are valid.
|
||||
static_assert(std::is_nothrow_swappable_with<A&, B&>::value, "");
|
||||
static_assert(!std::is_nothrow_swappable_with<A&, C&>::value &&
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
|
||||
// <optional>
|
||||
|
||||
// class bad_optional_access is default constructible
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::bad_optional_access;
|
||||
bad_optional_access ex;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
|
||||
// <optional>
|
||||
|
||||
// class bad_optional_access : public logic_error
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::bad_optional_access;
|
||||
|
||||
static_assert(std::is_base_of<std::logic_error, bad_optional_access>::value, "");
|
||||
static_assert(std::is_convertible<bad_optional_access*, std::logic_error*>::value, "");
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator==(const optional<T>& x, const T& v);
|
||||
// template <class T> constexpr bool operator==(const T& v, const optional<T>& x);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator == ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ == rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr T val(2);
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
constexpr O o3{val}; // engaged
|
||||
|
||||
static_assert ( !(o1 == T(1)), "" );
|
||||
static_assert ( (o2 == T(1)), "" );
|
||||
static_assert ( !(o3 == T(1)), "" );
|
||||
static_assert ( (o3 == T(2)), "" );
|
||||
static_assert ( (o3 == val), "" );
|
||||
|
||||
static_assert ( !(T(1) == o1), "" );
|
||||
static_assert ( (T(1) == o2), "" );
|
||||
static_assert ( !(T(1) == o3), "" );
|
||||
static_assert ( (T(2) == o3), "" );
|
||||
static_assert ( (val == o3), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator>(const optional<T>& x, const T& v);
|
||||
// template <class T> constexpr bool operator>(const T& v, const optional<T>& x);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator > ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ > rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr T val(2);
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
constexpr O o3{val}; // engaged
|
||||
|
||||
static_assert ( !(o1 > T(1)), "" );
|
||||
static_assert ( !(o2 > T(1)), "" ); // equal
|
||||
static_assert ( (o3 > T(1)), "" );
|
||||
static_assert ( !(o2 > val), "" );
|
||||
static_assert ( !(o3 > val), "" ); // equal
|
||||
static_assert ( !(o3 > T(3)), "" );
|
||||
|
||||
static_assert ( (T(1) > o1), "" );
|
||||
static_assert ( !(T(1) > o2), "" ); // equal
|
||||
static_assert ( !(T(1) > o3), "" );
|
||||
static_assert ( (val > o2), "" );
|
||||
static_assert ( !(val > o3), "" ); // equal
|
||||
static_assert ( (T(3) > o3), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator>=(const optional<T>& x, const T& v);
|
||||
// template <class T> constexpr bool operator>=(const T& v, const optional<T>& x);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator >= ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ >= rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr T val(2);
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
constexpr O o3{val}; // engaged
|
||||
|
||||
static_assert ( !(o1 >= T(1)), "" );
|
||||
static_assert ( (o2 >= T(1)), "" ); // equal
|
||||
static_assert ( (o3 >= T(1)), "" );
|
||||
static_assert ( !(o2 >= val), "" );
|
||||
static_assert ( (o3 >= val), "" ); // equal
|
||||
static_assert ( !(o3 >= T(3)), "" );
|
||||
|
||||
static_assert ( (T(1) >= o1), "" );
|
||||
static_assert ( (T(1) >= o2), "" ); // equal
|
||||
static_assert ( !(T(1) >= o3), "" );
|
||||
static_assert ( (val >= o2), "" );
|
||||
static_assert ( (val >= o3), "" ); // equal
|
||||
static_assert ( (T(3) >= o3), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator<=(const optional<T>& x, const T& v);
|
||||
// template <class T> constexpr bool operator<=(const T& v, const optional<T>& x);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator <= ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ <= rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr T val(2);
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
constexpr O o3{val}; // engaged
|
||||
|
||||
static_assert ( (o1 <= T(1)), "" );
|
||||
static_assert ( (o2 <= T(1)), "" ); // equal
|
||||
static_assert ( !(o3 <= T(1)), "" );
|
||||
static_assert ( (o2 <= val), "" );
|
||||
static_assert ( (o3 <= val), "" ); // equal
|
||||
static_assert ( (o3 <= T(3)), "" );
|
||||
|
||||
static_assert ( !(T(1) <= o1), "" );
|
||||
static_assert ( (T(1) <= o2), "" ); // equal
|
||||
static_assert ( (T(1) <= o3), "" );
|
||||
static_assert ( !(val <= o2), "" );
|
||||
static_assert ( (val <= o3), "" ); // equal
|
||||
static_assert ( !(T(3) <= o3), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator<(const optional<T>& x, const T& v);
|
||||
// template <class T> constexpr bool operator<(const T& v, const optional<T>& x);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator < ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ < rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr T val(2);
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
constexpr O o3{val}; // engaged
|
||||
|
||||
static_assert ( (o1 < T(1)), "" );
|
||||
static_assert ( !(o2 < T(1)), "" ); // equal
|
||||
static_assert ( !(o3 < T(1)), "" );
|
||||
static_assert ( (o2 < val), "" );
|
||||
static_assert ( !(o3 < val), "" ); // equal
|
||||
static_assert ( (o3 < T(3)), "" );
|
||||
|
||||
static_assert ( !(T(1) < o1), "" );
|
||||
static_assert ( !(T(1) < o2), "" ); // equal
|
||||
static_assert ( (T(1) < o3), "" );
|
||||
static_assert ( !(val < o2), "" );
|
||||
static_assert ( !(val < o3), "" ); // equal
|
||||
static_assert ( !(T(3) < o3), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator!=(const optional<T>& x, const T& v);
|
||||
// template <class T> constexpr bool operator!=(const T& v, const optional<T>& x);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator != ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ != rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr T val(2);
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
constexpr O o3{val}; // engaged
|
||||
|
||||
static_assert ( (o1 != T(1)), "" );
|
||||
static_assert ( !(o2 != T(1)), "" );
|
||||
static_assert ( (o3 != T(1)), "" );
|
||||
static_assert ( !(o3 != T(2)), "" );
|
||||
static_assert ( !(o3 != val), "" );
|
||||
|
||||
static_assert ( (T(1) != o1), "" );
|
||||
static_assert ( !(T(1) != o2), "" );
|
||||
static_assert ( (T(1) != o3), "" );
|
||||
static_assert ( !(T(2) != o3), "" );
|
||||
static_assert ( !(val != o3), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> struct hash<optional<T>>;
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
const std::size_t nullopt_hash =
|
||||
std::hash<optional<double>>{}(optional<double>{});
|
||||
|
||||
{
|
||||
typedef int T;
|
||||
optional<T> opt;
|
||||
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
||||
opt = 2;
|
||||
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
||||
}
|
||||
{
|
||||
typedef std::string T;
|
||||
optional<T> opt;
|
||||
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
||||
opt = std::string("123");
|
||||
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
||||
}
|
||||
{
|
||||
typedef std::unique_ptr<int> T;
|
||||
optional<T> opt;
|
||||
assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
|
||||
opt = std::unique_ptr<int>(new int(3));
|
||||
assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept;
|
||||
// template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept;
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
{
|
||||
typedef int T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
|
||||
static_assert ( (nullopt == o1), "" );
|
||||
static_assert ( !(nullopt == o2), "" );
|
||||
static_assert ( (o1 == nullopt), "" );
|
||||
static_assert ( !(o2 == nullopt), "" );
|
||||
|
||||
static_assert (noexcept(nullopt == o1), "");
|
||||
static_assert (noexcept(o1 == nullopt), "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept;
|
||||
// template <class T> constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept;
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
{
|
||||
typedef int T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
|
||||
static_assert ( !(nullopt > o1), "" );
|
||||
static_assert ( !(nullopt > o2), "" );
|
||||
static_assert ( !(o1 > nullopt), "" );
|
||||
static_assert ( (o2 > nullopt), "" );
|
||||
|
||||
static_assert (noexcept(nullopt > o1), "");
|
||||
static_assert (noexcept(o1 > nullopt), "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept;
|
||||
// template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept;
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
{
|
||||
typedef int T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
|
||||
static_assert ( (nullopt >= o1), "" );
|
||||
static_assert ( !(nullopt >= o2), "" );
|
||||
static_assert ( (o1 >= nullopt), "" );
|
||||
static_assert ( (o2 >= nullopt), "" );
|
||||
|
||||
static_assert (noexcept(nullopt >= o1), "");
|
||||
static_assert (noexcept(o1 >= nullopt), "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept;
|
||||
// template <class T> constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept;
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
{
|
||||
typedef int T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
|
||||
static_assert ( (nullopt <= o1), "" );
|
||||
static_assert ( (nullopt <= o2), "" );
|
||||
static_assert ( (o1 <= nullopt), "" );
|
||||
static_assert ( !(o2 <= nullopt), "" );
|
||||
|
||||
static_assert (noexcept(nullopt <= o1), "");
|
||||
static_assert (noexcept(o1 <= nullopt), "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept;
|
||||
// template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept;
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
{
|
||||
typedef int T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
|
||||
static_assert ( !(nullopt < o1), "" );
|
||||
static_assert ( (nullopt < o2), "" );
|
||||
static_assert ( !(o1 < nullopt), "" );
|
||||
static_assert ( !(o2 < nullopt), "" );
|
||||
|
||||
static_assert (noexcept(nullopt < o1), "");
|
||||
static_assert (noexcept(o1 < nullopt), "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept;
|
||||
// template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept;
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
{
|
||||
typedef int T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2{1}; // engaged
|
||||
|
||||
static_assert ( !(nullopt != o1), "" );
|
||||
static_assert ( (nullopt != o2), "" );
|
||||
static_assert ( !(o1 != nullopt), "" );
|
||||
static_assert ( (o2 != nullopt), "" );
|
||||
|
||||
static_assert (noexcept(nullopt != o1), "");
|
||||
static_assert (noexcept(o1 != nullopt), "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// struct nullopt_t{see below};
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
|
||||
int main()
|
||||
{
|
||||
// I roughly interpret LWG2736 as "it shall not be possible to copy-list-initialize nullopt_t with an
|
||||
// empty braced-init-list."
|
||||
nullopt_t foo = {};
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// struct nullopt_t{see below};
|
||||
// constexpr nullopt_t nullopt(unspecified);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
constexpr
|
||||
int
|
||||
test(const nullopt_t&)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
static_assert((std::is_class<nullopt_t>::value), "");
|
||||
static_assert((std::is_empty<nullopt_t>::value), "");
|
||||
static_assert((std::is_literal_type<nullopt_t>::value), "");
|
||||
static_assert((!std::is_default_constructible<nullopt_t>::value), "");
|
||||
|
||||
static_assert(test(nullopt) == 3, "");
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U> optional<T>& operator=(U&& v);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct ThrowAssign {
|
||||
static int dtor_called;
|
||||
ThrowAssign() = default;
|
||||
ThrowAssign(int) { TEST_THROW(42); }
|
||||
ThrowAssign& operator=(int) {
|
||||
TEST_THROW(42);
|
||||
}
|
||||
~ThrowAssign() { ++dtor_called; }
|
||||
};
|
||||
int ThrowAssign::dtor_called = 0;
|
||||
|
||||
template <class T, class Arg = T, bool Expect = true>
|
||||
void assert_assignable() {
|
||||
static_assert(std::is_assignable<optional<T>&, Arg>::value == Expect, "");
|
||||
static_assert(!std::is_assignable<const optional<T>&, Arg>::value, "");
|
||||
}
|
||||
|
||||
struct MismatchType {
|
||||
explicit MismatchType(int) {}
|
||||
explicit MismatchType(char*) {}
|
||||
explicit MismatchType(int*) = delete;
|
||||
MismatchType& operator=(int) { return *this; }
|
||||
MismatchType& operator=(int*) { return *this; }
|
||||
MismatchType& operator=(char*) = delete;
|
||||
};
|
||||
|
||||
void test_sfinae() {
|
||||
using I = TestTypes::TestType;
|
||||
using E = ExplicitTestTypes::TestType;
|
||||
assert_assignable<int>();
|
||||
assert_assignable<int, int&>();
|
||||
assert_assignable<int, int const&>();
|
||||
// Implicit test type
|
||||
assert_assignable<I, I const&>();
|
||||
assert_assignable<I, I&&>();
|
||||
assert_assignable<I, int>();
|
||||
assert_assignable<I, void*, false>();
|
||||
// Explicit test type
|
||||
assert_assignable<E, E const&>();
|
||||
assert_assignable<E, E &&>();
|
||||
assert_assignable<E, int>();
|
||||
assert_assignable<E, void*, false>();
|
||||
// Mismatch type
|
||||
assert_assignable<MismatchType, int>();
|
||||
assert_assignable<MismatchType, int*, false>();
|
||||
assert_assignable<MismatchType, char*, false>();
|
||||
}
|
||||
|
||||
void test_with_test_type()
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
{ // to empty
|
||||
optional<T> opt;
|
||||
opt = 3;
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(3));
|
||||
}
|
||||
{ // to existing
|
||||
optional<T> opt(42);
|
||||
T::reset_constructors();
|
||||
opt = 3;
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 1);
|
||||
assert(T::value_assigned == 1);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(3));
|
||||
}
|
||||
{ // test default argument
|
||||
optional<T> opt;
|
||||
T::reset_constructors();
|
||||
opt = {1, 2};
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 2);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::move_constructed == 1);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(1, 2));
|
||||
}
|
||||
{ // test default argument
|
||||
optional<T> opt(42);
|
||||
T::reset_constructors();
|
||||
opt = {1, 2};
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::assigned == 1);
|
||||
assert(T::move_assigned == 1);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(1, 2));
|
||||
}
|
||||
{ // test default argument
|
||||
optional<T> opt;
|
||||
T::reset_constructors();
|
||||
opt = {1};
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 2);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::move_constructed == 1);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(1));
|
||||
}
|
||||
{ // test default argument
|
||||
optional<T> opt(42);
|
||||
T::reset_constructors();
|
||||
opt = {};
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
assert(T::alive == 0);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 1);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Value = int>
|
||||
void test_with_type() {
|
||||
{ // to empty
|
||||
optional<T> opt;
|
||||
opt = Value(3);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(3));
|
||||
}
|
||||
{ // to existing
|
||||
optional<T> opt(Value(42));
|
||||
opt = Value(3);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(3));
|
||||
}
|
||||
{ // test const
|
||||
optional<T> opt(Value(42));
|
||||
const T t(Value(3));
|
||||
opt = t;
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(3));
|
||||
}
|
||||
{ // test default argument
|
||||
optional<T> opt;
|
||||
opt = {Value(1)};
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(1));
|
||||
}
|
||||
{ // test default argument
|
||||
optional<T> opt(Value(42));
|
||||
opt = {};
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void test_with_type_multi() {
|
||||
test_with_type<T>();
|
||||
{ // test default argument
|
||||
optional<T> opt;
|
||||
opt = {1, 2};
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(1, 2));
|
||||
}
|
||||
{ // test default argument
|
||||
optional<T> opt(42);
|
||||
opt = {1, 2};
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(1, 2));
|
||||
}
|
||||
}
|
||||
|
||||
void test_throws()
|
||||
{
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
using T = ThrowAssign;
|
||||
{
|
||||
using T = ThrowAssign;
|
||||
optional<T> opt;
|
||||
try {
|
||||
opt = 42;
|
||||
assert(false);
|
||||
} catch (int) {}
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(T::dtor_called == 0);
|
||||
{
|
||||
T::dtor_called = 0;
|
||||
optional<T> opt(std::in_place);
|
||||
try {
|
||||
opt = 42;
|
||||
assert(false);
|
||||
} catch (int) {}
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(T::dtor_called == 0);
|
||||
}
|
||||
assert(T::dtor_called == 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
enum MyEnum { Zero, One, Two, Three, FortyTwo = 42 };
|
||||
|
||||
using Fn = void(*)();
|
||||
|
||||
int main()
|
||||
{
|
||||
test_sfinae();
|
||||
// Test with instrumented type
|
||||
test_with_test_type();
|
||||
// Test with various scalar types
|
||||
test_with_type<int>();
|
||||
test_with_type<MyEnum, MyEnum>();
|
||||
test_with_type<int, MyEnum>();
|
||||
test_with_type<Fn, Fn>();
|
||||
// Test types with multi argument constructors
|
||||
test_with_type_multi<ConstexprTestTypes::TestType>();
|
||||
test_with_type_multi<TrivialTestTypes::TestType>();
|
||||
// Test move only types
|
||||
{
|
||||
optional<std::unique_ptr<int>> opt;
|
||||
opt = std::unique_ptr<int>(new int(3));
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(**opt == 3);
|
||||
}
|
||||
{
|
||||
optional<std::unique_ptr<int>> opt(std::unique_ptr<int>(new int(2)));
|
||||
opt = std::unique_ptr<int>(new int(3));
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(**opt == 3);
|
||||
}
|
||||
test_throws();
|
||||
}
|
|
@ -0,0 +1,254 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// From LWG2451:
|
||||
// template<class U>
|
||||
// optional<T>& operator=(const optional<U>& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
static bool throw_now;
|
||||
|
||||
X() = default;
|
||||
X(int)
|
||||
{
|
||||
if (throw_now)
|
||||
TEST_THROW(6);
|
||||
}
|
||||
};
|
||||
|
||||
bool X::throw_now = false;
|
||||
|
||||
struct Y1
|
||||
{
|
||||
Y1() = default;
|
||||
Y1(const int&) {}
|
||||
Y1& operator=(const Y1&) = delete;
|
||||
};
|
||||
|
||||
struct Y2
|
||||
{
|
||||
Y2() = default;
|
||||
Y2(const int&) = delete;
|
||||
Y2& operator=(const int&) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct AssignableFrom {
|
||||
static int type_constructed;
|
||||
static int type_assigned;
|
||||
static int int_constructed;
|
||||
static int int_assigned;
|
||||
|
||||
static void reset() {
|
||||
type_constructed = int_constructed = 0;
|
||||
type_assigned = int_assigned = 0;
|
||||
}
|
||||
|
||||
AssignableFrom() = default;
|
||||
|
||||
explicit AssignableFrom(T) { ++type_constructed; }
|
||||
AssignableFrom& operator=(T) { ++type_assigned; return *this; }
|
||||
|
||||
AssignableFrom(int) { ++int_constructed; }
|
||||
AssignableFrom& operator=(int) { ++int_assigned; return *this; }
|
||||
private:
|
||||
AssignableFrom(AssignableFrom const&) = delete;
|
||||
AssignableFrom& operator=(AssignableFrom const&) = delete;
|
||||
};
|
||||
|
||||
template <class T> int AssignableFrom<T>::type_constructed = 0;
|
||||
template <class T> int AssignableFrom<T>::type_assigned = 0;
|
||||
template <class T> int AssignableFrom<T>::int_constructed = 0;
|
||||
template <class T> int AssignableFrom<T>::int_assigned = 0;
|
||||
|
||||
|
||||
void test_with_test_type() {
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
{ // non-empty to empty
|
||||
T::reset_constructors();
|
||||
optional<T> opt;
|
||||
const optional<int> other(42);
|
||||
opt = other;
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == true);
|
||||
assert(*other == 42);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(42));
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // non-empty to non-empty
|
||||
optional<T> opt(101);
|
||||
const optional<int> other(42);
|
||||
T::reset_constructors();
|
||||
opt = other;
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 1);
|
||||
assert(T::value_assigned == 1);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == true);
|
||||
assert(*other == 42);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(42));
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // empty to non-empty
|
||||
optional<T> opt(101);
|
||||
const optional<int> other;
|
||||
T::reset_constructors();
|
||||
opt = other;
|
||||
assert(T::alive == 0);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(other) == false);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // empty to empty
|
||||
optional<T> opt;
|
||||
const optional<int> other;
|
||||
T::reset_constructors();
|
||||
opt = other;
|
||||
assert(T::alive == 0);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == false);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
}
|
||||
|
||||
void test_ambigious_assign() {
|
||||
using OptInt = std::optional<int>;
|
||||
{
|
||||
using T = AssignableFrom<OptInt const&>;
|
||||
const OptInt a(42);
|
||||
T::reset();
|
||||
{
|
||||
std::optional<T> t;
|
||||
t = a;
|
||||
assert(T::type_constructed == 1);
|
||||
assert(T::type_assigned == 0);
|
||||
assert(T::int_constructed == 0);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
T::reset();
|
||||
{
|
||||
std::optional<T> t(42);
|
||||
t = a;
|
||||
assert(T::type_constructed == 0);
|
||||
assert(T::type_assigned == 1);
|
||||
assert(T::int_constructed == 1);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
T::reset();
|
||||
{
|
||||
std::optional<T> t(42);
|
||||
t = std::move(a);
|
||||
assert(T::type_constructed == 0);
|
||||
assert(T::type_assigned == 1);
|
||||
assert(T::int_constructed == 1);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
}
|
||||
{
|
||||
using T = AssignableFrom<OptInt&>;
|
||||
OptInt a(42);
|
||||
T::reset();
|
||||
{
|
||||
std::optional<T> t;
|
||||
t = a;
|
||||
assert(T::type_constructed == 1);
|
||||
assert(T::type_assigned == 0);
|
||||
assert(T::int_constructed == 0);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
{
|
||||
using Opt = std::optional<T>;
|
||||
static_assert(!std::is_assignable_v<Opt&, OptInt const&>, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test_with_test_type();
|
||||
test_ambigious_assign();
|
||||
{
|
||||
optional<int> opt;
|
||||
constexpr optional<short> opt2;
|
||||
opt = opt2;
|
||||
static_assert(static_cast<bool>(opt2) == false, "");
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
optional<int> opt;
|
||||
constexpr optional<short> opt2(short{2});
|
||||
opt = opt2;
|
||||
static_assert(static_cast<bool>(opt2) == true, "");
|
||||
static_assert(*opt2 == 2, "");
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
assert(*opt == *opt2);
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
constexpr optional<short> opt2;
|
||||
opt = opt2;
|
||||
static_assert(static_cast<bool>(opt2) == false, "");
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
constexpr optional<short> opt2(short{2});
|
||||
opt = opt2;
|
||||
static_assert(static_cast<bool>(opt2) == true, "");
|
||||
static_assert(*opt2 == 2, "");
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
assert(*opt == *opt2);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
optional<X> opt;
|
||||
optional<int> opt2(42);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
try
|
||||
{
|
||||
X::throw_now = true;
|
||||
opt = opt2;
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// optional<T>& operator=(const optional<T>& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
static bool throw_now;
|
||||
|
||||
X() = default;
|
||||
X(const X&)
|
||||
{
|
||||
if (throw_now)
|
||||
TEST_THROW(6);
|
||||
}
|
||||
};
|
||||
|
||||
bool X::throw_now = false;
|
||||
|
||||
template <class Tp>
|
||||
constexpr bool assign_empty(optional<Tp>&& lhs) {
|
||||
const optional<Tp> rhs;
|
||||
lhs = rhs;
|
||||
return !lhs.has_value() && !rhs.has_value();
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
constexpr bool assign_value(optional<Tp>&& lhs) {
|
||||
const optional<Tp> rhs(101);
|
||||
lhs = rhs;
|
||||
return lhs.has_value() && rhs.has_value() && *lhs == *rhs;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
using O = optional<int>;
|
||||
LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
|
||||
LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
|
||||
assert(assign_empty(O{42}));
|
||||
assert(assign_value(O{42}));
|
||||
}
|
||||
{
|
||||
using O = optional<TrivialTestTypes::TestType>;
|
||||
LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
|
||||
LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
|
||||
assert(assign_empty(O{42}));
|
||||
assert(assign_value(O{42}));
|
||||
}
|
||||
{
|
||||
using O = optional<TestTypes::TestType>;
|
||||
assert(assign_empty(O{42}));
|
||||
assert(assign_value(O{42}));
|
||||
}
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
optional<T> opt(3);
|
||||
const optional<T> opt2;
|
||||
assert(T::alive == 1);
|
||||
opt = opt2;
|
||||
assert(T::alive == 0);
|
||||
assert(!opt2.has_value());
|
||||
assert(!opt.has_value());
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
optional<X> opt;
|
||||
optional<X> opt2(X{});
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
try
|
||||
{
|
||||
X::throw_now = true;
|
||||
opt = opt2;
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class... Args> void optional<T>::emplace(Args&&... args);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
X() : i_(0) {}
|
||||
X(int i) : i_(i) {}
|
||||
X(int i, int j) : i_(i), j_(j) {}
|
||||
|
||||
friend bool operator==(const X& x, const X& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
class Y
|
||||
{
|
||||
public:
|
||||
static bool dtor_called;
|
||||
Y() = default;
|
||||
Y(int) { TEST_THROW(6);}
|
||||
~Y() {dtor_called = true;}
|
||||
};
|
||||
|
||||
bool Y::dtor_called = false;
|
||||
|
||||
template <class T>
|
||||
void test_one_arg() {
|
||||
using Opt = std::optional<T>;
|
||||
{
|
||||
Opt opt;
|
||||
opt.emplace();
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(0));
|
||||
}
|
||||
{
|
||||
Opt opt;
|
||||
opt.emplace(1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(1));
|
||||
}
|
||||
{
|
||||
Opt opt(2);
|
||||
opt.emplace();
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(0));
|
||||
}
|
||||
{
|
||||
Opt opt(2);
|
||||
opt.emplace(1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void test_multi_arg()
|
||||
{
|
||||
test_one_arg<T>();
|
||||
using Opt = std::optional<T>;
|
||||
Opt opt;
|
||||
{
|
||||
opt.emplace(101, 41);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(101, 41));
|
||||
}
|
||||
{
|
||||
Opt opt;
|
||||
opt.emplace({1, 2, 3, 4});
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(4)); // T sets its value to the size of the init list
|
||||
}
|
||||
{
|
||||
Opt opt;
|
||||
opt.emplace({1, 2, 3, 4, 5}, 6);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(5)); // T sets its value to the size of the init list
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void test_on_test_type() {
|
||||
|
||||
T::reset();
|
||||
optional<T> opt;
|
||||
assert(T::alive == 0);
|
||||
{
|
||||
T::reset_constructors();
|
||||
opt.emplace();
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::default_constructed == 1);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T());
|
||||
}
|
||||
{
|
||||
T::reset_constructors();
|
||||
opt.emplace();
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::default_constructed == 1);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T());
|
||||
}
|
||||
{
|
||||
T::reset_constructors();
|
||||
opt.emplace(101);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(101));
|
||||
}
|
||||
{
|
||||
T::reset_constructors();
|
||||
opt.emplace(-10, 99);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(-10, 99));
|
||||
}
|
||||
{
|
||||
T::reset_constructors();
|
||||
opt.emplace(-10, 99);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(-10, 99));
|
||||
}
|
||||
{
|
||||
T::reset_constructors();
|
||||
opt.emplace({-10, 99, 42, 1});
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(4)); // size of the initializer list
|
||||
}
|
||||
{
|
||||
T::reset_constructors();
|
||||
opt.emplace({-10, 99, 42, 1}, 42);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(4)); // size of the initializer list
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
test_on_test_type<TestTypes::TestType>();
|
||||
test_on_test_type<ExplicitTestTypes::TestType>();
|
||||
}
|
||||
{
|
||||
using T = int;
|
||||
test_one_arg<T>();
|
||||
test_one_arg<const T>();
|
||||
}
|
||||
{
|
||||
using T = ConstexprTestTypes::TestType;
|
||||
test_multi_arg<T>();
|
||||
}
|
||||
{
|
||||
using T = ExplicitConstexprTestTypes::TestType;
|
||||
test_multi_arg<T>();
|
||||
}
|
||||
{
|
||||
using T = TrivialTestTypes::TestType;
|
||||
test_multi_arg<T>();
|
||||
}
|
||||
{
|
||||
using T = ExplicitTrivialTestTypes::TestType;
|
||||
test_multi_arg<T>();
|
||||
}
|
||||
{
|
||||
optional<const int> opt;
|
||||
opt.emplace(42);
|
||||
assert(*opt == 42);
|
||||
opt.emplace();
|
||||
assert(*opt == 0);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
Y::dtor_called = false;
|
||||
{
|
||||
Y y;
|
||||
optional<Y> opt(y);
|
||||
try
|
||||
{
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(Y::dtor_called == false);
|
||||
opt.emplace(1);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
assert(Y::dtor_called == true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U, class... Args>
|
||||
// void optional<T>::emplace(initializer_list<U> il, Args&&... args);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
static bool dtor_called;
|
||||
constexpr X() : i_(0) {}
|
||||
constexpr X(int i) : i_(i) {}
|
||||
constexpr X(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
|
||||
~X() {dtor_called = true;}
|
||||
|
||||
friend constexpr bool operator==(const X& x, const X& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
bool X::dtor_called = false;
|
||||
|
||||
class Y
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
constexpr Y() : i_(0) {}
|
||||
constexpr Y(int i) : i_(i) {}
|
||||
constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
|
||||
|
||||
friend constexpr bool operator==(const Y& x, const Y& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
class Z
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
static bool dtor_called;
|
||||
Z() : i_(0) {}
|
||||
Z(int i) : i_(i) {}
|
||||
Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
|
||||
{ TEST_THROW(6);}
|
||||
~Z() {dtor_called = true;}
|
||||
|
||||
friend bool operator==(const Z& x, const Z& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
bool Z::dtor_called = false;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
X x;
|
||||
optional<X> opt(x);
|
||||
assert(X::dtor_called == false);
|
||||
opt.emplace({1, 2});
|
||||
assert(X::dtor_called == true);
|
||||
assert(*opt == X({1, 2}));
|
||||
}
|
||||
{
|
||||
optional<std::vector<int>> opt;
|
||||
opt.emplace({1, 2, 3}, std::allocator<int>());
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == std::vector<int>({1, 2, 3}));
|
||||
}
|
||||
{
|
||||
optional<Y> opt;
|
||||
opt.emplace({1, 2});
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == Y({1, 2}));
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
Z z;
|
||||
optional<Z> opt(z);
|
||||
try
|
||||
{
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(Z::dtor_called == false);
|
||||
opt.emplace({1, 2});
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
assert(Z::dtor_called == true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// optional<T>& operator=(optional<T>&& rhs)
|
||||
// noexcept(is_nothrow_move_assignable<T>::value &&
|
||||
// is_nothrow_move_constructible<T>::value);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
static bool throw_now;
|
||||
static int alive;
|
||||
|
||||
X() { ++alive; }
|
||||
X(X&&)
|
||||
{
|
||||
if (throw_now)
|
||||
TEST_THROW(6);
|
||||
++alive;
|
||||
}
|
||||
|
||||
X& operator=(X&&)
|
||||
{
|
||||
if (throw_now)
|
||||
TEST_THROW(42);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~X() { assert(alive > 0); --alive; }
|
||||
};
|
||||
|
||||
struct Y {};
|
||||
|
||||
bool X::throw_now = false;
|
||||
int X::alive = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
|
||||
optional<int> opt;
|
||||
constexpr optional<int> opt2;
|
||||
opt = std::move(opt2);
|
||||
static_assert(static_cast<bool>(opt2) == false, "");
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
optional<int> opt;
|
||||
constexpr optional<int> opt2(2);
|
||||
opt = std::move(opt2);
|
||||
static_assert(static_cast<bool>(opt2) == true, "");
|
||||
static_assert(*opt2 == 2, "");
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
assert(*opt == *opt2);
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
constexpr optional<int> opt2;
|
||||
opt = std::move(opt2);
|
||||
static_assert(static_cast<bool>(opt2) == false, "");
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
optional<T> opt(3);
|
||||
optional<T> opt2;
|
||||
assert(T::alive == 1);
|
||||
opt = std::move(opt2);
|
||||
assert(T::alive == 0);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
constexpr optional<int> opt2(2);
|
||||
opt = std::move(opt2);
|
||||
static_assert(static_cast<bool>(opt2) == true, "");
|
||||
static_assert(*opt2 == 2, "");
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
assert(*opt == *opt2);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
|
||||
X::alive = 0;
|
||||
X::throw_now = false;
|
||||
optional<X> opt;
|
||||
optional<X> opt2(X{});
|
||||
assert(X::alive == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
try
|
||||
{
|
||||
X::throw_now = true;
|
||||
opt = std::move(opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(X::alive == 1);
|
||||
}
|
||||
assert(X::alive == 0);
|
||||
{
|
||||
static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
|
||||
X::throw_now = false;
|
||||
optional<X> opt(X{});
|
||||
optional<X> opt2(X{});
|
||||
assert(X::alive == 2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
try
|
||||
{
|
||||
X::throw_now = true;
|
||||
opt = std::move(opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 42);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
}
|
||||
assert(X::alive == 2);
|
||||
}
|
||||
assert(X::alive == 0);
|
||||
#endif // TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
|
||||
}
|
||||
{
|
||||
struct ThrowsMove {
|
||||
ThrowsMove() noexcept {}
|
||||
ThrowsMove(ThrowsMove const&) noexcept {}
|
||||
ThrowsMove(ThrowsMove &&) noexcept(false) {}
|
||||
ThrowsMove& operator=(ThrowsMove const&) noexcept { return *this; }
|
||||
ThrowsMove& operator=(ThrowsMove &&) noexcept { return *this; }
|
||||
};
|
||||
static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMove>>::value, "");
|
||||
struct ThrowsMoveAssign {
|
||||
ThrowsMoveAssign() noexcept {}
|
||||
ThrowsMoveAssign(ThrowsMoveAssign const&) noexcept {}
|
||||
ThrowsMoveAssign(ThrowsMoveAssign &&) noexcept {}
|
||||
ThrowsMoveAssign& operator=(ThrowsMoveAssign const&) noexcept { return *this; }
|
||||
ThrowsMoveAssign& operator=(ThrowsMoveAssign &&) noexcept(false) { return *this; }
|
||||
};
|
||||
static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMoveAssign>>::value, "");
|
||||
struct NoThrowMove {
|
||||
NoThrowMove() noexcept(false) {}
|
||||
NoThrowMove(NoThrowMove const&) noexcept(false) {}
|
||||
NoThrowMove(NoThrowMove &&) noexcept {}
|
||||
NoThrowMove& operator=(NoThrowMove const&) noexcept { return *this; }
|
||||
NoThrowMove& operator=(NoThrowMove&&) noexcept { return *this; }
|
||||
};
|
||||
static_assert(std::is_nothrow_move_assignable<optional<NoThrowMove>>::value, "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// optional<T>& operator=(nullopt_t) noexcept;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<int> opt;
|
||||
static_assert(noexcept(opt = nullopt) == true, "");
|
||||
opt = nullopt;
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
opt = nullopt;
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
using TT = TestTypes::TestType;
|
||||
TT::reset();
|
||||
{
|
||||
optional<TT> opt;
|
||||
static_assert(noexcept(opt = nullopt) == true, "");
|
||||
assert(TT::destroyed == 0);
|
||||
opt = nullopt;
|
||||
assert(TT::constructed == 0);
|
||||
assert(TT::alive == 0);
|
||||
assert(TT::destroyed == 0);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(TT::alive == 0);
|
||||
assert(TT::destroyed == 0);
|
||||
TT::reset();
|
||||
{
|
||||
optional<TT> opt(42);
|
||||
assert(TT::destroyed == 0);
|
||||
TT::reset_constructors();
|
||||
opt = nullopt;
|
||||
assert(TT::constructed == 0);
|
||||
assert(TT::alive == 0);
|
||||
assert(TT::destroyed == 1);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(TT::alive == 0);
|
||||
assert(TT::destroyed == 1);
|
||||
TT::reset();
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// From LWG2451:
|
||||
// template <class U>
|
||||
// optional<T>& operator=(optional<U>&& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
static bool throw_now;
|
||||
|
||||
X() = default;
|
||||
X(int &&)
|
||||
{
|
||||
if (throw_now)
|
||||
TEST_THROW(6);
|
||||
}
|
||||
};
|
||||
|
||||
bool X::throw_now = false;
|
||||
|
||||
struct Y1
|
||||
{
|
||||
Y1() = default;
|
||||
Y1(const int&) {}
|
||||
Y1& operator=(const Y1&) = delete;
|
||||
};
|
||||
|
||||
struct Y2
|
||||
{
|
||||
Y2() = default;
|
||||
Y2(const int&) = delete;
|
||||
Y2& operator=(const int&) { return *this; }
|
||||
};
|
||||
|
||||
class B {};
|
||||
class D : public B {};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct AssignableFrom {
|
||||
static int type_constructed;
|
||||
static int type_assigned;
|
||||
static int int_constructed;
|
||||
static int int_assigned;
|
||||
|
||||
static void reset() {
|
||||
type_constructed = int_constructed = 0;
|
||||
type_assigned = int_assigned = 0;
|
||||
}
|
||||
|
||||
AssignableFrom() = default;
|
||||
|
||||
explicit AssignableFrom(T) { ++type_constructed; }
|
||||
AssignableFrom& operator=(T) { ++type_assigned; return *this; }
|
||||
|
||||
AssignableFrom(int) { ++int_constructed; }
|
||||
AssignableFrom& operator=(int) { ++int_assigned; return *this; }
|
||||
private:
|
||||
AssignableFrom(AssignableFrom const&) = delete;
|
||||
AssignableFrom& operator=(AssignableFrom const&) = delete;
|
||||
};
|
||||
|
||||
template <class T> int AssignableFrom<T>::type_constructed = 0;
|
||||
template <class T> int AssignableFrom<T>::type_assigned = 0;
|
||||
template <class T> int AssignableFrom<T>::int_constructed = 0;
|
||||
template <class T> int AssignableFrom<T>::int_assigned = 0;
|
||||
|
||||
void test_with_test_type() {
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
{ // non-empty to empty
|
||||
T::reset_constructors();
|
||||
optional<T> opt;
|
||||
optional<int> other(42);
|
||||
opt = std::move(other);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == true);
|
||||
assert(*other == 42);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(42));
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // non-empty to non-empty
|
||||
optional<T> opt(101);
|
||||
optional<int> other(42);
|
||||
T::reset_constructors();
|
||||
opt = std::move(other);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 1);
|
||||
assert(T::value_assigned == 1);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == true);
|
||||
assert(*other == 42);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(42));
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // empty to non-empty
|
||||
optional<T> opt(101);
|
||||
optional<int> other;
|
||||
T::reset_constructors();
|
||||
opt = std::move(other);
|
||||
assert(T::alive == 0);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(other) == false);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // empty to empty
|
||||
optional<T> opt;
|
||||
optional<int> other;
|
||||
T::reset_constructors();
|
||||
opt = std::move(other);
|
||||
assert(T::alive == 0);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == false);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
}
|
||||
|
||||
|
||||
void test_ambigious_assign() {
|
||||
using OptInt = std::optional<int>;
|
||||
{
|
||||
using T = AssignableFrom<OptInt&&>;
|
||||
T::reset();
|
||||
{
|
||||
OptInt a(42);
|
||||
std::optional<T> t;
|
||||
t = std::move(a);
|
||||
assert(T::type_constructed == 1);
|
||||
assert(T::type_assigned == 0);
|
||||
assert(T::int_constructed == 0);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
{
|
||||
using Opt = std::optional<T>;
|
||||
static_assert(!std::is_assignable<Opt&, const OptInt&&>::value, "");
|
||||
static_assert(!std::is_assignable<Opt&, const OptInt&>::value, "");
|
||||
static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
|
||||
}
|
||||
}
|
||||
{
|
||||
using T = AssignableFrom<OptInt const&&>;
|
||||
T::reset();
|
||||
{
|
||||
const OptInt a(42);
|
||||
std::optional<T> t;
|
||||
t = std::move(a);
|
||||
assert(T::type_constructed == 1);
|
||||
assert(T::type_assigned == 0);
|
||||
assert(T::int_constructed == 0);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
T::reset();
|
||||
{
|
||||
OptInt a(42);
|
||||
std::optional<T> t;
|
||||
t = std::move(a);
|
||||
assert(T::type_constructed == 1);
|
||||
assert(T::type_assigned == 0);
|
||||
assert(T::int_constructed == 0);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
{
|
||||
using Opt = std::optional<T>;
|
||||
static_assert(std::is_assignable<Opt&, OptInt&&>::value, "");
|
||||
static_assert(!std::is_assignable<Opt&, const OptInt&>::value, "");
|
||||
static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test_with_test_type();
|
||||
test_ambigious_assign();
|
||||
{
|
||||
optional<int> opt;
|
||||
optional<short> opt2;
|
||||
opt = std::move(opt2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
optional<int> opt;
|
||||
optional<short> opt2(short{2});
|
||||
opt = std::move(opt2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
assert(*opt == *opt2);
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
optional<short> opt2;
|
||||
opt = std::move(opt2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
optional<short> opt2(short{2});
|
||||
opt = std::move(opt2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
assert(*opt == *opt2);
|
||||
}
|
||||
{
|
||||
optional<std::unique_ptr<B>> opt;
|
||||
optional<std::unique_ptr<D>> other(new D());
|
||||
opt = std::move(other);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(static_cast<bool>(other) == true);
|
||||
assert(opt->get() != nullptr);
|
||||
assert(other->get() == nullptr);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
optional<X> opt;
|
||||
optional<int> opt2(42);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
try
|
||||
{
|
||||
X::throw_now = true;
|
||||
opt = std::move(opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
|
||||
// <optional>
|
||||
|
||||
// template <class U>
|
||||
// constexpr EXPLICIT optional(U&& u);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
#include "test_convertible.hpp"
|
||||
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct ImplicitThrow
|
||||
{
|
||||
constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
|
||||
};
|
||||
|
||||
struct ExplicitThrow
|
||||
{
|
||||
constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
|
||||
};
|
||||
|
||||
|
||||
template <class To, class From>
|
||||
constexpr bool implicit_conversion(optional<To>&& opt, const From& v)
|
||||
{
|
||||
using O = optional<To>;
|
||||
static_assert(test_convertible<O, From>(), "");
|
||||
static_assert(!test_convertible<O, void*>(), "");
|
||||
static_assert(!test_convertible<O, From, int>(), "");
|
||||
return opt && *opt == static_cast<To>(v);
|
||||
}
|
||||
|
||||
template <class To, class Input, class Expect>
|
||||
constexpr bool explicit_conversion(Input&& in, const Expect& v)
|
||||
{
|
||||
using O = optional<To>;
|
||||
static_assert(std::is_constructible<O, Input>::value, "");
|
||||
static_assert(!std::is_convertible<Input, O>::value, "");
|
||||
static_assert(!std::is_constructible<O, void*>::value, "");
|
||||
static_assert(!std::is_constructible<O, Input, int>::value, "");
|
||||
optional<To> opt(std::forward<Input>(in));
|
||||
return opt && *opt == static_cast<To>(v);
|
||||
}
|
||||
|
||||
void test_implicit()
|
||||
{
|
||||
{
|
||||
using T = long long;
|
||||
static_assert(implicit_conversion<long long>(42, 42), "");
|
||||
}
|
||||
{
|
||||
using T = long double;
|
||||
static_assert(implicit_conversion<long double>(3.14, 3.14), "");
|
||||
}
|
||||
{
|
||||
using T = TrivialTestTypes::TestType;
|
||||
static_assert(implicit_conversion<T>(42, 42), "");
|
||||
}
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
assert(implicit_conversion<T>(3, T(3)));
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
try {
|
||||
using T = ImplicitThrow;
|
||||
optional<T> t = 42;
|
||||
assert(false);
|
||||
} catch (int) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_explicit() {
|
||||
{
|
||||
using T = ExplicitTrivialTestTypes::TestType;
|
||||
using O = optional<T>;
|
||||
static_assert(explicit_conversion<T>(42, 42), "");
|
||||
}
|
||||
{
|
||||
using T = ExplicitConstexprTestTypes::TestType;
|
||||
using O = optional<T>;
|
||||
static_assert(explicit_conversion<T>(42, 42), "");
|
||||
static_assert(!std::is_convertible<int, T>::value, "");
|
||||
}
|
||||
{
|
||||
using T = ExplicitTestTypes::TestType;
|
||||
using O = optional<T>;
|
||||
T::reset();
|
||||
{
|
||||
assert(explicit_conversion<T>(42, 42));
|
||||
assert(T::alive == 0);
|
||||
}
|
||||
T::reset();
|
||||
{
|
||||
optional<T> t(42);
|
||||
assert(T::alive == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::move_constructed == 0);
|
||||
assert(T::copy_constructed == 0);
|
||||
assert(t.value().value == 42);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
try {
|
||||
using T = ExplicitThrow;
|
||||
optional<T> t(42);
|
||||
assert(false);
|
||||
} catch (int) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_implicit();
|
||||
test_explicit();
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
|
||||
// <optional>
|
||||
|
||||
// constexpr optional(const T& v);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef int T;
|
||||
constexpr T t(5);
|
||||
constexpr optional<T> opt(t);
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == 5, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(const T&) {}
|
||||
};
|
||||
|
||||
}
|
||||
{
|
||||
typedef double T;
|
||||
constexpr T t(3);
|
||||
constexpr optional<T> opt(t);
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == 3, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(const T&) {}
|
||||
};
|
||||
|
||||
}
|
||||
{
|
||||
typedef TestTypes::TestType T;
|
||||
T::reset();
|
||||
const T t(3);
|
||||
optional<T> opt = t;
|
||||
assert(T::alive == 2);
|
||||
assert(T::copy_constructed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(opt.value().value == 3);
|
||||
}
|
||||
{
|
||||
typedef ExplicitTestTypes::TestType T;
|
||||
static_assert(!std::is_convertible<T const&, optional<T>>::value, "");
|
||||
T::reset();
|
||||
const T t(3);
|
||||
optional<T> opt(t);
|
||||
assert(T::alive == 2);
|
||||
assert(T::copy_constructed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(opt.value().value == 3);
|
||||
}
|
||||
{
|
||||
typedef ConstexprTestTypes::TestType T;
|
||||
constexpr T t(3);
|
||||
constexpr optional<T> opt = {t};
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(opt.value().value == 3, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(const T&) {}
|
||||
};
|
||||
}
|
||||
{
|
||||
typedef ExplicitConstexprTestTypes::TestType T;
|
||||
static_assert(!std::is_convertible<const T&, optional<T>>::value, "");
|
||||
constexpr T t(3);
|
||||
constexpr optional<T> opt(t);
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(opt.value().value == 3, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(const T&) {}
|
||||
};
|
||||
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
struct Z {
|
||||
Z(int) {}
|
||||
Z(const Z&) {throw 6;}
|
||||
};
|
||||
typedef Z T;
|
||||
try
|
||||
{
|
||||
const T t(3);
|
||||
optional<T> opt(t);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U>
|
||||
// optional(const optional<U>& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
template <class T, class U>
|
||||
void
|
||||
test(const optional<U>& rhs, bool is_going_to_throw = false)
|
||||
{
|
||||
bool rhs_engaged = static_cast<bool>(rhs);
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
optional<T> lhs = rhs;
|
||||
assert(is_going_to_throw == false);
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
if (rhs_engaged)
|
||||
assert(*lhs == *rhs);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
#else
|
||||
if (is_going_to_throw) return;
|
||||
optional<T> lhs = rhs;
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
if (rhs_engaged)
|
||||
assert(*lhs == *rhs);
|
||||
#endif
|
||||
}
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
X(int i) : i_(i) {}
|
||||
X(const X& x) : i_(x.i_) {}
|
||||
~X() {i_ = 0;}
|
||||
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
class Y
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
Y(int i) : i_(i) {}
|
||||
|
||||
friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
int count = 0;
|
||||
|
||||
class Z
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
Z(int i) : i_(i) {TEST_THROW(6);}
|
||||
|
||||
friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef short U;
|
||||
typedef int T;
|
||||
optional<U> rhs;
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef short U;
|
||||
typedef int T;
|
||||
optional<U> rhs(U{3});
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef X T;
|
||||
typedef int U;
|
||||
optional<U> rhs;
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef X T;
|
||||
typedef int U;
|
||||
optional<U> rhs(U{3});
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef Y T;
|
||||
typedef int U;
|
||||
optional<U> rhs;
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef Y T;
|
||||
typedef int U;
|
||||
optional<U> rhs(U{3});
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef Z T;
|
||||
typedef int U;
|
||||
optional<U> rhs;
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef Z T;
|
||||
typedef int U;
|
||||
optional<U> rhs(U{3});
|
||||
test<T>(rhs, true);
|
||||
}
|
||||
|
||||
static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value), "");
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// optional(const optional<T>& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
template <class T, class ...InitArgs>
|
||||
void test(InitArgs&&... args)
|
||||
{
|
||||
const optional<T> rhs(std::forward<InitArgs>(args)...);
|
||||
bool rhs_engaged = static_cast<bool>(rhs);
|
||||
optional<T> lhs = rhs;
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
if (rhs_engaged)
|
||||
assert(*lhs == *rhs);
|
||||
}
|
||||
|
||||
void test_throwing_ctor() {
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
struct Z {
|
||||
Z() : count(0) {}
|
||||
Z(Z const& o) : count(o.count + 1)
|
||||
{ if (count == 2) throw 6; }
|
||||
int count;
|
||||
};
|
||||
const Z z;
|
||||
const optional<Z> rhs(z);
|
||||
try
|
||||
{
|
||||
optional<Z> lhs(rhs);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, class ...InitArgs>
|
||||
void test_ref(InitArgs&&... args)
|
||||
{
|
||||
const optional<T> rhs(std::forward<InitArgs>(args)...);
|
||||
bool rhs_engaged = static_cast<bool>(rhs);
|
||||
optional<T> lhs = rhs;
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
if (rhs_engaged)
|
||||
assert(&(*lhs) == &(*rhs));
|
||||
}
|
||||
|
||||
|
||||
void test_reference_extension()
|
||||
{
|
||||
#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
{
|
||||
T t;
|
||||
T::reset_constructors();
|
||||
test_ref<T&>();
|
||||
test_ref<T&>(t);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
}
|
||||
assert(T::destroyed == 1);
|
||||
assert(T::alive == 0);
|
||||
{
|
||||
T t;
|
||||
const T& ct = t;
|
||||
T::reset_constructors();
|
||||
test_ref<T const&>();
|
||||
test_ref<T const&>(t);
|
||||
test_ref<T const&>(ct);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
assert(T::destroyed == 1);
|
||||
{
|
||||
static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
|
||||
static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test<int>();
|
||||
test<int>(3);
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
const optional<T> rhs;
|
||||
assert(T::alive == 0);
|
||||
const optional<T> lhs(rhs);
|
||||
assert(lhs.has_value() == false);
|
||||
assert(T::alive == 0);
|
||||
}
|
||||
TestTypes::TestType::reset();
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
const optional<T> rhs(42);
|
||||
assert(T::alive == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::copy_constructed == 0);
|
||||
const optional<T> lhs(rhs);
|
||||
assert(lhs.has_value());
|
||||
assert(T::copy_constructed == 1);
|
||||
assert(T::alive == 2);
|
||||
}
|
||||
TestTypes::TestType::reset();
|
||||
{
|
||||
using namespace ConstexprTestTypes;
|
||||
test<TestType>();
|
||||
test<TestType>(42);
|
||||
}
|
||||
{
|
||||
using namespace TrivialTestTypes;
|
||||
test<TestType>();
|
||||
test<TestType>(42);
|
||||
}
|
||||
{
|
||||
test_throwing_ctor();
|
||||
}
|
||||
{
|
||||
test_reference_extension();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr optional() noexcept;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
template <class Opt>
|
||||
void
|
||||
test_constexpr()
|
||||
{
|
||||
static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
|
||||
static_assert(std::is_trivially_destructible<Opt>::value, "");
|
||||
static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
|
||||
|
||||
constexpr Opt opt;
|
||||
static_assert(static_cast<bool>(opt) == false, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public Opt
|
||||
{
|
||||
constexpr test_constexpr_ctor() {}
|
||||
};
|
||||
}
|
||||
|
||||
template <class Opt>
|
||||
void
|
||||
test()
|
||||
{
|
||||
static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
|
||||
static_assert(!std::is_trivially_destructible<Opt>::value, "");
|
||||
static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
|
||||
{
|
||||
Opt opt;
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
{
|
||||
const Opt opt;
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public Opt
|
||||
{
|
||||
constexpr test_constexpr_ctor() {}
|
||||
};
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_constexpr<optional<int>>();
|
||||
test_constexpr<optional<int*>>();
|
||||
test_constexpr<optional<ImplicitTypes::NoCtors>>();
|
||||
test_constexpr<optional<NonTrivialTypes::NoCtors>>();
|
||||
test_constexpr<optional<NonConstexprTypes::NoCtors>>();
|
||||
test<optional<NonLiteralTypes::NoCtors>>();
|
||||
// EXTENSIONS
|
||||
#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
|
||||
test_constexpr<optional<int&>>();
|
||||
test_constexpr<optional<const int&>>();
|
||||
test_constexpr<optional<int&>>();
|
||||
test_constexpr<optional<NonLiteralTypes::NoCtors&>>();
|
||||
test_constexpr<optional<NonLiteralTypes::NoCtors&&>>();
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U>
|
||||
// explicit optional(const optional<U>& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
template <class T, class U>
|
||||
void
|
||||
test(const optional<U>& rhs, bool is_going_to_throw = false)
|
||||
{
|
||||
static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value), "");
|
||||
bool rhs_engaged = static_cast<bool>(rhs);
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
optional<T> lhs(rhs);
|
||||
assert(is_going_to_throw == false);
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
if (rhs_engaged)
|
||||
assert(*lhs == T(*rhs));
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
#else
|
||||
if (is_going_to_throw) return;
|
||||
optional<T> lhs(rhs);
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
if (rhs_engaged)
|
||||
assert(*lhs == T(*rhs));
|
||||
#endif
|
||||
}
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
explicit X(int i) : i_(i) {}
|
||||
X(const X& x) : i_(x.i_) {}
|
||||
~X() {i_ = 0;}
|
||||
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
class Y
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
explicit Y(int i) : i_(i) {}
|
||||
|
||||
friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
int count = 0;
|
||||
|
||||
class Z
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
explicit Z(int i) : i_(i) { TEST_THROW(6);}
|
||||
|
||||
friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef int U;
|
||||
optional<U> rhs;
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef X T;
|
||||
typedef int U;
|
||||
optional<U> rhs(3);
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef Y T;
|
||||
typedef int U;
|
||||
optional<U> rhs;
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef Y T;
|
||||
typedef int U;
|
||||
optional<U> rhs(3);
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef Z T;
|
||||
typedef int U;
|
||||
optional<U> rhs;
|
||||
test<T>(rhs);
|
||||
}
|
||||
{
|
||||
typedef Z T;
|
||||
typedef int U;
|
||||
optional<U> rhs(3);
|
||||
test<T>(rhs, true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U>
|
||||
// explicit optional(optional<U>&& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
template <class T, class U>
|
||||
void
|
||||
test(optional<U>&& rhs, bool is_going_to_throw = false)
|
||||
{
|
||||
static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value), "");
|
||||
bool rhs_engaged = static_cast<bool>(rhs);
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
optional<T> lhs(std::move(rhs));
|
||||
assert(is_going_to_throw == false);
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
#else
|
||||
if (is_going_to_throw) return;
|
||||
optional<T> lhs(std::move(rhs));
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
#endif
|
||||
}
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
explicit X(int i) : i_(i) {}
|
||||
X(X&& x) : i_(std::exchange(x.i_, 0)) {}
|
||||
~X() {i_ = 0;}
|
||||
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
int count = 0;
|
||||
|
||||
class Z
|
||||
{
|
||||
public:
|
||||
explicit Z(int) { TEST_THROW(6); }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<int> rhs;
|
||||
test<X>(std::move(rhs));
|
||||
}
|
||||
{
|
||||
optional<int> rhs(3);
|
||||
test<X>(std::move(rhs));
|
||||
}
|
||||
{
|
||||
optional<int> rhs;
|
||||
test<Z>(std::move(rhs));
|
||||
}
|
||||
{
|
||||
optional<int> rhs(3);
|
||||
test<Z>(std::move(rhs), true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
|
||||
// <optional>
|
||||
|
||||
// template <class... Args>
|
||||
// constexpr explicit optional(in_place_t, Args&&... args);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
using std::in_place_t;
|
||||
using std::in_place;
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
X() : i_(0) {}
|
||||
X(int i) : i_(i) {}
|
||||
X(int i, int j) : i_(i), j_(j) {}
|
||||
|
||||
~X() {}
|
||||
|
||||
friend bool operator==(const X& x, const X& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
class Y
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
constexpr Y() : i_(0) {}
|
||||
constexpr Y(int i) : i_(i) {}
|
||||
constexpr Y(int i, int j) : i_(i), j_(j) {}
|
||||
|
||||
friend constexpr bool operator==(const Y& x, const Y& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
class Z
|
||||
{
|
||||
public:
|
||||
Z(int i) {TEST_THROW(6);}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
constexpr optional<int> opt(in_place, 5);
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == 5, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<int>
|
||||
{
|
||||
constexpr test_constexpr_ctor(in_place_t, int i)
|
||||
: optional<int>(in_place, i) {}
|
||||
};
|
||||
|
||||
}
|
||||
{
|
||||
const optional<X> opt(in_place);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == X());
|
||||
}
|
||||
{
|
||||
const optional<X> opt(in_place, 5);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == X(5));
|
||||
}
|
||||
{
|
||||
const optional<X> opt(in_place, 5, 4);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == X(5, 4));
|
||||
}
|
||||
{
|
||||
constexpr optional<Y> opt(in_place);
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == Y(), "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<Y>
|
||||
{
|
||||
constexpr test_constexpr_ctor(in_place_t)
|
||||
: optional<Y>(in_place) {}
|
||||
};
|
||||
|
||||
}
|
||||
{
|
||||
constexpr optional<Y> opt(in_place, 5);
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == Y(5), "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<Y>
|
||||
{
|
||||
constexpr test_constexpr_ctor(in_place_t, int i)
|
||||
: optional<Y>(in_place, i) {}
|
||||
};
|
||||
|
||||
}
|
||||
{
|
||||
constexpr optional<Y> opt(in_place, 5, 4);
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == Y(5, 4), "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<Y>
|
||||
{
|
||||
constexpr test_constexpr_ctor(in_place_t, int i, int j)
|
||||
: optional<Y>(in_place, i, j) {}
|
||||
};
|
||||
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
try
|
||||
{
|
||||
const optional<Z> opt(in_place, 1);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U, class... Args>
|
||||
// constexpr
|
||||
// explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
using std::in_place_t;
|
||||
using std::in_place;
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
X() : i_(0) {}
|
||||
X(int i) : i_(i) {}
|
||||
X(int i, int j) : i_(i), j_(j) {}
|
||||
|
||||
~X() {}
|
||||
|
||||
friend bool operator==(const X& x, const X& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
class Y
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
constexpr Y() : i_(0) {}
|
||||
constexpr Y(int i) : i_(i) {}
|
||||
constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
|
||||
|
||||
friend constexpr bool operator==(const Y& x, const Y& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
class Z
|
||||
{
|
||||
int i_;
|
||||
int j_ = 0;
|
||||
public:
|
||||
Z() : i_(0) {}
|
||||
Z(int i) : i_(i) {}
|
||||
Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
|
||||
{TEST_THROW(6);}
|
||||
|
||||
friend bool operator==(const Z& x, const Z& y)
|
||||
{return x.i_ == y.i_ && x.j_ == y.j_;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, "");
|
||||
static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, "");
|
||||
}
|
||||
{
|
||||
optional<std::vector<int>> opt(in_place, {3, 1});
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert((*opt == std::vector<int>{3, 1}));
|
||||
assert(opt->size() == 2);
|
||||
}
|
||||
{
|
||||
optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert((*opt == std::vector<int>{3, 1}));
|
||||
assert(opt->size() == 2);
|
||||
}
|
||||
{
|
||||
static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, "");
|
||||
constexpr optional<Y> opt(in_place, {3, 1});
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == Y{3, 1}, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<Y>
|
||||
{
|
||||
constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i)
|
||||
: optional<Y>(in_place, i) {}
|
||||
};
|
||||
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, "");
|
||||
try
|
||||
{
|
||||
optional<Z> opt(in_place, {3, 1});
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// optional(optional<T>&& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
template <class T, class ...InitArgs>
|
||||
void test(InitArgs&&... args)
|
||||
{
|
||||
const optional<T> orig(std::forward<InitArgs>(args)...);
|
||||
optional<T> rhs(orig);
|
||||
bool rhs_engaged = static_cast<bool>(rhs);
|
||||
optional<T> lhs = std::move(rhs);
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
if (rhs_engaged)
|
||||
assert(*lhs == *orig);
|
||||
}
|
||||
|
||||
void test_throwing_ctor() {
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
struct Z {
|
||||
Z() : count(0) {}
|
||||
Z(Z&& o) : count(o.count + 1)
|
||||
{ if (count == 2) throw 6; }
|
||||
int count;
|
||||
};
|
||||
Z z;
|
||||
optional<Z> rhs(std::move(z));
|
||||
try
|
||||
{
|
||||
optional<Z> lhs(std::move(rhs));
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class T, class ...InitArgs>
|
||||
void test_ref(InitArgs&&... args)
|
||||
{
|
||||
optional<T> rhs(std::forward<InitArgs>(args)...);
|
||||
bool rhs_engaged = static_cast<bool>(rhs);
|
||||
optional<T> lhs = std::move(rhs);
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
if (rhs_engaged)
|
||||
assert(&(*lhs) == &(*rhs));
|
||||
}
|
||||
|
||||
void test_reference_extension()
|
||||
{
|
||||
#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
{
|
||||
T t;
|
||||
T::reset_constructors();
|
||||
test_ref<T&>();
|
||||
test_ref<T&>(t);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
}
|
||||
assert(T::destroyed == 1);
|
||||
assert(T::alive == 0);
|
||||
{
|
||||
T t;
|
||||
const T& ct = t;
|
||||
T::reset_constructors();
|
||||
test_ref<T const&>();
|
||||
test_ref<T const&>(t);
|
||||
test_ref<T const&>(ct);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
assert(T::destroyed == 1);
|
||||
{
|
||||
T t;
|
||||
T::reset_constructors();
|
||||
test_ref<T&&>();
|
||||
test_ref<T&&>(std::move(t));
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
assert(T::destroyed == 1);
|
||||
{
|
||||
T t;
|
||||
const T& ct = t;
|
||||
T::reset_constructors();
|
||||
test_ref<T const&&>();
|
||||
test_ref<T const&&>(std::move(t));
|
||||
test_ref<T const&&>(std::move(ct));
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
assert(T::destroyed == 1);
|
||||
{
|
||||
static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
|
||||
static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test<int>();
|
||||
test<int>(3);
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
optional<T> rhs;
|
||||
assert(T::alive == 0);
|
||||
const optional<T> lhs(std::move(rhs));
|
||||
assert(lhs.has_value() == false);
|
||||
assert(rhs.has_value() == false);
|
||||
assert(T::alive == 0);
|
||||
}
|
||||
TestTypes::TestType::reset();
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
optional<T> rhs(42);
|
||||
assert(T::alive == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::move_constructed == 0);
|
||||
const optional<T> lhs(std::move(rhs));
|
||||
assert(lhs.has_value());
|
||||
assert(rhs.has_value());
|
||||
assert(lhs.value().value == 42);
|
||||
assert(rhs.value().value == -1);
|
||||
assert(T::move_constructed == 1);
|
||||
assert(T::alive == 2);
|
||||
}
|
||||
TestTypes::TestType::reset();
|
||||
{
|
||||
using namespace ConstexprTestTypes;
|
||||
test<TestType>();
|
||||
test<TestType>(42);
|
||||
}
|
||||
{
|
||||
using namespace TrivialTestTypes;
|
||||
test<TestType>();
|
||||
test<TestType>(42);
|
||||
}
|
||||
{
|
||||
test_throwing_ctor();
|
||||
}
|
||||
{
|
||||
struct ThrowsMove {
|
||||
ThrowsMove() noexcept(false) {}
|
||||
ThrowsMove(ThrowsMove const&) noexcept(false) {}
|
||||
ThrowsMove(ThrowsMove &&) noexcept(false) {}
|
||||
};
|
||||
static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, "");
|
||||
struct NoThrowMove {
|
||||
NoThrowMove() noexcept(false) {}
|
||||
NoThrowMove(NoThrowMove const&) noexcept(false) {}
|
||||
NoThrowMove(NoThrowMove &&) noexcept(true) {}
|
||||
};
|
||||
static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
|
||||
}
|
||||
{
|
||||
test_reference_extension();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr optional(nullopt_t) noexcept;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
template <class Opt>
|
||||
void
|
||||
test_constexpr()
|
||||
{
|
||||
static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
|
||||
static_assert(std::is_trivially_destructible<Opt>::value, "");
|
||||
static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
|
||||
|
||||
constexpr Opt opt(nullopt);
|
||||
static_assert(static_cast<bool>(opt) == false, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public Opt
|
||||
{
|
||||
constexpr test_constexpr_ctor() {}
|
||||
};
|
||||
}
|
||||
|
||||
template <class Opt>
|
||||
void
|
||||
test()
|
||||
{
|
||||
static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
|
||||
static_assert(!std::is_trivially_destructible<Opt>::value, "");
|
||||
static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
|
||||
{
|
||||
Opt opt(nullopt);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
{
|
||||
const Opt opt(nullopt);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
struct test_constexpr_ctor
|
||||
: public Opt
|
||||
{
|
||||
constexpr test_constexpr_ctor() {}
|
||||
};
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_constexpr<optional<int>>();
|
||||
test_constexpr<optional<int*>>();
|
||||
test_constexpr<optional<ImplicitTypes::NoCtors>>();
|
||||
test_constexpr<optional<NonTrivialTypes::NoCtors>>();
|
||||
test_constexpr<optional<NonConstexprTypes::NoCtors>>();
|
||||
test<optional<NonLiteralTypes::NoCtors>>();
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U>
|
||||
// optional(optional<U>&& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
template <class T, class U>
|
||||
void
|
||||
test(optional<U>&& rhs, bool is_going_to_throw = false)
|
||||
{
|
||||
bool rhs_engaged = static_cast<bool>(rhs);
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
optional<T> lhs = std::move(rhs);
|
||||
assert(is_going_to_throw == false);
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
#else
|
||||
if (is_going_to_throw) return;
|
||||
optional<T> lhs = std::move(rhs);
|
||||
assert(static_cast<bool>(lhs) == rhs_engaged);
|
||||
#endif
|
||||
}
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
X(int i) : i_(i) {}
|
||||
X(X&& x) : i_(std::exchange(x.i_, 0)) {}
|
||||
~X() {i_ = 0;}
|
||||
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
int count = 0;
|
||||
|
||||
struct Z
|
||||
{
|
||||
Z(int) { TEST_THROW(6); }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<short> rhs;
|
||||
test<int>(std::move(rhs));
|
||||
}
|
||||
{
|
||||
optional<short> rhs(short{3});
|
||||
test<int>(std::move(rhs));
|
||||
}
|
||||
{
|
||||
optional<int> rhs;
|
||||
test<X>(std::move(rhs));
|
||||
}
|
||||
{
|
||||
optional<int> rhs(3);
|
||||
test<X>(std::move(rhs));
|
||||
}
|
||||
{
|
||||
optional<int> rhs;
|
||||
test<Z>(std::move(rhs));
|
||||
}
|
||||
{
|
||||
optional<int> rhs(3);
|
||||
test<Z>(std::move(rhs), true);
|
||||
}
|
||||
|
||||
static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
|
||||
// <optional>
|
||||
|
||||
// constexpr optional(T&& v);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
|
||||
using std::optional;
|
||||
|
||||
|
||||
class Z
|
||||
{
|
||||
public:
|
||||
Z(int) {}
|
||||
Z(Z&&) {TEST_THROW(6);}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef int T;
|
||||
constexpr optional<T> opt(T(5));
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == 5, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(T&&) {}
|
||||
};
|
||||
}
|
||||
{
|
||||
typedef double T;
|
||||
constexpr optional<T> opt(T(3));
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(*opt == 3, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(T&&) {}
|
||||
};
|
||||
}
|
||||
{
|
||||
typedef TestTypes::TestType T;
|
||||
T::reset();
|
||||
optional<T> opt = T{3};
|
||||
assert(T::alive == 1);
|
||||
assert(T::move_constructed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(opt.value().value == 3);
|
||||
}
|
||||
{
|
||||
typedef ExplicitTestTypes::TestType T;
|
||||
static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
|
||||
T::reset();
|
||||
optional<T> opt(T{3});
|
||||
assert(T::alive == 1);
|
||||
assert(T::move_constructed == 1);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(opt.value().value == 3);
|
||||
}
|
||||
{
|
||||
typedef TestTypes::TestType T;
|
||||
T::reset();
|
||||
optional<T> opt = {3};
|
||||
assert(T::alive == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::copy_constructed == 0);
|
||||
assert(T::move_constructed == 0);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(opt.value().value == 3);
|
||||
}
|
||||
{
|
||||
typedef ConstexprTestTypes::TestType T;
|
||||
constexpr optional<T> opt = {T(3)};
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(opt.value().value == 3, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(const T&) {}
|
||||
};
|
||||
}
|
||||
{
|
||||
typedef ConstexprTestTypes::TestType T;
|
||||
constexpr optional<T> opt = {3};
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(opt.value().value == 3, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(const T&) {}
|
||||
};
|
||||
}
|
||||
{
|
||||
typedef ExplicitConstexprTestTypes::TestType T;
|
||||
static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
|
||||
constexpr optional<T> opt(T{3});
|
||||
static_assert(static_cast<bool>(opt) == true, "");
|
||||
static_assert(opt.value().value == 3, "");
|
||||
|
||||
struct test_constexpr_ctor
|
||||
: public optional<T>
|
||||
{
|
||||
constexpr test_constexpr_ctor(T&&) {}
|
||||
};
|
||||
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
struct Z {
|
||||
Z(int) {}
|
||||
Z(Z&&) {throw 6;}
|
||||
};
|
||||
typedef Z T;
|
||||
try
|
||||
{
|
||||
T t(3);
|
||||
optional<T> opt(std::move(t));
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// ~optional();
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct PODType {
|
||||
int value;
|
||||
int value2;
|
||||
};
|
||||
|
||||
class X
|
||||
{
|
||||
public:
|
||||
static bool dtor_called;
|
||||
X() = default;
|
||||
~X() {dtor_called = true;}
|
||||
};
|
||||
|
||||
bool X::dtor_called = false;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef int T;
|
||||
static_assert(std::is_trivially_destructible<T>::value, "");
|
||||
static_assert(std::is_trivially_destructible<optional<T>>::value, "");
|
||||
static_assert(std::is_literal_type<optional<T>>::value, "");
|
||||
}
|
||||
{
|
||||
typedef double T;
|
||||
static_assert(std::is_trivially_destructible<T>::value, "");
|
||||
static_assert(std::is_trivially_destructible<optional<T>>::value, "");
|
||||
static_assert(std::is_literal_type<optional<T>>::value, "");
|
||||
}
|
||||
{
|
||||
typedef PODType T;
|
||||
static_assert(std::is_trivially_destructible<T>::value, "");
|
||||
static_assert(std::is_trivially_destructible<optional<T>>::value, "");
|
||||
static_assert(std::is_literal_type<optional<T>>::value, "");
|
||||
}
|
||||
{
|
||||
typedef X T;
|
||||
static_assert(!std::is_trivially_destructible<T>::value, "");
|
||||
static_assert(!std::is_trivially_destructible<optional<T>>::value, "");
|
||||
static_assert(!std::is_literal_type<optional<T>>::value, "");
|
||||
{
|
||||
X x;
|
||||
optional<X> opt{x};
|
||||
assert(X::dtor_called == false);
|
||||
}
|
||||
assert(X::dtor_called == true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
|
||||
// <optional>
|
||||
|
||||
// void reset() noexcept;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
static bool dtor_called;
|
||||
~X() {dtor_called = true;}
|
||||
};
|
||||
|
||||
bool X::dtor_called = false;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<int> opt;
|
||||
static_assert(noexcept(opt.reset()) == true, "");
|
||||
opt.reset();
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
opt.reset();
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
{
|
||||
optional<X> opt;
|
||||
static_assert(noexcept(opt.reset()) == true, "");
|
||||
assert(X::dtor_called == false);
|
||||
opt.reset();
|
||||
assert(X::dtor_called == false);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997
|
||||
{
|
||||
optional<X> opt(X{});
|
||||
X::dtor_called = false;
|
||||
opt.reset();
|
||||
assert(X::dtor_called == true);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
X::dtor_called = false;
|
||||
}
|
||||
assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr explicit optional<T>::operator bool() const noexcept;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
{
|
||||
const optional<int> opt; ((void)opt);
|
||||
ASSERT_NOEXCEPT(bool(opt));
|
||||
static_assert(!std::is_convertible<optional<int>, bool>::value, "");
|
||||
}
|
||||
{
|
||||
constexpr optional<int> opt;
|
||||
static_assert(!opt, "");
|
||||
}
|
||||
{
|
||||
constexpr optional<int> opt(0);
|
||||
static_assert(opt, "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr T& optional<T>::operator*() &;
|
||||
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
|
||||
#endif
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int test() const& {return 3;}
|
||||
int test() & {return 4;}
|
||||
constexpr int test() const&& {return 5;}
|
||||
int test() && {return 6;}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
constexpr int test() {return 7;}
|
||||
};
|
||||
|
||||
constexpr int
|
||||
test()
|
||||
{
|
||||
optional<Y> opt{Y{}};
|
||||
return (*opt).test();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<X> opt; ((void)opt);
|
||||
ASSERT_SAME_TYPE(decltype(*opt), X&);
|
||||
// ASSERT_NOT_NOEXCEPT(*opt);
|
||||
// FIXME: This assertion fails with GCC because it can see that
|
||||
// (A) operator*() is constexpr, and
|
||||
// (B) there is no path through the function that throws.
|
||||
// It's arguable if this is the correct behavior for the noexcept
|
||||
// operator.
|
||||
// Regardless this function should still be noexcept(false) because
|
||||
// it has a narrow contract.
|
||||
}
|
||||
{
|
||||
optional<X> opt(X{});
|
||||
assert((*opt).test() == 4);
|
||||
}
|
||||
static_assert(test() == 7, "");
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
{
|
||||
optional<X> opt;
|
||||
assert((*opt).test() == 3);
|
||||
assert(false);
|
||||
}
|
||||
#endif // _LIBCPP_DEBUG
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr const T& optional<T>::operator*() const &;
|
||||
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
|
||||
#endif
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int test() const& {return 3;}
|
||||
int test() & {return 4;}
|
||||
constexpr int test() const&& {return 5;}
|
||||
int test() && {return 6;}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int test() const {return 2;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
const optional<X> opt; ((void)opt);
|
||||
ASSERT_SAME_TYPE(decltype(*opt), X const&);
|
||||
// ASSERT_NOT_NOEXCEPT(*opt);
|
||||
// FIXME: This assertion fails with GCC because it can see that
|
||||
// (A) operator*() is constexpr, and
|
||||
// (B) there is no path through the function that throws.
|
||||
// It's arguable if this is the correct behavior for the noexcept
|
||||
// operator.
|
||||
// Regardless this function should still be noexcept(false) because
|
||||
// it has a narrow contract.
|
||||
}
|
||||
{
|
||||
constexpr optional<X> opt(X{});
|
||||
static_assert((*opt).test() == 3, "");
|
||||
}
|
||||
{
|
||||
constexpr optional<Y> opt(Y{});
|
||||
assert((*opt).test() == 2);
|
||||
}
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
{
|
||||
const optional<X> opt;
|
||||
assert((*opt).test() == 3);
|
||||
assert(false);
|
||||
}
|
||||
#endif // _LIBCPP_DEBUG
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr T&& optional<T>::operator*() const &&;
|
||||
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
|
||||
#endif
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int test() const& {return 3;}
|
||||
int test() & {return 4;}
|
||||
constexpr int test() const&& {return 5;}
|
||||
int test() && {return 6;}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int test() const && {return 2;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
const optional<X> opt; ((void)opt);
|
||||
ASSERT_SAME_TYPE(decltype(*std::move(opt)), X const &&);
|
||||
// ASSERT_NOT_NOEXCEPT(*std::move(opt));
|
||||
// FIXME: This assertion fails with GCC because it can see that
|
||||
// (A) operator*() is constexpr, and
|
||||
// (B) there is no path through the function that throws.
|
||||
// It's arguable if this is the correct behavior for the noexcept
|
||||
// operator.
|
||||
// Regardless this function should still be noexcept(false) because
|
||||
// it has a narrow contract.
|
||||
}
|
||||
{
|
||||
constexpr optional<X> opt(X{});
|
||||
static_assert((*std::move(opt)).test() == 5, "");
|
||||
}
|
||||
{
|
||||
constexpr optional<Y> opt(Y{});
|
||||
assert((*std::move(opt)).test() == 2);
|
||||
}
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
{
|
||||
optional<X> opt;
|
||||
assert((*std::move(opt)).test() == 5);
|
||||
assert(false);
|
||||
}
|
||||
#endif // _LIBCPP_DEBUG
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr T&& optional<T>::operator*() &&;
|
||||
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
|
||||
#endif
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int test() const& {return 3;}
|
||||
int test() & {return 4;}
|
||||
constexpr int test() const&& {return 5;}
|
||||
int test() && {return 6;}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
constexpr int test() && {return 7;}
|
||||
};
|
||||
|
||||
constexpr int
|
||||
test()
|
||||
{
|
||||
optional<Y> opt{Y{}};
|
||||
return (*std::move(opt)).test();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<X> opt; ((void)opt);
|
||||
ASSERT_SAME_TYPE(decltype(*std::move(opt)), X&&);
|
||||
// ASSERT_NOT_NOEXCEPT(*std::move(opt));
|
||||
// FIXME: This assertion fails with GCC because it can see that
|
||||
// (A) operator*() is constexpr, and
|
||||
// (B) there is no path through the function that throws.
|
||||
// It's arguable if this is the correct behavior for the noexcept
|
||||
// operator.
|
||||
// Regardless this function should still be noexcept(false) because
|
||||
// it has a narrow contract.
|
||||
}
|
||||
{
|
||||
optional<X> opt(X{});
|
||||
assert((*std::move(opt)).test() == 6);
|
||||
}
|
||||
static_assert(test() == 7, "");
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
{
|
||||
optional<X> opt;
|
||||
assert((*std::move(opt)).test() == 3);
|
||||
assert(false);
|
||||
}
|
||||
#endif // _LIBCPP_DEBUG
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr bool optional<T>::has_value() const noexcept;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
{
|
||||
const optional<int> opt; ((void)opt);
|
||||
ASSERT_NOEXCEPT(opt.has_value());
|
||||
ASSERT_SAME_TYPE(decltype(opt.has_value()), bool);
|
||||
}
|
||||
{
|
||||
constexpr optional<int> opt;
|
||||
static_assert(!opt.has_value(), "");
|
||||
}
|
||||
{
|
||||
constexpr optional<int> opt(0);
|
||||
static_assert(opt.has_value(), "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr T* optional<T>::operator->();
|
||||
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
|
||||
#endif
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int test() noexcept {return 3;}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
constexpr int test() {return 3;}
|
||||
};
|
||||
|
||||
constexpr int
|
||||
test()
|
||||
{
|
||||
optional<Y> opt{Y{}};
|
||||
return opt->test();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::optional<X> opt; ((void)opt);
|
||||
ASSERT_SAME_TYPE(decltype(opt.operator->()), X*);
|
||||
// ASSERT_NOT_NOEXCEPT(opt.operator->());
|
||||
// FIXME: This assertion fails with GCC because it can see that
|
||||
// (A) operator->() is constexpr, and
|
||||
// (B) there is no path through the function that throws.
|
||||
// It's arguable if this is the correct behavior for the noexcept
|
||||
// operator.
|
||||
// Regardless this function should still be noexcept(false) because
|
||||
// it has a narrow contract.
|
||||
}
|
||||
{
|
||||
optional<X> opt(X{});
|
||||
assert(opt->test() == 3);
|
||||
}
|
||||
{
|
||||
static_assert(test() == 3, "");
|
||||
}
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
{
|
||||
optional<X> opt;
|
||||
assert(opt->test() == 3);
|
||||
assert(false);
|
||||
}
|
||||
#endif // _LIBCPP_DEBUG
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr const T* optional<T>::operator->() const;
|
||||
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
|
||||
#endif
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int test() const {return 3;}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int test() const noexcept {return 2;}
|
||||
};
|
||||
|
||||
struct Z
|
||||
{
|
||||
const Z* operator&() const;
|
||||
constexpr int test() const {return 1;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
const std::optional<X> opt; ((void)opt);
|
||||
ASSERT_SAME_TYPE(decltype(opt.operator->()), X const*);
|
||||
// ASSERT_NOT_NOEXCEPT(opt.operator->());
|
||||
// FIXME: This assertion fails with GCC because it can see that
|
||||
// (A) operator->() is constexpr, and
|
||||
// (B) there is no path through the function that throws.
|
||||
// It's arguable if this is the correct behavior for the noexcept
|
||||
// operator.
|
||||
// Regardless this function should still be noexcept(false) because
|
||||
// it has a narrow contract.
|
||||
}
|
||||
{
|
||||
constexpr optional<X> opt(X{});
|
||||
static_assert(opt->test() == 3, "");
|
||||
}
|
||||
{
|
||||
constexpr optional<Y> opt(Y{});
|
||||
assert(opt->test() == 2);
|
||||
}
|
||||
{
|
||||
constexpr optional<Z> opt(Z{});
|
||||
static_assert(opt->test() == 1, "");
|
||||
}
|
||||
#ifdef _LIBCPP_DEBUG
|
||||
{
|
||||
const optional<X> opt;
|
||||
assert(opt->test() == 3);
|
||||
assert(false);
|
||||
}
|
||||
#endif // _LIBCPP_DEBUG
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr T& optional<T>::value() &;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
using std::bad_optional_access;
|
||||
|
||||
struct X
|
||||
{
|
||||
X() = default;
|
||||
X(const X&) = delete;
|
||||
constexpr int test() const & {return 3;}
|
||||
int test() & {return 4;}
|
||||
constexpr int test() const && {return 5;}
|
||||
int test() && {return 6;}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
constexpr int test() & {return 7;}
|
||||
};
|
||||
|
||||
constexpr int
|
||||
test()
|
||||
{
|
||||
optional<Y> opt{Y{}};
|
||||
return opt.value().test();
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<X> opt; ((void)opt);
|
||||
ASSERT_NOT_NOEXCEPT(opt.value());
|
||||
ASSERT_SAME_TYPE(decltype(opt.value()), X&);
|
||||
}
|
||||
{
|
||||
optional<X> opt;
|
||||
opt.emplace();
|
||||
assert(opt.value().test() == 4);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
optional<X> opt;
|
||||
try
|
||||
{
|
||||
opt.value();
|
||||
assert(false);
|
||||
}
|
||||
catch (const bad_optional_access&)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static_assert(test() == 7, "");
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr const T& optional<T>::value() const &;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int test() const {return 3;}
|
||||
int test() {return 4;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
constexpr optional<X> opt;
|
||||
static_assert(opt.value().test() == 3, "");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr const T& optional<T>::value() const &;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
using std::in_place_t;
|
||||
using std::in_place;
|
||||
using std::bad_optional_access;
|
||||
|
||||
struct X
|
||||
{
|
||||
X() = default;
|
||||
X(const X&) = delete;
|
||||
constexpr int test() const & {return 3;}
|
||||
int test() & {return 4;}
|
||||
constexpr int test() const && {return 5;}
|
||||
int test() && {return 6;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
const optional<X> opt; ((void)opt);
|
||||
ASSERT_NOT_NOEXCEPT(opt.value());
|
||||
ASSERT_SAME_TYPE(decltype(opt.value()), X const&);
|
||||
}
|
||||
{
|
||||
constexpr optional<X> opt(in_place);
|
||||
static_assert(opt.value().test() == 3, "");
|
||||
}
|
||||
{
|
||||
const optional<X> opt(in_place);
|
||||
assert(opt.value().test() == 3);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
const optional<X> opt;
|
||||
try
|
||||
{
|
||||
opt.value();
|
||||
assert(false);
|
||||
}
|
||||
catch (const bad_optional_access&)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr const T& optional<T>::value() const &&;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
using std::in_place_t;
|
||||
using std::in_place;
|
||||
using std::bad_optional_access;
|
||||
|
||||
struct X
|
||||
{
|
||||
X() = default;
|
||||
X(const X&) = delete;
|
||||
constexpr int test() const & {return 3;}
|
||||
int test() & {return 4;}
|
||||
constexpr int test() const && {return 5;}
|
||||
int test() && {return 6;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
const optional<X> opt; ((void)opt);
|
||||
ASSERT_NOT_NOEXCEPT(std::move(opt).value());
|
||||
ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X const&&);
|
||||
}
|
||||
{
|
||||
constexpr optional<X> opt(in_place);
|
||||
static_assert(std::move(opt).value().test() == 5, "");
|
||||
}
|
||||
{
|
||||
const optional<X> opt(in_place);
|
||||
assert(std::move(opt).value().test() == 5);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
const optional<X> opt;
|
||||
try
|
||||
{
|
||||
std::move(opt).value();
|
||||
assert(false);
|
||||
}
|
||||
catch (const bad_optional_access&)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U> T optional<T>::value_or(U&& v) &&;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
using std::in_place_t;
|
||||
using std::in_place;
|
||||
|
||||
struct Y
|
||||
{
|
||||
int i_;
|
||||
|
||||
Y(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
X(int i) : i_(i) {}
|
||||
X(X&& x) : i_(x.i_) {x.i_ = 0;}
|
||||
X(const Y& y) : i_(y.i_) {}
|
||||
X(Y&& y) : i_(y.i_+1) {}
|
||||
friend constexpr bool operator==(const X& x, const X& y)
|
||||
{return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<X> opt(in_place, 2);
|
||||
Y y(3);
|
||||
assert(std::move(opt).value_or(y) == 2);
|
||||
assert(*opt == 0);
|
||||
}
|
||||
{
|
||||
optional<X> opt(in_place, 2);
|
||||
assert(std::move(opt).value_or(Y(3)) == 2);
|
||||
assert(*opt == 0);
|
||||
}
|
||||
{
|
||||
optional<X> opt;
|
||||
Y y(3);
|
||||
assert(std::move(opt).value_or(y) == 3);
|
||||
assert(!opt);
|
||||
}
|
||||
{
|
||||
optional<X> opt;
|
||||
assert(std::move(opt).value_or(Y(3)) == 4);
|
||||
assert(!opt);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class U> constexpr T optional<T>::value_or(U&& v) const&;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct Y
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr Y(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
constexpr X(const Y& y) : i_(y.i_) {}
|
||||
constexpr X(Y&& y) : i_(y.i_+1) {}
|
||||
friend constexpr bool operator==(const X& x, const X& y)
|
||||
{return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
constexpr optional<X> opt(2);
|
||||
constexpr Y y(3);
|
||||
static_assert(opt.value_or(y) == 2, "");
|
||||
}
|
||||
{
|
||||
constexpr optional<X> opt(2);
|
||||
static_assert(opt.value_or(Y(3)) == 2, "");
|
||||
}
|
||||
{
|
||||
constexpr optional<X> opt;
|
||||
constexpr Y y(3);
|
||||
static_assert(opt.value_or(y) == 3, "");
|
||||
}
|
||||
{
|
||||
constexpr optional<X> opt;
|
||||
static_assert(opt.value_or(Y(3)) == 4, "");
|
||||
}
|
||||
{
|
||||
const optional<X> opt(2);
|
||||
const Y y(3);
|
||||
assert(opt.value_or(y) == 2);
|
||||
}
|
||||
{
|
||||
const optional<X> opt(2);
|
||||
assert(opt.value_or(Y(3)) == 2);
|
||||
}
|
||||
{
|
||||
const optional<X> opt;
|
||||
const Y y(3);
|
||||
assert(opt.value_or(y) == 3);
|
||||
}
|
||||
{
|
||||
const optional<X> opt;
|
||||
assert(opt.value_or(Y(3)) == 4);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// constexpr T& optional<T>::value() &&;
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using std::optional;
|
||||
using std::bad_optional_access;
|
||||
|
||||
struct X
|
||||
{
|
||||
X() = default;
|
||||
X(const X&) = delete;
|
||||
constexpr int test() const & {return 3;}
|
||||
int test() & {return 4;}
|
||||
constexpr int test() const && {return 5;}
|
||||
int test() && {return 6;}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
constexpr int test() && {return 7;}
|
||||
};
|
||||
|
||||
constexpr int
|
||||
test()
|
||||
{
|
||||
optional<Y> opt{Y{}};
|
||||
return std::move(opt).value().test();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<X> opt; ((void)opt);
|
||||
ASSERT_NOT_NOEXCEPT(std::move(opt).value());
|
||||
ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X&&);
|
||||
}
|
||||
{
|
||||
optional<X> opt;
|
||||
opt.emplace();
|
||||
assert(std::move(opt).value().test() == 6);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
optional<X> opt;
|
||||
try
|
||||
{
|
||||
std::move(opt).value();
|
||||
assert(false);
|
||||
}
|
||||
catch (const bad_optional_access&)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static_assert(test() == 7, "");
|
||||
}
|
|
@ -0,0 +1,306 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// void swap(optional&)
|
||||
// noexcept(is_nothrow_move_constructible<T>::value &&
|
||||
// is_nothrow_swappable<T>::value)
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
static unsigned dtor_called;
|
||||
X(int i) : i_(i) {}
|
||||
X(X&& x) = default;
|
||||
X& operator=(X&&) = default;
|
||||
~X() {++dtor_called;}
|
||||
|
||||
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
unsigned X::dtor_called = 0;
|
||||
|
||||
class Y
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
static unsigned dtor_called;
|
||||
Y(int i) : i_(i) {}
|
||||
Y(Y&&) = default;
|
||||
~Y() {++dtor_called;}
|
||||
|
||||
friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
|
||||
friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
|
||||
};
|
||||
|
||||
unsigned Y::dtor_called = 0;
|
||||
|
||||
class Z
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
Z(int i) : i_(i) {}
|
||||
Z(Z&&) {TEST_THROW(7);}
|
||||
|
||||
friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
|
||||
friend void swap(Z& x, Z& y) {TEST_THROW(6);}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
optional<int> opt1;
|
||||
optional<int> opt2;
|
||||
static_assert(noexcept(opt1.swap(opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
opt1.swap(opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<int> opt1(1);
|
||||
optional<int> opt2;
|
||||
static_assert(noexcept(opt1.swap(opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
opt1.swap(opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<int> opt1;
|
||||
optional<int> opt2(2);
|
||||
static_assert(noexcept(opt1.swap(opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
opt1.swap(opt2);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<int> opt1(1);
|
||||
optional<int> opt2(2);
|
||||
static_assert(noexcept(opt1.swap(opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
opt1.swap(opt2);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<X> opt1;
|
||||
optional<X> opt2;
|
||||
static_assert(noexcept(opt1.swap(opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
opt1.swap(opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(X::dtor_called == 0);
|
||||
}
|
||||
{
|
||||
optional<X> opt1(1);
|
||||
optional<X> opt2;
|
||||
static_assert(noexcept(opt1.swap(opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
X::dtor_called = 0;
|
||||
opt1.swap(opt2);
|
||||
assert(X::dtor_called == 1);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<X> opt1;
|
||||
optional<X> opt2(2);
|
||||
static_assert(noexcept(opt1.swap(opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
X::dtor_called = 0;
|
||||
opt1.swap(opt2);
|
||||
assert(X::dtor_called == 1);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<X> opt1(1);
|
||||
optional<X> opt2(2);
|
||||
static_assert(noexcept(opt1.swap(opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
X::dtor_called = 0;
|
||||
opt1.swap(opt2);
|
||||
assert(X::dtor_called == 1); // from inside std::swap
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<Y> opt1;
|
||||
optional<Y> opt2;
|
||||
static_assert(noexcept(opt1.swap(opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
opt1.swap(opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(Y::dtor_called == 0);
|
||||
}
|
||||
{
|
||||
optional<Y> opt1(1);
|
||||
optional<Y> opt2;
|
||||
static_assert(noexcept(opt1.swap(opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
Y::dtor_called = 0;
|
||||
opt1.swap(opt2);
|
||||
assert(Y::dtor_called == 1);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<Y> opt1;
|
||||
optional<Y> opt2(2);
|
||||
static_assert(noexcept(opt1.swap(opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
Y::dtor_called = 0;
|
||||
opt1.swap(opt2);
|
||||
assert(Y::dtor_called == 1);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<Y> opt1(1);
|
||||
optional<Y> opt2(2);
|
||||
static_assert(noexcept(opt1.swap(opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
Y::dtor_called = 0;
|
||||
opt1.swap(opt2);
|
||||
assert(Y::dtor_called == 0);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<Z> opt1;
|
||||
optional<Z> opt2;
|
||||
static_assert(noexcept(opt1.swap(opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
opt1.swap(opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
optional<Z> opt1;
|
||||
opt1.emplace(1);
|
||||
optional<Z> opt2;
|
||||
static_assert(noexcept(opt1.swap(opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
try
|
||||
{
|
||||
opt1.swap(opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 7);
|
||||
}
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<Z> opt1;
|
||||
optional<Z> opt2;
|
||||
opt2.emplace(2);
|
||||
static_assert(noexcept(opt1.swap(opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
try
|
||||
{
|
||||
opt1.swap(opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 7);
|
||||
}
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
}
|
||||
{
|
||||
optional<Z> opt1;
|
||||
opt1.emplace(1);
|
||||
optional<Z> opt2;
|
||||
opt2.emplace(2);
|
||||
static_assert(noexcept(opt1.swap(opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
try
|
||||
{
|
||||
opt1.swap(opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// T shall be an object type and shall satisfy the requirements of Destructible
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
private:
|
||||
~X() {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
{
|
||||
// expected-error@optional:* 2 {{static_assert failed "instantiation of optional with a reference type is ill-formed}}
|
||||
optional<int&> opt1;
|
||||
optional<int&&> opt2;
|
||||
}
|
||||
{
|
||||
// expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed"}}
|
||||
optional<X> opt3;
|
||||
}
|
||||
{
|
||||
// expected-error@optional:* {{static_assert failed "instantiation of optional with a non-object type is undefined behavior"}}
|
||||
// expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed}}
|
||||
optional<void()> opt4;
|
||||
}
|
||||
{
|
||||
// expected-error@optional:* {{static_assert failed "instantiation of optional with a non-object type is undefined behavior"}}
|
||||
// expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed}}
|
||||
// expected-error@optional:* 1+ {{cannot form a reference to 'void'}}
|
||||
optional<const void> opt4;
|
||||
}
|
||||
// FIXME these are garbage diagnostics that Clang should not produce
|
||||
// expected-error@optional:* 0+ {{is not a base class}}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "archetypes.hpp"
|
||||
|
||||
template <class T>
|
||||
struct SpecialMemberTest {
|
||||
using O = std::optional<T>;
|
||||
|
||||
static_assert(std::is_default_constructible_v<O>,
|
||||
"optional is always default constructible.");
|
||||
static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>,
|
||||
"optional<T> is copy constructible if and only if T is copy constructible.");
|
||||
static_assert(std::is_move_constructible_v<O> ==
|
||||
(std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>),
|
||||
"optional<T> is move constructible if and only if T is copy or move constructible.");
|
||||
static_assert(std::is_copy_assignable_v<O> ==
|
||||
(std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>),
|
||||
"optional<T> is copy assignable if and only if T is both copy "
|
||||
"constructible and copy assignable.");
|
||||
static_assert(std::is_move_assignable_v<O> ==
|
||||
((std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>) ||
|
||||
(std::is_move_constructible_v<T> && std::is_move_assignable_v<T>)),
|
||||
"optional<T> is move assignable if and only if T is both move assignable and "
|
||||
"move constructible, or both copy constructible and copy assignable.");
|
||||
};
|
||||
|
||||
template <class ...Args> static void sink(Args&&...) {}
|
||||
|
||||
template <class ...TestTypes>
|
||||
struct DoTestsMetafunction {
|
||||
DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
|
||||
};
|
||||
|
||||
struct TrivialMoveNonTrivialCopy {
|
||||
TrivialMoveNonTrivialCopy() = default;
|
||||
TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
|
||||
TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
|
||||
TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
|
||||
TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
|
||||
};
|
||||
|
||||
struct TrivialCopyNonTrivialMove {
|
||||
TrivialCopyNonTrivialMove() = default;
|
||||
TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
|
||||
TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
|
||||
TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
|
||||
TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
sink(
|
||||
ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
|
||||
ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
|
||||
NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
|
||||
NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
|
||||
DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
|
||||
);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T>
|
||||
// class optional
|
||||
// {
|
||||
// public:
|
||||
// typedef T value_type;
|
||||
// ...
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
using std::optional;
|
||||
|
||||
template <class Opt, class T>
|
||||
void
|
||||
test()
|
||||
{
|
||||
static_assert(std::is_same<typename Opt::value_type, T>::value, "");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test<optional<int>, int>();
|
||||
test<optional<const int>, const int>();
|
||||
test<optional<double>, double>();
|
||||
test<optional<const double>, const double>();
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator == ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ == rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2; // disengaged
|
||||
constexpr O o3{1}; // engaged
|
||||
constexpr O o4{2}; // engaged
|
||||
constexpr O o5{1}; // engaged
|
||||
|
||||
static_assert ( o1 == o1 , "" );
|
||||
static_assert ( o1 == o2 , "" );
|
||||
static_assert ( !(o1 == o3), "" );
|
||||
static_assert ( !(o1 == o4), "" );
|
||||
static_assert ( !(o1 == o5), "" );
|
||||
|
||||
static_assert ( o2 == o1 , "" );
|
||||
static_assert ( o2 == o2 , "" );
|
||||
static_assert ( !(o2 == o3), "" );
|
||||
static_assert ( !(o2 == o4), "" );
|
||||
static_assert ( !(o2 == o5), "" );
|
||||
|
||||
static_assert ( !(o3 == o1), "" );
|
||||
static_assert ( !(o3 == o2), "" );
|
||||
static_assert ( o3 == o3 , "" );
|
||||
static_assert ( !(o3 == o4), "" );
|
||||
static_assert ( o3 == o5 , "" );
|
||||
|
||||
static_assert ( !(o4 == o1), "" );
|
||||
static_assert ( !(o4 == o2), "" );
|
||||
static_assert ( !(o4 == o3), "" );
|
||||
static_assert ( o4 == o4 , "" );
|
||||
static_assert ( !(o4 == o5), "" );
|
||||
|
||||
static_assert ( !(o5 == o1), "" );
|
||||
static_assert ( !(o5 == o2), "" );
|
||||
static_assert ( o5 == o3 , "" );
|
||||
static_assert ( !(o5 == o4), "" );
|
||||
static_assert ( o5 == o5 , "" );
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator>= (const optional<T>& x, const optional<T>& y);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator >= ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ >= rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef optional<X> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2; // disengaged
|
||||
constexpr O o3{1}; // engaged
|
||||
constexpr O o4{2}; // engaged
|
||||
constexpr O o5{1}; // engaged
|
||||
|
||||
static_assert ( (o1 >= o1), "" );
|
||||
static_assert ( (o1 >= o2), "" );
|
||||
static_assert ( !(o1 >= o3), "" );
|
||||
static_assert ( !(o1 >= o4), "" );
|
||||
static_assert ( !(o1 >= o5), "" );
|
||||
|
||||
static_assert ( (o2 >= o1), "" );
|
||||
static_assert ( (o2 >= o2), "" );
|
||||
static_assert ( !(o2 >= o3), "" );
|
||||
static_assert ( !(o2 >= o4), "" );
|
||||
static_assert ( !(o2 >= o5), "" );
|
||||
|
||||
static_assert ( (o3 >= o1), "" );
|
||||
static_assert ( (o3 >= o2), "" );
|
||||
static_assert ( (o3 >= o3), "" );
|
||||
static_assert ( !(o3 >= o4), "" );
|
||||
static_assert ( (o3 >= o5), "" );
|
||||
|
||||
static_assert ( (o4 >= o1), "" );
|
||||
static_assert ( (o4 >= o2), "" );
|
||||
static_assert ( (o4 >= o3), "" );
|
||||
static_assert ( (o4 >= o4), "" );
|
||||
static_assert ( (o4 >= o5), "" );
|
||||
|
||||
static_assert ( (o5 >= o1), "" );
|
||||
static_assert ( (o5 >= o2), "" );
|
||||
static_assert ( (o5 >= o3), "" );
|
||||
static_assert ( !(o5 >= o4), "" );
|
||||
static_assert ( (o5 >= o5), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator> (const optional<T>& x, const optional<T>& y);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator > ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ > rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef optional<X> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2; // disengaged
|
||||
constexpr O o3{1}; // engaged
|
||||
constexpr O o4{2}; // engaged
|
||||
constexpr O o5{1}; // engaged
|
||||
|
||||
static_assert ( !(o1 > o1), "" );
|
||||
static_assert ( !(o1 > o2), "" );
|
||||
static_assert ( !(o1 > o3), "" );
|
||||
static_assert ( !(o1 > o4), "" );
|
||||
static_assert ( !(o1 > o5), "" );
|
||||
|
||||
static_assert ( !(o2 > o1), "" );
|
||||
static_assert ( !(o2 > o2), "" );
|
||||
static_assert ( !(o2 > o3), "" );
|
||||
static_assert ( !(o2 > o4), "" );
|
||||
static_assert ( !(o2 > o5), "" );
|
||||
|
||||
static_assert ( (o3 > o1), "" );
|
||||
static_assert ( (o3 > o2), "" );
|
||||
static_assert ( !(o3 > o3), "" );
|
||||
static_assert ( !(o3 > o4), "" );
|
||||
static_assert ( !(o3 > o5), "" );
|
||||
|
||||
static_assert ( (o4 > o1), "" );
|
||||
static_assert ( (o4 > o2), "" );
|
||||
static_assert ( (o4 > o3), "" );
|
||||
static_assert ( !(o4 > o4), "" );
|
||||
static_assert ( (o4 > o5), "" );
|
||||
|
||||
static_assert ( (o5 > o1), "" );
|
||||
static_assert ( (o5 > o2), "" );
|
||||
static_assert ( !(o5 > o3), "" );
|
||||
static_assert ( !(o5 > o4), "" );
|
||||
static_assert ( !(o5 > o5), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator<= (const optional<T>& x, const optional<T>& y);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator <= ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ <= rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef optional<X> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2; // disengaged
|
||||
constexpr O o3{1}; // engaged
|
||||
constexpr O o4{2}; // engaged
|
||||
constexpr O o5{1}; // engaged
|
||||
|
||||
static_assert ( (o1 <= o1), "" );
|
||||
static_assert ( (o1 <= o2), "" );
|
||||
static_assert ( (o1 <= o3), "" );
|
||||
static_assert ( (o1 <= o4), "" );
|
||||
static_assert ( (o1 <= o5), "" );
|
||||
|
||||
static_assert ( (o2 <= o1), "" );
|
||||
static_assert ( (o2 <= o2), "" );
|
||||
static_assert ( (o2 <= o3), "" );
|
||||
static_assert ( (o2 <= o4), "" );
|
||||
static_assert ( (o2 <= o5), "" );
|
||||
|
||||
static_assert ( !(o3 <= o1), "" );
|
||||
static_assert ( !(o3 <= o2), "" );
|
||||
static_assert ( (o3 <= o3), "" );
|
||||
static_assert ( (o3 <= o4), "" );
|
||||
static_assert ( (o3 <= o5), "" );
|
||||
|
||||
static_assert ( !(o4 <= o1), "" );
|
||||
static_assert ( !(o4 <= o2), "" );
|
||||
static_assert ( !(o4 <= o3), "" );
|
||||
static_assert ( (o4 <= o4), "" );
|
||||
static_assert ( !(o4 <= o5), "" );
|
||||
|
||||
static_assert ( !(o5 <= o1), "" );
|
||||
static_assert ( !(o5 <= o2), "" );
|
||||
static_assert ( (o5 <= o3), "" );
|
||||
static_assert ( (o5 <= o4), "" );
|
||||
static_assert ( (o5 <= o5), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator< (const optional<T>& x, const optional<T>& y);
|
||||
|
||||
#include <optional>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator < ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ < rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef optional<X> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2; // disengaged
|
||||
constexpr O o3{1}; // engaged
|
||||
constexpr O o4{2}; // engaged
|
||||
constexpr O o5{1}; // engaged
|
||||
|
||||
static_assert ( !(o1 < o1), "" );
|
||||
static_assert ( !(o1 < o2), "" );
|
||||
static_assert ( (o1 < o3), "" );
|
||||
static_assert ( (o1 < o4), "" );
|
||||
static_assert ( (o1 < o5), "" );
|
||||
|
||||
static_assert ( !(o2 < o1), "" );
|
||||
static_assert ( !(o2 < o2), "" );
|
||||
static_assert ( (o2 < o3), "" );
|
||||
static_assert ( (o2 < o4), "" );
|
||||
static_assert ( (o2 < o5), "" );
|
||||
|
||||
static_assert ( !(o3 < o1), "" );
|
||||
static_assert ( !(o3 < o2), "" );
|
||||
static_assert ( !(o3 < o3), "" );
|
||||
static_assert ( (o3 < o4), "" );
|
||||
static_assert ( !(o3 < o5), "" );
|
||||
|
||||
static_assert ( !(o4 < o1), "" );
|
||||
static_assert ( !(o4 < o2), "" );
|
||||
static_assert ( !(o4 < o3), "" );
|
||||
static_assert ( !(o4 < o4), "" );
|
||||
static_assert ( !(o4 < o5), "" );
|
||||
|
||||
static_assert ( !(o5 < o1), "" );
|
||||
static_assert ( !(o5 < o2), "" );
|
||||
static_assert ( !(o5 < o3), "" );
|
||||
static_assert ( (o5 < o4), "" );
|
||||
static_assert ( !(o5 < o5), "" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
int i_;
|
||||
|
||||
constexpr X(int i) : i_(i) {}
|
||||
};
|
||||
|
||||
constexpr bool operator != ( const X &lhs, const X &rhs )
|
||||
{ return lhs.i_ != rhs.i_ ; }
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef X T;
|
||||
typedef optional<T> O;
|
||||
|
||||
constexpr O o1; // disengaged
|
||||
constexpr O o2; // disengaged
|
||||
constexpr O o3{1}; // engaged
|
||||
constexpr O o4{2}; // engaged
|
||||
constexpr O o5{1}; // engaged
|
||||
|
||||
static_assert ( !(o1 != o1), "" );
|
||||
static_assert ( !(o1 != o2), "" );
|
||||
static_assert ( (o1 != o3), "" );
|
||||
static_assert ( (o1 != o4), "" );
|
||||
static_assert ( (o1 != o5), "" );
|
||||
|
||||
static_assert ( !(o2 != o1), "" );
|
||||
static_assert ( !(o2 != o2), "" );
|
||||
static_assert ( (o2 != o3), "" );
|
||||
static_assert ( (o2 != o4), "" );
|
||||
static_assert ( (o2 != o5), "" );
|
||||
|
||||
static_assert ( (o3 != o1), "" );
|
||||
static_assert ( (o3 != o2), "" );
|
||||
static_assert ( !(o3 != o3), "" );
|
||||
static_assert ( (o3 != o4), "" );
|
||||
static_assert ( !(o3 != o5), "" );
|
||||
|
||||
static_assert ( (o4 != o1), "" );
|
||||
static_assert ( (o4 != o2), "" );
|
||||
static_assert ( (o4 != o3), "" );
|
||||
static_assert ( !(o4 != o4), "" );
|
||||
static_assert ( (o4 != o5), "" );
|
||||
|
||||
static_assert ( (o5 != o1), "" );
|
||||
static_assert ( (o5 != o2), "" );
|
||||
static_assert ( !(o5 != o3), "" );
|
||||
static_assert ( (o5 != o4), "" );
|
||||
static_assert ( !(o5 != o5), "" );
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T>
|
||||
// constexpr optional<decay_t<T>> make_optional(T&& v);
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::make_optional;
|
||||
{
|
||||
int arr[10]; ((void)arr);
|
||||
ASSERT_SAME_TYPE(decltype(make_optional(arr)), optional<int*>);
|
||||
}
|
||||
{
|
||||
constexpr auto opt = make_optional(2);
|
||||
ASSERT_SAME_TYPE(decltype(opt), const optional<int>);
|
||||
static_assert(opt.value() == 2);
|
||||
}
|
||||
{
|
||||
optional<int> opt = make_optional(2);
|
||||
assert(*opt == 2);
|
||||
}
|
||||
{
|
||||
std::string s("123");
|
||||
optional<std::string> opt = make_optional(s);
|
||||
assert(*opt == s);
|
||||
}
|
||||
{
|
||||
std::unique_ptr<int> s(new int(3));
|
||||
optional<std::unique_ptr<int>> opt = make_optional(std::move(s));
|
||||
assert(**opt == 3);
|
||||
assert(s == nullptr);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T, class... Args>
|
||||
// constexpr optional<T> make_optional(Args&&... args);
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::make_optional;
|
||||
|
||||
{
|
||||
constexpr auto opt = make_optional<int>('a');
|
||||
static_assert(*opt == int('a'), "");
|
||||
}
|
||||
{
|
||||
std::string s("123");
|
||||
auto opt = make_optional<std::string>(s);
|
||||
assert(*opt == s);
|
||||
}
|
||||
{
|
||||
std::unique_ptr<int> s(new int(3));
|
||||
auto opt = make_optional<std::unique_ptr<int>>(std::move(s));
|
||||
assert(**opt == 3);
|
||||
assert(s == nullptr);
|
||||
}
|
||||
{
|
||||
auto opt = make_optional<std::string>(4, 'X');
|
||||
assert(*opt == "XXXX");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T, class U, class... Args>
|
||||
// constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct TestT {
|
||||
int x;
|
||||
int size;
|
||||
constexpr TestT(std::initializer_list<int> il) : x(*il.begin()), size(il.size()) {}
|
||||
constexpr TestT(std::initializer_list<int> il, const int*)
|
||||
: x(*il.begin()), size(il.size()) {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::make_optional;
|
||||
{
|
||||
constexpr auto opt = make_optional<TestT>({42, 2, 3});
|
||||
ASSERT_SAME_TYPE(decltype(opt), const std::optional<TestT>);
|
||||
static_assert(opt->x == 42, "");
|
||||
static_assert(opt->size == 3, "");
|
||||
}
|
||||
{
|
||||
constexpr auto opt = make_optional<TestT>({42, 2, 3}, nullptr);
|
||||
static_assert(opt->x == 42, "");
|
||||
static_assert(opt->size == 3, "");
|
||||
}
|
||||
{
|
||||
auto opt = make_optional<std::string>({'1', '2', '3'});
|
||||
assert(*opt == "123");
|
||||
}
|
||||
{
|
||||
auto opt = make_optional<std::string>({'a', 'b', 'c'}, std::allocator<char>{});
|
||||
assert(*opt == "abc");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,352 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// template <class T> void swap(optional<T>& x, optional<T>& y)
|
||||
// noexcept(noexcept(x.swap(y)));
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
class X
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
static unsigned dtor_called;
|
||||
X(int i) : i_(i) {}
|
||||
X(X&& x) = default;
|
||||
X& operator=(X&&) = default;
|
||||
~X() {++dtor_called;}
|
||||
|
||||
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
unsigned X::dtor_called = 0;
|
||||
|
||||
class Y
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
static unsigned dtor_called;
|
||||
Y(int i) : i_(i) {}
|
||||
Y(Y&&) = default;
|
||||
~Y() {++dtor_called;}
|
||||
|
||||
friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
|
||||
friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
|
||||
};
|
||||
|
||||
unsigned Y::dtor_called = 0;
|
||||
|
||||
class Z
|
||||
{
|
||||
int i_;
|
||||
public:
|
||||
Z(int i) : i_(i) {}
|
||||
Z(Z&&) { TEST_THROW(7);}
|
||||
|
||||
friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
|
||||
friend void swap(Z& x, Z& y) { TEST_THROW(6);}
|
||||
};
|
||||
|
||||
|
||||
struct NonSwappable {
|
||||
NonSwappable(NonSwappable const&) = delete;
|
||||
};
|
||||
void swap(NonSwappable&, NonSwappable&) = delete;
|
||||
|
||||
void test_swap_sfinae() {
|
||||
using std::optional;
|
||||
{
|
||||
using T = TestTypes::TestType;
|
||||
static_assert(std::is_swappable_v<optional<T>>, "");
|
||||
}
|
||||
{
|
||||
using T = TestTypes::MoveOnly;
|
||||
static_assert(std::is_swappable_v<optional<T>>, "");
|
||||
}
|
||||
{
|
||||
using T = TestTypes::Copyable;
|
||||
static_assert(std::is_swappable_v<optional<T>>, "");
|
||||
}
|
||||
{
|
||||
using T = TestTypes::NoCtors;
|
||||
static_assert(!std::is_swappable_v<optional<T>>, "");
|
||||
}
|
||||
{
|
||||
using T = NonSwappable;
|
||||
static_assert(!std::is_swappable_v<optional<T>>, "");
|
||||
}
|
||||
{
|
||||
// Even thought CopyOnly has deleted move operations, those operations
|
||||
// cause optional<CopyOnly> to have implicitly deleted move operations
|
||||
// that decay into copies.
|
||||
using T = TestTypes::CopyOnly;
|
||||
using Opt = optional<T>;
|
||||
T::reset();
|
||||
Opt L(101), R(42);
|
||||
T::reset_constructors();
|
||||
std::swap(L, R);
|
||||
assert(L->value == 42);
|
||||
assert(R->value == 101);
|
||||
assert(T::copy_constructed == 1);
|
||||
assert(T::constructed == T::copy_constructed);
|
||||
assert(T::assigned == 2);
|
||||
assert(T::assigned == T::copy_assigned);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_swap_sfinae();
|
||||
{
|
||||
optional<int> opt1;
|
||||
optional<int> opt2;
|
||||
static_assert(noexcept(swap(opt1, opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
swap(opt1, opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<int> opt1(1);
|
||||
optional<int> opt2;
|
||||
static_assert(noexcept(swap(opt1, opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
swap(opt1, opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<int> opt1;
|
||||
optional<int> opt2(2);
|
||||
static_assert(noexcept(swap(opt1, opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
swap(opt1, opt2);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<int> opt1(1);
|
||||
optional<int> opt2(2);
|
||||
static_assert(noexcept(swap(opt1, opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
swap(opt1, opt2);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<X> opt1;
|
||||
optional<X> opt2;
|
||||
static_assert(noexcept(swap(opt1, opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
swap(opt1, opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(X::dtor_called == 0);
|
||||
}
|
||||
{
|
||||
optional<X> opt1(1);
|
||||
optional<X> opt2;
|
||||
static_assert(noexcept(swap(opt1, opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
X::dtor_called = 0;
|
||||
swap(opt1, opt2);
|
||||
assert(X::dtor_called == 1);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<X> opt1;
|
||||
optional<X> opt2(2);
|
||||
static_assert(noexcept(swap(opt1, opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
X::dtor_called = 0;
|
||||
swap(opt1, opt2);
|
||||
assert(X::dtor_called == 1);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<X> opt1(1);
|
||||
optional<X> opt2(2);
|
||||
static_assert(noexcept(swap(opt1, opt2)) == true, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
X::dtor_called = 0;
|
||||
swap(opt1, opt2);
|
||||
assert(X::dtor_called == 1); // from inside std::swap
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<Y> opt1;
|
||||
optional<Y> opt2;
|
||||
static_assert(noexcept(swap(opt1, opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
swap(opt1, opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(Y::dtor_called == 0);
|
||||
}
|
||||
{
|
||||
optional<Y> opt1(1);
|
||||
optional<Y> opt2;
|
||||
static_assert(noexcept(swap(opt1, opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
Y::dtor_called = 0;
|
||||
swap(opt1, opt2);
|
||||
assert(Y::dtor_called == 1);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<Y> opt1;
|
||||
optional<Y> opt2(2);
|
||||
static_assert(noexcept(swap(opt1, opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
Y::dtor_called = 0;
|
||||
swap(opt1, opt2);
|
||||
assert(Y::dtor_called == 1);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<Y> opt1(1);
|
||||
optional<Y> opt2(2);
|
||||
static_assert(noexcept(swap(opt1, opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
Y::dtor_called = 0;
|
||||
swap(opt1, opt2);
|
||||
assert(Y::dtor_called == 0);
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 1);
|
||||
}
|
||||
{
|
||||
optional<Z> opt1;
|
||||
optional<Z> opt2;
|
||||
static_assert(noexcept(swap(opt1, opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
swap(opt1, opt2);
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
optional<Z> opt1;
|
||||
opt1.emplace(1);
|
||||
optional<Z> opt2;
|
||||
static_assert(noexcept(swap(opt1, opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
try
|
||||
{
|
||||
swap(opt1, opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 7);
|
||||
}
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
}
|
||||
{
|
||||
optional<Z> opt1;
|
||||
optional<Z> opt2;
|
||||
opt2.emplace(2);
|
||||
static_assert(noexcept(swap(opt1, opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
try
|
||||
{
|
||||
swap(opt1, opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 7);
|
||||
}
|
||||
assert(static_cast<bool>(opt1) == false);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
}
|
||||
{
|
||||
optional<Z> opt1;
|
||||
opt1.emplace(1);
|
||||
optional<Z> opt2;
|
||||
opt2.emplace(2);
|
||||
static_assert(noexcept(swap(opt1, opt2)) == false, "");
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
try
|
||||
{
|
||||
swap(opt1, opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
}
|
||||
assert(static_cast<bool>(opt1) == true);
|
||||
assert(*opt1 == 1);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
}
|
||||
#endif // TEST_HAS_NO_EXCEPTIONS
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// A program that necessitates the instantiation of template optional for
|
||||
// (possibly cv-qualified) in_place_t is ill-formed.
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::in_place_t;
|
||||
using std::in_place;
|
||||
|
||||
optional<in_place_t> opt; // expected-note {{requested here}}
|
||||
// expected-error@optional:* {{"instantiation of optional with in_place_t is ill-formed"}}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// #include <initializer_list>
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
|
||||
std::initializer_list<int> list;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// A program that necessitates the instantiation of template optional for
|
||||
// (possibly cv-qualified) nullopt_t is ill-formed.
|
||||
|
||||
#include <optional>
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::optional;
|
||||
using std::nullopt_t;
|
||||
using std::nullopt;
|
||||
|
||||
optional<nullopt_t> opt; // expected-note 1 {{requested here}}
|
||||
optional<const nullopt_t> opt1; // expected-note 1 {{requested here}}
|
||||
optional<nullopt_t &> opt2; // expected-note 1 {{requested here}}
|
||||
optional<nullopt_t &&> opt3; // expected-note 1 {{requested here}}
|
||||
// expected-error@optional:* 4 {{instantiation of optional with nullopt_t is ill-formed}}
|
||||
}
|
|
@ -1,10 +1,186 @@
|
|||
#ifndef TEST_SUPPORT_ARCHETYPES_HPP
|
||||
#define TEST_SUPPORT_ARCHETYPES_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
|
||||
namespace ArchetypeBases {
|
||||
|
||||
template <bool, class T>
|
||||
struct DepType : T {};
|
||||
|
||||
struct NullBase {};
|
||||
|
||||
template <class Derived, bool Explicit = false>
|
||||
struct TestBase {
|
||||
static int alive;
|
||||
static int constructed;
|
||||
static int value_constructed;
|
||||
static int default_constructed;
|
||||
static int copy_constructed;
|
||||
static int move_constructed;
|
||||
static int assigned;
|
||||
static int value_assigned;
|
||||
static int copy_assigned;
|
||||
static int move_assigned;
|
||||
static int destroyed;
|
||||
|
||||
static void reset() {
|
||||
assert(alive == 0);
|
||||
alive = 0;
|
||||
reset_constructors();
|
||||
}
|
||||
|
||||
static void reset_constructors() {
|
||||
constructed = value_constructed = default_constructed =
|
||||
copy_constructed = move_constructed = 0;
|
||||
assigned = value_assigned = copy_assigned = move_assigned = destroyed = 0;
|
||||
}
|
||||
|
||||
TestBase() noexcept : value(0) {
|
||||
++alive; ++constructed; ++default_constructed;
|
||||
}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit TestBase(int x) noexcept : value(x) {
|
||||
++alive; ++constructed; ++value_constructed;
|
||||
}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
TestBase(int x) noexcept : value(x) {
|
||||
++alive; ++constructed; ++value_constructed;
|
||||
}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit TestBase(int x, int y) noexcept : value(y) {
|
||||
++alive; ++constructed; ++value_constructed;
|
||||
}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
TestBase(int x, int y) noexcept : value(y) {
|
||||
++alive; ++constructed; ++value_constructed;
|
||||
}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit TestBase(std::initializer_list<int>& il, int y = 0) noexcept
|
||||
: value(il.size()) {
|
||||
++alive; ++constructed; ++value_constructed;
|
||||
}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
TestBase(std::initializer_list<int>& il, int y = 0) noexcept : value(il.size()) {
|
||||
++alive; ++constructed; ++value_constructed;
|
||||
}
|
||||
TestBase& operator=(int xvalue) noexcept {
|
||||
value = xvalue;
|
||||
++assigned; ++value_assigned;
|
||||
return *this;
|
||||
}
|
||||
protected:
|
||||
~TestBase() {
|
||||
assert(value != -999); assert(alive > 0);
|
||||
--alive; ++destroyed; value = -999;
|
||||
}
|
||||
TestBase(TestBase const& o) noexcept : value(o.value) {
|
||||
assert(o.value != -1); assert(o.value != -999);
|
||||
++alive; ++constructed; ++copy_constructed;
|
||||
}
|
||||
TestBase(TestBase && o) noexcept : value(o.value) {
|
||||
assert(o.value != -1); assert(o.value != -999);
|
||||
++alive; ++constructed; ++move_constructed;
|
||||
o.value = -1;
|
||||
}
|
||||
TestBase& operator=(TestBase const& o) noexcept {
|
||||
assert(o.value != -1); assert(o.value != -999);
|
||||
++assigned; ++copy_assigned;
|
||||
value = o.value;
|
||||
return *this;
|
||||
}
|
||||
TestBase& operator=(TestBase&& o) noexcept {
|
||||
assert(o.value != -1); assert(o.value != -999);
|
||||
++assigned; ++move_assigned;
|
||||
value = o.value;
|
||||
o.value = -1;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
int value;
|
||||
};
|
||||
|
||||
template <class D, bool E> int TestBase<D, E>::alive = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::constructed = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::value_constructed = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::default_constructed = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::copy_constructed = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::move_constructed = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::assigned = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::value_assigned = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::copy_assigned = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::move_assigned = 0;
|
||||
template <class D, bool E> int TestBase<D, E>::destroyed = 0;
|
||||
|
||||
template <bool Explicit = false>
|
||||
struct ValueBase {
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit constexpr ValueBase(int x) : value(x) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
constexpr ValueBase(int x) : value(x) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit constexpr ValueBase(int x, int y) : value(y) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
constexpr ValueBase(int x, int y) : value(y) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit constexpr ValueBase(std::initializer_list<int>& il, int y = 0) : value(il.size()) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
constexpr ValueBase(std::initializer_list<int>& il, int y = 0) : value(il.size()) {}
|
||||
constexpr ValueBase& operator=(int xvalue) noexcept {
|
||||
value = xvalue;
|
||||
return *this;
|
||||
}
|
||||
//~ValueBase() { assert(value != -999); value = -999; }
|
||||
int value;
|
||||
protected:
|
||||
constexpr ValueBase() noexcept : value(0) {}
|
||||
constexpr ValueBase(ValueBase const& o) noexcept : value(o.value) {
|
||||
assert(o.value != -1); assert(o.value != -999);
|
||||
}
|
||||
constexpr ValueBase(ValueBase && o) noexcept : value(o.value) {
|
||||
assert(o.value != -1); assert(o.value != -999);
|
||||
o.value = -1;
|
||||
}
|
||||
constexpr ValueBase& operator=(ValueBase const& o) noexcept {
|
||||
assert(o.value != -1); assert(o.value != -999);
|
||||
value = o.value;
|
||||
return *this;
|
||||
}
|
||||
constexpr ValueBase& operator=(ValueBase&& o) noexcept {
|
||||
assert(o.value != -1); assert(o.value != -999);
|
||||
value = o.value;
|
||||
o.value = -1;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <bool Explicit = false>
|
||||
struct TrivialValueBase {
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit constexpr TrivialValueBase(int x) : value(x) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
constexpr TrivialValueBase(int x) : value(x) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit constexpr TrivialValueBase(int x, int y) : value(y) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
constexpr TrivialValueBase(int x, int y) : value(y) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
||||
explicit constexpr TrivialValueBase(std::initializer_list<int>& il, int y = 0) : value(il.size()) {}
|
||||
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
||||
constexpr TrivialValueBase(std::initializer_list<int>& il, int y = 0) : value(il.size()) {};
|
||||
int value;
|
||||
protected:
|
||||
constexpr TrivialValueBase() noexcept : value(0) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
// Trivial Implicit Test Types
|
||||
namespace ImplicitTypes {
|
||||
|
@ -18,9 +194,18 @@ namespace ExplicitTypes {
|
|||
#include "archetypes.ipp"
|
||||
}
|
||||
|
||||
|
||||
//============================================================================//
|
||||
// Non-Trivial Implicit Test Types
|
||||
//
|
||||
namespace NonConstexprTypes {
|
||||
#define DEFINE_CONSTEXPR
|
||||
#include "archetypes.ipp"
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
// Non-literal implicit test types
|
||||
namespace NonLiteralTypes {
|
||||
#define DEFINE_ASSIGN_CONSTEXPR
|
||||
#define DEFINE_DTOR(Name) ~Name() {}
|
||||
#include "archetypes.ipp"
|
||||
}
|
||||
|
@ -29,9 +214,144 @@ namespace NonLiteralTypes {
|
|||
// Non-Trivially Copyable Implicit Test Types
|
||||
namespace NonTrivialTypes {
|
||||
#define DEFINE_CTOR {}
|
||||
#define DEFINE_ASSIGN { return *this; }
|
||||
#define DEFINE_DEFAULT_CTOR = default
|
||||
#include "archetypes.ipp"
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
// Implicit counting types
|
||||
namespace TestTypes {
|
||||
#define DEFINE_CONSTEXPR
|
||||
#define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
|
||||
#include "archetypes.ipp"
|
||||
|
||||
using TestType = AllCtors;
|
||||
|
||||
// Add equality operators
|
||||
template <class Tp>
|
||||
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value == R.value;
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value != R.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
// Implicit counting types
|
||||
namespace ExplicitTestTypes {
|
||||
#define DEFINE_CONSTEXPR
|
||||
#define DEFINE_EXPLICIT explicit
|
||||
#define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
|
||||
#include "archetypes.ipp"
|
||||
|
||||
using TestType = AllCtors;
|
||||
|
||||
// Add equality operators
|
||||
template <class Tp>
|
||||
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value == R.value;
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value != R.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
// Implicit value types
|
||||
namespace ConstexprTestTypes {
|
||||
#define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
|
||||
#include "archetypes.ipp"
|
||||
|
||||
using TestType = AllCtors;
|
||||
|
||||
// Add equality operators
|
||||
template <class Tp>
|
||||
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value == R.value;
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value != R.value;
|
||||
}
|
||||
|
||||
} // end namespace ValueTypes
|
||||
|
||||
|
||||
//============================================================================//
|
||||
//
|
||||
namespace ExplicitConstexprTestTypes {
|
||||
#define DEFINE_EXPLICIT explicit
|
||||
#define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
|
||||
#include "archetypes.ipp"
|
||||
|
||||
using TestType = AllCtors;
|
||||
|
||||
// Add equality operators
|
||||
template <class Tp>
|
||||
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value == R.value;
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value != R.value;
|
||||
}
|
||||
|
||||
} // end namespace ValueTypes
|
||||
|
||||
|
||||
//============================================================================//
|
||||
//
|
||||
namespace TrivialTestTypes {
|
||||
#define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
|
||||
#include "archetypes.ipp"
|
||||
|
||||
using TestType = AllCtors;
|
||||
|
||||
// Add equality operators
|
||||
template <class Tp>
|
||||
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value == R.value;
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value != R.value;
|
||||
}
|
||||
|
||||
} // end namespace TrivialValueTypes
|
||||
|
||||
//============================================================================//
|
||||
//
|
||||
namespace ExplicitTrivialTestTypes {
|
||||
#define DEFINE_EXPLICIT explicit
|
||||
#define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
|
||||
#include "archetypes.ipp"
|
||||
|
||||
using TestType = AllCtors;
|
||||
|
||||
// Add equality operators
|
||||
template <class Tp>
|
||||
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value == R.value;
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
||||
return L.value != R.value;
|
||||
}
|
||||
|
||||
} // end namespace ExplicitTrivialTestTypes
|
||||
|
||||
#endif // TEST_STD_VER >= 11
|
||||
|
||||
#endif // TEST_SUPPORT_ARCHETYPES_HPP
|
||||
|
|
|
@ -1,10 +1,22 @@
|
|||
|
||||
#ifndef DEFINE_BASE
|
||||
#define DEFINE_BASE(Name) ::ArchetypeBases::NullBase
|
||||
#endif
|
||||
#ifndef DEFINE_EXPLICIT
|
||||
#define DEFINE_EXPLICIT
|
||||
#endif
|
||||
#ifndef DEFINE_CONSTEXPR
|
||||
#define DEFINE_CONSTEXPR constexpr
|
||||
#endif
|
||||
#ifndef DEFINE_ASSIGN_CONSTEXPR
|
||||
#define DEFINE_ASSIGN_CONSTEXPR DEFINE_CONSTEXPR
|
||||
#endif
|
||||
#ifndef DEFINE_CTOR
|
||||
#define DEFINE_CTOR = default
|
||||
#endif
|
||||
#ifndef DEFINE_DEFAULT_CTOR
|
||||
#define DEFINE_DEFAULT_CTOR DEFINE_CTOR
|
||||
#endif
|
||||
#ifndef DEFINE_ASSIGN
|
||||
#define DEFINE_ASSIGN = default
|
||||
#endif
|
||||
|
@ -12,78 +24,117 @@
|
|||
#define DEFINE_DTOR(Name)
|
||||
#endif
|
||||
|
||||
struct NoDefault {
|
||||
DEFINE_EXPLICIT NoDefault() = delete;
|
||||
DEFINE_DTOR(NoDefault)
|
||||
};
|
||||
|
||||
struct AllCtors {
|
||||
DEFINE_EXPLICIT AllCtors() DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT AllCtors(AllCtors const&) DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT AllCtors(AllCtors &&) DEFINE_CTOR;
|
||||
AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN;
|
||||
AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN;
|
||||
struct AllCtors : DEFINE_BASE(AllCtors) {
|
||||
using Base = DEFINE_BASE(AllCtors);
|
||||
using Base::Base;
|
||||
using Base::operator=;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_DEFAULT_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_CTOR;
|
||||
DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN;
|
||||
DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN;
|
||||
DEFINE_DTOR(AllCtors)
|
||||
};
|
||||
|
||||
struct Copyable {
|
||||
DEFINE_EXPLICIT Copyable() DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT Copyable(Copyable const &) DEFINE_CTOR;
|
||||
struct NoCtors : DEFINE_BASE(NoCtors) {
|
||||
using Base = DEFINE_BASE(NoCtors);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT NoCtors() = delete;
|
||||
DEFINE_EXPLICIT NoCtors(NoCtors const&) = delete;
|
||||
NoCtors& operator=(NoCtors const&) = delete;
|
||||
DEFINE_DTOR(NoCtors)
|
||||
};
|
||||
|
||||
struct NoDefault : DEFINE_BASE(NoDefault) {
|
||||
using Base = DEFINE_BASE(NoDefault);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() = delete;
|
||||
DEFINE_DTOR(NoDefault)
|
||||
};
|
||||
|
||||
struct DefaultOnly : DEFINE_BASE(DefaultOnly) {
|
||||
using Base = DEFINE_BASE(DefaultOnly);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_DEFAULT_CTOR;
|
||||
DefaultOnly(DefaultOnly const&) = delete;
|
||||
DefaultOnly& operator=(DefaultOnly const&) = delete;
|
||||
DEFINE_DTOR(DefaultOnly)
|
||||
};
|
||||
|
||||
struct Copyable : DEFINE_BASE(Copyable) {
|
||||
using Base = DEFINE_BASE(Copyable);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_DEFAULT_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_CTOR;
|
||||
Copyable &operator=(Copyable const &) DEFINE_ASSIGN;
|
||||
DEFINE_DTOR(Copyable)
|
||||
};
|
||||
|
||||
struct CopyOnly {
|
||||
DEFINE_EXPLICIT CopyOnly() DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT CopyOnly(CopyOnly const &) DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT CopyOnly(CopyOnly &&) = delete;
|
||||
struct CopyOnly : DEFINE_BASE(CopyOnly) {
|
||||
using Base = DEFINE_BASE(CopyOnly);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_DEFAULT_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) = delete;
|
||||
CopyOnly &operator=(CopyOnly const &) DEFINE_ASSIGN;
|
||||
CopyOnly &operator=(CopyOnly &&) = delete;
|
||||
DEFINE_DTOR(CopyOnly)
|
||||
};
|
||||
|
||||
struct NonCopyable {
|
||||
DEFINE_EXPLICIT NonCopyable() DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT NonCopyable(NonCopyable const &) = delete;
|
||||
struct NonCopyable : DEFINE_BASE(NonCopyable) {
|
||||
using Base = DEFINE_BASE(NonCopyable);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_DEFAULT_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) = delete;
|
||||
NonCopyable &operator=(NonCopyable const &) = delete;
|
||||
DEFINE_DTOR(NonCopyable)
|
||||
};
|
||||
|
||||
struct MoveOnly {
|
||||
DEFINE_EXPLICIT MoveOnly() DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT MoveOnly(MoveOnly &&) DEFINE_CTOR;
|
||||
struct MoveOnly : DEFINE_BASE(MoveOnly) {
|
||||
using Base = DEFINE_BASE(MoveOnly);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_DEFAULT_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_CTOR;
|
||||
MoveOnly &operator=(MoveOnly &&) DEFINE_ASSIGN;
|
||||
DEFINE_DTOR(MoveOnly)
|
||||
};
|
||||
|
||||
struct CopyAssignable {
|
||||
DEFINE_EXPLICIT CopyAssignable() = delete;
|
||||
CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN;
|
||||
DEFINE_DTOR(CopyAssignable)
|
||||
struct CopyAssignable : DEFINE_BASE(CopyAssignable) {
|
||||
using Base = DEFINE_BASE(CopyAssignable);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() = delete;
|
||||
CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN;
|
||||
DEFINE_DTOR(CopyAssignable)
|
||||
};
|
||||
|
||||
struct CopyAssignOnly {
|
||||
DEFINE_EXPLICIT CopyAssignOnly() = delete;
|
||||
CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN;
|
||||
CopyAssignOnly& operator=(CopyAssignOnly &&) = delete;
|
||||
DEFINE_DTOR(CopyAssignOnly)
|
||||
struct CopyAssignOnly : DEFINE_BASE(CopyAssignOnly) {
|
||||
using Base = DEFINE_BASE(CopyAssignOnly);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() = delete;
|
||||
CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN;
|
||||
CopyAssignOnly& operator=(CopyAssignOnly &&) = delete;
|
||||
DEFINE_DTOR(CopyAssignOnly)
|
||||
};
|
||||
|
||||
struct MoveAssignOnly {
|
||||
DEFINE_EXPLICIT MoveAssignOnly() = delete;
|
||||
MoveAssignOnly& operator=(MoveAssignOnly const&) = delete;
|
||||
MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN;
|
||||
DEFINE_DTOR(MoveAssignOnly)
|
||||
struct MoveAssignOnly : DEFINE_BASE(MoveAssignOnly) {
|
||||
using Base = DEFINE_BASE(MoveAssignOnly);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() = delete;
|
||||
MoveAssignOnly& operator=(MoveAssignOnly const&) = delete;
|
||||
MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN;
|
||||
DEFINE_DTOR(MoveAssignOnly)
|
||||
};
|
||||
|
||||
struct ConvertingType {
|
||||
DEFINE_EXPLICIT ConvertingType() DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT ConvertingType(ConvertingType const&) DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT ConvertingType(ConvertingType &&) DEFINE_CTOR;
|
||||
struct ConvertingType : DEFINE_BASE(ConvertingType) {
|
||||
using Base = DEFINE_BASE(ConvertingType);
|
||||
using Base::Base;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_DEFAULT_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_CTOR;
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_CTOR;
|
||||
ConvertingType& operator=(ConvertingType const&) DEFINE_ASSIGN;
|
||||
ConvertingType& operator=(ConvertingType &&) DEFINE_ASSIGN;
|
||||
template <class ...Args>
|
||||
DEFINE_EXPLICIT ConvertingType(Args&&...) {}
|
||||
DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {}
|
||||
template <class Arg>
|
||||
ConvertingType& operator=(Arg&&) { return *this; }
|
||||
DEFINE_DTOR(ConvertingType)
|
||||
|
@ -91,8 +142,10 @@ struct ConvertingType {
|
|||
|
||||
template <template <class...> class List>
|
||||
using ApplyTypes = List<
|
||||
NoDefault,
|
||||
AllCtors,
|
||||
NoCtors,
|
||||
NoDefault,
|
||||
DefaultOnly,
|
||||
Copyable,
|
||||
CopyOnly,
|
||||
NonCopyable,
|
||||
|
@ -103,7 +156,11 @@ using ApplyTypes = List<
|
|||
ConvertingType
|
||||
>;
|
||||
|
||||
#undef DEFINE_BASE
|
||||
#undef DEFINE_EXPLICIT
|
||||
#undef DEFINE_CONSTEXPR
|
||||
#undef DEFINE_ASSIGN_CONSTEXPR
|
||||
#undef DEFINE_CTOR
|
||||
#undef DEFINE_DEFAULT_CTOR
|
||||
#undef DEFINE_ASSIGN
|
||||
#undef DEFINE_DTOR
|
||||
|
|
Loading…
Reference in New Issue