118 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++1110// <utility>11 12// exchange13 14// template<class T, class U=T>15// constexpr T // constexpr after C++1716// exchange(T& obj, U&& new_value)17// noexcept(is_nothrow_move_constructible<T>::value && is_nothrow_assignable<T&, U>::value);18 19#include <utility>20#include <cassert>21#include <string>22 23#include "test_macros.h"24 25#if TEST_STD_VER > 1726TEST_CONSTEXPR bool test_constexpr() {27 int v = 12;28 29 if (12 != std::exchange(v,23) || v != 23)30 return false;31 32 if (23 != std::exchange(v,static_cast<short>(67)) || v != 67)33 return false;34 35 if (67 != std::exchange<int, short>(v, {}) || v != 0)36 return false;37 return true;38 }39#endif40 41template<bool Move, bool Assign>42struct TestNoexcept {43 TestNoexcept() = default;44 TestNoexcept(const TestNoexcept&);45 TestNoexcept(TestNoexcept&&) noexcept(Move);46 TestNoexcept& operator=(const TestNoexcept&);47 TestNoexcept& operator=(TestNoexcept&&) noexcept(Assign);48};49 50constexpr bool test_noexcept() {51 {52 int x = 42;53 ASSERT_NOEXCEPT(std::exchange(x, 42));54 }55 {56 TestNoexcept<true, true> x;57 ASSERT_NOEXCEPT(std::exchange(x, std::move(x)));58 ASSERT_NOT_NOEXCEPT(std::exchange(x, x)); // copy-assignment is not noexcept59 }60 {61 TestNoexcept<true, false> x;62 ASSERT_NOT_NOEXCEPT(std::exchange(x, std::move(x)));63 }64 {65 TestNoexcept<false, true> x;66 ASSERT_NOT_NOEXCEPT(std::exchange(x, std::move(x)));67 }68 69 return true;70}71 72int main(int, char**)73{74 {75 int v = 12;76 assert ( std::exchange ( v, 23 ) == 12 );77 assert ( v == 23 );78 assert ( std::exchange ( v, static_cast<short>(67) ) == 23 );79 assert ( v == 67 );80 81 assert ((std::exchange<int, short> ( v, {} )) == 67 );82 assert ( v == 0 );83 84 }85 86 {87 bool b = false;88 assert ( !std::exchange ( b, true ));89 assert ( b );90 }91 92 {93 const std::string s1 ( "Hi Mom!" );94 const std::string s2 ( "Yo Dad!" );95 std::string s3 = s1; // Mom96 assert ( std::exchange ( s3, s2 ) == s1 );97 assert ( s3 == s2 );98 assert ( std::exchange ( s3, "Hi Mom!" ) == s2 );99 assert ( s3 == s1 );100 101 s3 = s2; // Dad102 assert ( std::exchange ( s3, {} ) == s2 );103 assert ( s3.size () == 0 );104 105 s3 = s2; // Dad106 assert ( std::exchange ( s3, "" ) == s2 );107 assert ( s3.size () == 0 );108 }109 110#if TEST_STD_VER > 17111 static_assert(test_constexpr());112#endif113 114 static_assert(test_noexcept(), "");115 116 return 0;117}118