diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-10-12 06:45:11 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-10-12 06:45:11 +0000 |
commit | 6ee4001cc957acac39181b68193e1414c3163698 (patch) | |
tree | 6f4a8a05e89e454e08b4385f522b0d84b9e64d7a /libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp | |
parent | 49a278fb6ddd123d68ddbe7cedbedff92cd433c1 (diff) | |
download | bcm5719-llvm-6ee4001cc957acac39181b68193e1414c3163698.tar.gz bcm5719-llvm-6ee4001cc957acac39181b68193e1414c3163698.zip |
Add <optional> header.
This patch is largely thanks to Casey Carter @ Microsoft. He did the initial
work of porting our experimental implementation and tests over to namespace
std.
llvm-svn: 283977
Diffstat (limited to 'libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp')
-rw-r--r-- | libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp new file mode 100644 index 00000000000..6bbb880b6ec --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp @@ -0,0 +1,345 @@ +//===----------------------------------------------------------------------===// +// +// 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);} +}; + +template <class T, class = decltype(std::declval<T&>().swap(std::declval<T&>()))> +constexpr bool has_swap(int) { return true; } +template <class T> +constexpr bool has_swap(long) { return false; } +template <class T> +constexpr bool has_swap() {return has_swap<T>(0); } + +struct NonSwappable { +}; +void swap(NonSwappable&, NonSwappable&) = delete; + +void test_swap_sfinae() { + using std::optional; + { + using T = TestTypes::TestType; + static_assert(has_swap<optional<T>>(), ""); + } + { + using T = TestTypes::MoveOnly; + static_assert(has_swap<optional<T>>(), ""); + } + { + using T = TestTypes::Copyable; + static_assert(has_swap<optional<T>>(), ""); + } + { + using T = TestTypes::NoCtors; + static_assert(!has_swap<optional<T>>(), ""); + } + { + using T = TestTypes::CopyOnly; + static_assert(!has_swap<optional<T>>(), ""); + } + { + using T = NonSwappable; + static_assert(!has_swap<optional<T>>(), ""); + } +} + +int main() +{ + test_swap_sfinae(); + { + 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 +} |