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-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11// indirect_result_t
12
13#include <iterator>
14#include <concepts>
15
16#include "test_macros.h"
17
18static_assert(std::same_as<std::indirect_result_t<int (*)(int), int*>, int>);
19static_assert(std::same_as<std::indirect_result_t<double (*)(int const&, float), int const*, float*>, double>);
20
21struct S { };
22static_assert(std::same_as<std::indirect_result_t<S (&)(int), int*>, S>);
23static_assert(std::same_as<std::indirect_result_t<long S::*, S*>, long&>);
24static_assert(std::same_as<std::indirect_result_t<S && (S::*)(), S*>, S&&>);
25static_assert(std::same_as<std::indirect_result_t<int S::* (S::*)(int) const, S*, int*>, int S::*>);
26
27template <class F, class... Is>
28constexpr bool has_indirect_result = requires {
29 typename std::indirect_result_t<F, Is...>;
30};
31
32static_assert(!has_indirect_result<int (*)(int), int>); // int isn't indirectly_readable
33static_assert(!has_indirect_result<int, int*>); // int isn't invocable
34
35// Test ADL-proofing (P2538R1)
36#if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
37// TODO: Enable this on GCC once this bug is fixed: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111419
38#ifndef TEST_COMPILER_GCC
39struct Incomplete;
40template<class T> struct Holder { T t; };
41static_assert(std::same_as<std::indirect_result_t<int (&)(int), int*>, int>);
42static_assert(std::same_as<std::indirect_result_t<Holder<Incomplete>&(&)(int), int*>, Holder<Incomplete>&>);
43static_assert(std::same_as<std::indirect_result_t<Holder<Incomplete>*(&)(int), int*>, Holder<Incomplete>*>);
44static_assert(std::same_as<std::indirect_result_t<int (&)(Holder<Incomplete>*), Holder<Incomplete>**>, int>);
45static_assert(std::same_as<std::indirect_result_t<Holder<Incomplete>&(&)(Holder<Incomplete>*), Holder<Incomplete>**>, Holder<Incomplete>&>);
46static_assert(std::same_as<std::indirect_result_t<Holder<Incomplete>*(&)(Holder<Incomplete>*), Holder<Incomplete>**>, Holder<Incomplete>*>);
47#endif
48#endif
49

source code of libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_result_t.compile.pass.cpp