blob: 997614064e2f1931259a341bd0940767d0c59437 [file] [log] [blame]
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -07001// Part of the Crubit project, under the Apache License v2.0 with LLVM
2// Exceptions. See /LICENSE for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_H_
6#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_H_
7
Devin Jeanpierre56413252022-06-02 18:48:24 -07008#pragma clang lifetime_elision
9
Devin Jeanpierrecc61dad2022-07-19 01:40:09 -070010struct DifferentScope final {};
Rosica Dejanovskaf9787c92022-06-22 12:14:57 -070011
12namespace test_namespace_bindings {
13
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -070014template <typename T>
Devin Jeanpierrecc61dad2022-07-19 01:40:09 -070015class MyTemplate final {
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -070016 public:
17 static MyTemplate Create(T value) {
18 MyTemplate result;
19 result.value_ = value;
20 return result;
21 }
22
23 const T& value() const { return value_; }
24
25 private:
26 T value_;
27};
28
29using MyTypeAlias = MyTemplate<int>;
30using OtherTypeAliasInSameTarget = MyTemplate<int>;
31
Devin Jeanpierrecc61dad2022-07-19 01:40:09 -070032struct TemplateParam final {};
Rosica Dejanovskaf9787c92022-06-22 12:14:57 -070033using TemplateWithStructTemplateParam = MyTemplate<TemplateParam>;
34using ParamFromDifferentScope = MyTemplate<DifferentScope>;
35
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -070036template <typename T1, typename T2>
Devin Jeanpierrecc61dad2022-07-19 01:40:09 -070037struct TemplateWithTwoParams final {
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -070038 T1 value1;
39 T2 value2;
40};
41
42using AliasToTemplateWithTwoParams = TemplateWithTwoParams<int, float>;
43
Rosica Dejanovskaf9787c92022-06-22 12:14:57 -070044using AliasToTemplateOfATemplate =
45 TemplateWithTwoParams<TemplateWithTwoParams<int, int>, int>;
46
Rosica Dejanovskad9d2f392022-08-24 05:31:13 -070047template <typename T>
48struct MyStruct {
49 T t;
50};
51
Marcel Hlopkoeecc2852022-09-08 06:30:51 -070052// Explicit class template specialization with definition should not be imported
53// unless also instantiated.
Marcel Hlopkoeecc2852022-09-08 06:30:51 -070054template <>
55struct MyStruct<bool> {};
56
57// Explicit class template specialization with definition should be imported
58// even when not instantiated if there is a type alias for it.
Rosica Dejanovskad9d2f392022-08-24 05:31:13 -070059template <>
60struct MyStruct<char> {};
Marcel Hlopkoeecc2852022-09-08 06:30:51 -070061using MyCharStruct = MyStruct<char>;
62
63// Forward declared explicit class template specialization should be imported
64// so the forward declaration code is generated (`forward_declare!`).
65template <>
66struct MyStruct<int>;
67
68// Explicit class template instantiation definition is imported similarly to
69// how implicit typedeffed instantiations are.
70template class MyStruct<float>;
71
72// Explicit class template instantiation declaration is not handled (yet?)
73// TODO(b/245467707): Consider handling these as a build speed/ergonomic
74// optimization.
75extern template class MyStruct<double>;
Rosica Dejanovskad9d2f392022-08-24 05:31:13 -070076
Rosica Dejanovskaf9787c92022-06-22 12:14:57 -070077} // namespace test_namespace_bindings
78
79template <typename T>
Devin Jeanpierrecc61dad2022-07-19 01:40:09 -070080struct MyTopLevelTemplate final {
Rosica Dejanovskaf9787c92022-06-22 12:14:57 -070081 T value;
82};
83
84using TopLevelTemplateWithNonTopLevelParam =
85 MyTopLevelTemplate<test_namespace_bindings::TemplateParam>;
86
Rosica Dejanovskae12d7172022-06-22 12:20:17 -070087template <>
88struct MyTopLevelTemplate<int>;
89
90void processForwardDeclaredSpecialization(MyTopLevelTemplate<int>* i);
91
Lukasz Anforowicz6d1aadf2022-08-31 09:04:35 -070092namespace template_template_params {
93
94template <typename TPolicyType>
95struct Policy {
96 static constexpr TPolicyType policy = TPolicyType();
97};
98
99template <>
100struct Policy<int> {
101 static constexpr int policy = 42;
102};
103
104template <template <class> class TPolicy>
105class MyTemplate {
106 public:
107 static int GetPolicy() { return TPolicy<int>::policy; }
108};
109
110using MyTypeAlias = MyTemplate<Policy>;
111
112} // namespace template_template_params
113
Lukasz Anforowiczf6c8b4d2022-09-01 06:58:17 -0700114// This namespace is a regression test for b/244227110 that is based on
Lukasz Anforowicz42ab93b2022-08-31 11:17:59 -0700115// `<iosfwd>`:
116// - `ForwardDeclaredTemplate` corresponds roughly to the `basic_ios` class
117// template.
118// - `TypeAliasToForwardDeclaredTemplate` corresponds toughtly to the
119// `typedef basic_ios<char> ios` type alias.
Lukasz Anforowiczf6c8b4d2022-09-01 06:58:17 -0700120namespace forward_declared_template {
Lukasz Anforowicz42ab93b2022-08-31 11:17:59 -0700121
122template <typename T>
123class ForwardDeclaredTemplate;
124
125using TypeAliasToForwardDeclaredTemplate = ForwardDeclaredTemplate<int>;
126
127} // namespace forward_declared_template
128
Devin Jeanpierre42238592022-10-04 20:27:44 -0700129namespace private_classes {
130
131class HasPrivateType {
132 private:
133 struct PrivateType {
134 using Foo = test_namespace_bindings::MyTemplate<PrivateType>;
135 Foo* get();
136 };
137
138 protected:
139 HasPrivateType(test_namespace_bindings::MyTemplate<PrivateType> x) {}
140};
141} // namespace private_classes
142
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -0700143#endif // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_H_