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