xref: /llvm-project/clang/test/Modules/recursive-instantiations.cppm (revision 20e904950967c125abc1e91f57e5a373987ff016)
1// RUN: rm -rf %t
2// RUN: mkdir -p %t
3// RUN: split-file %s %t
4//
5// RUN: %clang_cc1 -std=c++20 %t/type_traits.cppm -emit-module-interface -o %t/type_traits.pcm
6// RUN: %clang_cc1 -std=c++20 %t/test.cpp -fprebuilt-module-path=%t -verify
7
8//--- type_traits.cppm
9export module type_traits;
10
11export template <typename T>
12constexpr bool is_pod_v = __is_pod(T);
13
14//--- test.cpp
15// expected-no-diagnostics
16import type_traits;
17// Base is either void or wrapper<T>.
18template <class Base> struct wrapper : Base {};
19template <> struct wrapper<void> {};
20
21// wrap<0>::type<T> is wrapper<T>, wrap<1>::type<T> is wrapper<wrapper<T>>,
22// and so on.
23template <int N>
24struct wrap {
25  template <class Base>
26  using type = wrapper<typename wrap<N-1>::template type<Base>>;
27};
28
29template <>
30struct wrap<0> {
31  template <class Base>
32  using type = wrapper<Base>;
33};
34
35inline constexpr int kMaxRank = 40;
36template <int N, class Base = void>
37using rank = typename wrap<N>::template type<Base>;
38using rank_selector_t = rank<kMaxRank>;
39
40static_assert(is_pod_v<rank_selector_t>, "Must be POD");
41