Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 1 | // Copyright 2020 The Tint Authors. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | #include "src/tint/traits.h" |
| 16 | |
| 17 | #include "gtest/gtest.h" |
| 18 | |
dan sinclair | 8155b9d | 2022-04-07 19:10:25 +0000 | [diff] [blame] | 19 | namespace tint::traits { |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 20 | |
| 21 | namespace { |
Ben Clayton | 2cdf134 | 2023-02-03 13:24:18 +0000 | [diff] [blame] | 22 | |
| 23 | static_assert(std::is_same_v<PtrElTy<int*>, int>); |
| 24 | static_assert(std::is_same_v<PtrElTy<int const*>, int>); |
| 25 | static_assert(std::is_same_v<PtrElTy<int const* const>, int>); |
| 26 | static_assert(std::is_same_v<PtrElTy<int const* const volatile>, int>); |
| 27 | static_assert(std::is_same_v<PtrElTy<int>, int>); |
| 28 | static_assert(std::is_same_v<PtrElTy<int const>, int>); |
| 29 | static_assert(std::is_same_v<PtrElTy<int const volatile>, int>); |
| 30 | |
| 31 | static_assert(IsStringLike<std::string>); |
| 32 | static_assert(IsStringLike<std::string_view>); |
| 33 | static_assert(IsStringLike<const char*>); |
| 34 | static_assert(IsStringLike<const std::string&>); |
| 35 | static_assert(IsStringLike<const std::string_view&>); |
| 36 | static_assert(IsStringLike<const char*>); |
| 37 | static_assert(!IsStringLike<bool>); |
| 38 | static_assert(!IsStringLike<int>); |
| 39 | static_assert(!IsStringLike<const char**>); |
| 40 | |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 41 | struct S {}; |
| 42 | void F1(S) {} |
| 43 | void F3(int, S, float) {} |
| 44 | } // namespace |
| 45 | |
| 46 | TEST(ParamType, Function) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 47 | F1({}); // Avoid unused method warning |
| 48 | F3(0, {}, 0); // Avoid unused method warning |
| 49 | static_assert(std::is_same_v<ParameterType<decltype(&F1), 0>, S>); |
| 50 | static_assert(std::is_same_v<ParameterType<decltype(&F3), 0>, int>); |
| 51 | static_assert(std::is_same_v<ParameterType<decltype(&F3), 1>, S>); |
| 52 | static_assert(std::is_same_v<ParameterType<decltype(&F3), 2>, float>); |
| 53 | static_assert(std::is_same_v<ReturnType<decltype(&F1)>, void>); |
| 54 | static_assert(std::is_same_v<ReturnType<decltype(&F3)>, void>); |
| 55 | static_assert(SignatureOfT<decltype(&F1)>::parameter_count == 1); |
| 56 | static_assert(SignatureOfT<decltype(&F3)>::parameter_count == 3); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | TEST(ParamType, Method) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 60 | class C { |
| 61 | public: |
| 62 | void F1(S) {} |
| 63 | void F3(int, S, float) {} |
| 64 | }; |
| 65 | C().F1({}); // Avoid unused method warning |
| 66 | C().F3(0, {}, 0); // Avoid unused method warning |
| 67 | static_assert(std::is_same_v<ParameterType<decltype(&C::F1), 0>, S>); |
| 68 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 0>, int>); |
| 69 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 1>, S>); |
| 70 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 2>, float>); |
| 71 | static_assert(std::is_same_v<ReturnType<decltype(&C::F1)>, void>); |
| 72 | static_assert(std::is_same_v<ReturnType<decltype(&C::F3)>, void>); |
| 73 | static_assert(SignatureOfT<decltype(&C::F1)>::parameter_count == 1); |
| 74 | static_assert(SignatureOfT<decltype(&C::F3)>::parameter_count == 3); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | TEST(ParamType, ConstMethod) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 78 | class C { |
| 79 | public: |
| 80 | void F1(S) const {} |
| 81 | void F3(int, S, float) const {} |
| 82 | }; |
| 83 | C().F1({}); // Avoid unused method warning |
| 84 | C().F3(0, {}, 0); // Avoid unused method warning |
| 85 | static_assert(std::is_same_v<ParameterType<decltype(&C::F1), 0>, S>); |
| 86 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 0>, int>); |
| 87 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 1>, S>); |
| 88 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 2>, float>); |
| 89 | static_assert(std::is_same_v<ReturnType<decltype(&C::F1)>, void>); |
| 90 | static_assert(std::is_same_v<ReturnType<decltype(&C::F3)>, void>); |
| 91 | static_assert(SignatureOfT<decltype(&C::F1)>::parameter_count == 1); |
| 92 | static_assert(SignatureOfT<decltype(&C::F3)>::parameter_count == 3); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | TEST(ParamType, StaticMethod) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 96 | class C { |
| 97 | public: |
| 98 | static void F1(S) {} |
| 99 | static void F3(int, S, float) {} |
| 100 | }; |
| 101 | C::F1({}); // Avoid unused method warning |
| 102 | C::F3(0, {}, 0); // Avoid unused method warning |
| 103 | static_assert(std::is_same_v<ParameterType<decltype(&C::F1), 0>, S>); |
| 104 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 0>, int>); |
| 105 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 1>, S>); |
| 106 | static_assert(std::is_same_v<ParameterType<decltype(&C::F3), 2>, float>); |
| 107 | static_assert(std::is_same_v<ReturnType<decltype(&C::F1)>, void>); |
| 108 | static_assert(std::is_same_v<ReturnType<decltype(&C::F3)>, void>); |
| 109 | static_assert(SignatureOfT<decltype(&C::F1)>::parameter_count == 1); |
| 110 | static_assert(SignatureOfT<decltype(&C::F3)>::parameter_count == 3); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | TEST(ParamType, FunctionLike) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 114 | using F1 = std::function<void(S)>; |
| 115 | using F3 = std::function<void(int, S, float)>; |
| 116 | static_assert(std::is_same_v<ParameterType<F1, 0>, S>); |
| 117 | static_assert(std::is_same_v<ParameterType<F3, 0>, int>); |
| 118 | static_assert(std::is_same_v<ParameterType<F3, 1>, S>); |
| 119 | static_assert(std::is_same_v<ParameterType<F3, 2>, float>); |
| 120 | static_assert(std::is_same_v<ReturnType<F1>, void>); |
| 121 | static_assert(std::is_same_v<ReturnType<F3>, void>); |
| 122 | static_assert(SignatureOfT<F1>::parameter_count == 1); |
| 123 | static_assert(SignatureOfT<F3>::parameter_count == 3); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 124 | } |
| 125 | |
| 126 | TEST(ParamType, Lambda) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 127 | auto l1 = [](S) {}; |
| 128 | auto l3 = [](int, S, float) {}; |
| 129 | static_assert(std::is_same_v<ParameterType<decltype(l1), 0>, S>); |
| 130 | static_assert(std::is_same_v<ParameterType<decltype(l3), 0>, int>); |
| 131 | static_assert(std::is_same_v<ParameterType<decltype(l3), 1>, S>); |
| 132 | static_assert(std::is_same_v<ParameterType<decltype(l3), 2>, float>); |
| 133 | static_assert(std::is_same_v<ReturnType<decltype(l1)>, void>); |
| 134 | static_assert(std::is_same_v<ReturnType<decltype(l3)>, void>); |
| 135 | static_assert(SignatureOfT<decltype(l1)>::parameter_count == 1); |
| 136 | static_assert(SignatureOfT<decltype(l3)>::parameter_count == 3); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | TEST(Slice, Empty) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 140 | auto sliced = Slice<0, 0>(std::make_tuple<>()); |
| 141 | static_assert(std::tuple_size_v<decltype(sliced)> == 0); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | TEST(Slice, SingleElementSliceEmpty) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 145 | auto sliced = Slice<0, 0>(std::make_tuple<int>(1)); |
| 146 | static_assert(std::tuple_size_v<decltype(sliced)> == 0); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 147 | } |
| 148 | |
| 149 | TEST(Slice, SingleElementSliceFull) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 150 | auto sliced = Slice<0, 1>(std::make_tuple<int>(1)); |
| 151 | static_assert(std::tuple_size_v<decltype(sliced)> == 1); |
| 152 | static_assert(std::is_same_v<std::tuple_element_t<0, decltype(sliced)>, int>, ""); |
| 153 | EXPECT_EQ(std::get<0>(sliced), 1); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | TEST(Slice, MixedTupleSliceEmpty) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 157 | auto sliced = Slice<1, 0>(std::make_tuple<int, bool, float>(1, true, 2.0f)); |
| 158 | static_assert(std::tuple_size_v<decltype(sliced)> == 0); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | TEST(Slice, MixedTupleSliceFull) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 162 | auto sliced = Slice<0, 3>(std::make_tuple<int, bool, float>(1, true, 2.0f)); |
| 163 | static_assert(std::tuple_size_v<decltype(sliced)> == 3); |
| 164 | static_assert(std::is_same_v<std::tuple_element_t<0, decltype(sliced)>, int>, ""); |
| 165 | static_assert(std::is_same_v<std::tuple_element_t<1, decltype(sliced)>, bool>, ""); |
| 166 | static_assert(std::is_same_v<std::tuple_element_t<2, decltype(sliced)>, float>); |
| 167 | EXPECT_EQ(std::get<0>(sliced), 1); |
| 168 | EXPECT_EQ(std::get<1>(sliced), true); |
| 169 | EXPECT_EQ(std::get<2>(sliced), 2.0f); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 170 | } |
| 171 | |
| 172 | TEST(Slice, MixedTupleSliceLowPart) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 173 | auto sliced = Slice<0, 2>(std::make_tuple<int, bool, float>(1, true, 2.0f)); |
| 174 | static_assert(std::tuple_size_v<decltype(sliced)> == 2); |
| 175 | static_assert(std::is_same_v<std::tuple_element_t<0, decltype(sliced)>, int>, ""); |
| 176 | static_assert(std::is_same_v<std::tuple_element_t<1, decltype(sliced)>, bool>, ""); |
| 177 | EXPECT_EQ(std::get<0>(sliced), 1); |
| 178 | EXPECT_EQ(std::get<1>(sliced), true); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 179 | } |
| 180 | |
| 181 | TEST(Slice, MixedTupleSliceHighPart) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 182 | auto sliced = Slice<1, 2>(std::make_tuple<int, bool, float>(1, true, 2.0f)); |
| 183 | static_assert(std::tuple_size_v<decltype(sliced)> == 2); |
| 184 | static_assert(std::is_same_v<std::tuple_element_t<0, decltype(sliced)>, bool>, ""); |
| 185 | static_assert(std::is_same_v<std::tuple_element_t<1, decltype(sliced)>, float>); |
| 186 | EXPECT_EQ(std::get<0>(sliced), true); |
| 187 | EXPECT_EQ(std::get<1>(sliced), 2.0f); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 188 | } |
| 189 | |
| 190 | TEST(Slice, PreservesRValueRef) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 191 | int i; |
| 192 | int& int_ref = i; |
| 193 | auto tuple = std::forward_as_tuple(std::move(int_ref)); |
| 194 | static_assert(std::is_same_v<int&&, // |
| 195 | std::tuple_element_t<0, decltype(tuple)>>); |
| 196 | auto sliced = Slice<0, 1>(std::move(tuple)); |
| 197 | static_assert(std::is_same_v<int&&, // |
| 198 | std::tuple_element_t<0, decltype(sliced)>>); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 199 | } |
| 200 | |
| 201 | TEST(SliceTuple, Empty) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 202 | using sliced = SliceTuple<0, 0, std::tuple<>>; |
| 203 | static_assert(std::tuple_size_v<sliced> == 0); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 204 | } |
| 205 | |
| 206 | TEST(SliceTuple, SingleElementSliceEmpty) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 207 | using sliced = SliceTuple<0, 0, std::tuple<int>>; |
| 208 | static_assert(std::tuple_size_v<sliced> == 0); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 209 | } |
| 210 | |
| 211 | TEST(SliceTuple, SingleElementSliceFull) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 212 | using sliced = SliceTuple<0, 1, std::tuple<int>>; |
| 213 | static_assert(std::tuple_size_v<sliced> == 1); |
| 214 | static_assert(std::is_same_v<std::tuple_element_t<0, sliced>, int>); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 215 | } |
| 216 | |
| 217 | TEST(SliceTuple, MixedTupleSliceEmpty) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 218 | using sliced = SliceTuple<1, 0, std::tuple<int, bool, float>>; |
| 219 | static_assert(std::tuple_size_v<sliced> == 0); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 220 | } |
| 221 | |
| 222 | TEST(SliceTuple, MixedTupleSliceFull) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 223 | using sliced = SliceTuple<0, 3, std::tuple<int, bool, float>>; |
| 224 | static_assert(std::tuple_size_v<sliced> == 3); |
| 225 | static_assert(std::is_same_v<std::tuple_element_t<0, sliced>, int>); |
| 226 | static_assert(std::is_same_v<std::tuple_element_t<1, sliced>, bool>); |
| 227 | static_assert(std::is_same_v<std::tuple_element_t<2, sliced>, float>); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 228 | } |
| 229 | |
| 230 | TEST(SliceTuple, MixedTupleSliceLowPart) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 231 | using sliced = SliceTuple<0, 2, std::tuple<int, bool, float>>; |
| 232 | static_assert(std::tuple_size_v<sliced> == 2); |
| 233 | static_assert(std::is_same_v<std::tuple_element_t<0, sliced>, int>); |
| 234 | static_assert(std::is_same_v<std::tuple_element_t<1, sliced>, bool>); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 235 | } |
| 236 | |
| 237 | TEST(SliceTuple, MixedTupleSliceHighPart) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 238 | using sliced = SliceTuple<1, 2, std::tuple<int, bool, float>>; |
| 239 | static_assert(std::tuple_size_v<sliced> == 2); |
| 240 | static_assert(std::is_same_v<std::tuple_element_t<0, sliced>, bool>); |
| 241 | static_assert(std::is_same_v<std::tuple_element_t<1, sliced>, float>); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 242 | } |
| 243 | |
dan sinclair | 8155b9d | 2022-04-07 19:10:25 +0000 | [diff] [blame] | 244 | } // namespace tint::traits |