xref: /aosp_15_r20/external/tink/cc/core/template_util.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2019 Google LLC
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 ///////////////////////////////////////////////////////////////////////////////
16 #ifndef TINK_CORE_TEMPLATE_UTIL_H_
17 #define TINK_CORE_TEMPLATE_UTIL_H_
18 
19 #include <cstddef>
20 #include <tuple>
21 #include <type_traits>
22 
23 #include "absl/meta/type_traits.h"
24 
25 namespace crypto {
26 namespace tink {
27 
28 // A list of types
29 template <typename... P>
30 struct List {};
31 
32 namespace internal {
33 
34 // A helper class template which decides if the TestType occurs in the Tuple
35 // For example, OccursInTuple<int, std::tuple<float, float>>::value == false,
36 // and OccursInTuple<int, std::tuple<float, int>>::value == true. Not intended
37 // to be used directly.
38 
39 // First declare the template which always takes two parameters.
40 template <typename TestType, typename Tuple>
41 class OccursInTuple;
42 
43 // In the special case where the tuple is empty, the result is false.
44 template <typename TestType>
45 class OccursInTuple<TestType, std::tuple<>> : public std::false_type {};
46 
47 // If the list is not empty, the result is true if TestType equals the first in
48 // the list, or  TestType occurs in the rest of the list.
49 template <typename TestType, typename First, typename... List>
50 class OccursInTuple<TestType, std::tuple<First, List...>>
51     : public absl::disjunction<
52           std::is_same<TestType, First>,
53           OccursInTuple<TestType, typename std::tuple<List...>>> {};
54 
55 // The class HasDuplicates. Defines ::value as true in case the given list has
56 // a duplicate, false otherwise.
57 template <typename... Args>
58 class HasDuplicates;
59 
60 // Empty list has no duplicates.
61 template <>
62 class HasDuplicates<> : public std::false_type {};
63 
64 // Non-empty list has a duplicate if the first appears in the rest, or if the
65 // rest has a duplicate.
66 template <typename First, typename... List>
67 class HasDuplicates<First, List...>
68     : public absl::disjunction<
69           OccursInTuple<First, typename std::tuple<List...>>,
70           HasDuplicates<List...>> {};
71 
72 // The class IndexOf. Defines ::value as zero-based index of first element of
73 // type T in the List.
74 template <typename T, typename List>
75 struct IndexOf;
76 template <typename T, typename... Elements>
77 struct IndexOf<T, List<T, Elements...>>
78     : public std::integral_constant<std::size_t, 0> {};
79 template <typename T, typename E, typename... Elements>
80 struct IndexOf<T, List<E, Elements...>>
81     : public std::integral_constant<std::size_t,
82                                     1 + IndexOf<T, List<Elements...>>::value> {
83 };
84 
85 }  // namespace internal
86 }  // namespace tink
87 }  // namespace crypto
88 
89 #endif  // TINK_CORE_TEMPLATE_UTIL_H_
90