121 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++11, c++14, c++17, c++2010 11// test forward_like12 13#include <cassert>14#include <type_traits>15#include <utility>16 17struct U {}; // class type so const-qualification is not stripped from a prvalue18using CU = const U;19using T = int;20using CT = const T;21 22U u{};23const U& cu = u;24 25static_assert(std::is_same_v<decltype(std::forward_like<T>(U{})), U&&>);26static_assert(std::is_same_v<decltype(std::forward_like<T>(CU{})), CU&&>);27static_assert(std::is_same_v<decltype(std::forward_like<T>(u)), U&&>);28static_assert(std::is_same_v<decltype(std::forward_like<T>(cu)), CU&&>);29static_assert(std::is_same_v<decltype(std::forward_like<T>(std::move(u))), U&&>);30static_assert(std::is_same_v<decltype(std::forward_like<T>(std::move(cu))), CU&&>);31 32static_assert(std::is_same_v<decltype(std::forward_like<CT>(U{})), CU&&>);33static_assert(std::is_same_v<decltype(std::forward_like<CT>(CU{})), CU&&>);34static_assert(std::is_same_v<decltype(std::forward_like<CT>(u)), CU&&>);35static_assert(std::is_same_v<decltype(std::forward_like<CT>(cu)), CU&&>);36static_assert(std::is_same_v<decltype(std::forward_like<CT>(std::move(u))), CU&&>);37static_assert(std::is_same_v<decltype(std::forward_like<CT>(std::move(cu))), CU&&>);38 39static_assert(std::is_same_v<decltype(std::forward_like<T&>(U{})), U&>);40static_assert(std::is_same_v<decltype(std::forward_like<T&>(CU{})), CU&>);41static_assert(std::is_same_v<decltype(std::forward_like<T&>(u)), U&>);42static_assert(std::is_same_v<decltype(std::forward_like<T&>(cu)), CU&>);43static_assert(std::is_same_v<decltype(std::forward_like<T&>(std::move(u))), U&>);44static_assert(std::is_same_v<decltype(std::forward_like<T&>(std::move(cu))), CU&>);45 46static_assert(std::is_same_v<decltype(std::forward_like<CT&>(U{})), CU&>);47static_assert(std::is_same_v<decltype(std::forward_like<CT&>(CU{})), CU&>);48static_assert(std::is_same_v<decltype(std::forward_like<CT&>(u)), CU&>);49static_assert(std::is_same_v<decltype(std::forward_like<CT&>(cu)), CU&>);50static_assert(std::is_same_v<decltype(std::forward_like<CT&>(std::move(u))), CU&>);51static_assert(std::is_same_v<decltype(std::forward_like<CT&>(std::move(cu))), CU&>);52 53static_assert(std::is_same_v<decltype(std::forward_like<T&&>(U{})), U&&>);54static_assert(std::is_same_v<decltype(std::forward_like<T&&>(CU{})), CU&&>);55static_assert(std::is_same_v<decltype(std::forward_like<T&&>(u)), U&&>);56static_assert(std::is_same_v<decltype(std::forward_like<T&&>(cu)), CU&&>);57static_assert(std::is_same_v<decltype(std::forward_like<T&&>(std::move(u))), U&&>);58static_assert(std::is_same_v<decltype(std::forward_like<T&&>(std::move(cu))), CU&&>);59 60static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(U{})), CU&&>);61static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(CU{})), CU&&>);62static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(u)), CU&&>);63static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(cu)), CU&&>);64static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(std::move(u))), CU&&>);65static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(std::move(cu))), CU&&>);66 67static_assert(noexcept(std::forward_like<T>(u)));68 69static_assert(std::is_same_v<decltype(std::forward_like<U&>(u)), U&>);70static_assert(std::is_same_v<decltype(std::forward_like<CU&>(cu)), CU&>);71static_assert(std::is_same_v<decltype(std::forward_like<U&&>(std::move(u))), U&&>);72static_assert(std::is_same_v<decltype(std::forward_like<CU&&>(std::move(cu))), CU&&>);73 74struct NoCtorCopyMove {75 NoCtorCopyMove() = delete;76 NoCtorCopyMove(const NoCtorCopyMove&) = delete;77 NoCtorCopyMove(NoCtorCopyMove&&) = delete;78};79 80static_assert(std::is_same_v<decltype(std::forward_like<CT&&>(std::declval<NoCtorCopyMove>())), const NoCtorCopyMove&&>);81static_assert(std::is_same_v<decltype(std::forward_like<CT&>(std::declval<NoCtorCopyMove>())), const NoCtorCopyMove&>);82static_assert(std::is_same_v<decltype(std::forward_like<T&&>(std::declval<NoCtorCopyMove>())), NoCtorCopyMove&&>);83static_assert(std::is_same_v<decltype(std::forward_like<T&>(std::declval<NoCtorCopyMove>())), NoCtorCopyMove&>);84 85static_assert(noexcept(std::forward_like<T>(std::declval<NoCtorCopyMove>())));86 87constexpr bool test() {88 {89 int val = 1729;90 auto&& result = std::forward_like<const double&>(val);91 static_assert(std::is_same_v<decltype(result), const int&>);92 assert(&result == &val);93 }94 {95 int val = 1729;96 auto&& result = std::forward_like<double&>(val);97 static_assert(std::is_same_v<decltype(result), int&>);98 assert(&result == &val);99 }100 {101 int val = 1729;102 auto&& result = std::forward_like<const double&&>(val);103 static_assert(std::is_same_v<decltype(result), const int&&>);104 assert(&result == &val);105 }106 {107 int val = 1729;108 auto&& result = std::forward_like<double&&>(val);109 static_assert(std::is_same_v<decltype(result), int&&>);110 assert(&result == &val);111 }112 return true;113}114 115int main(int, char**) {116 test();117 static_assert(test());118 119 return 0;120}121