Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef BASE_PARAMETER_PACK_H_ |
| 6 | #define BASE_PARAMETER_PACK_H_ |
| 7 | |
Jan Wilken Dörrie | a33bc99 | 2020-03-24 17:45:31 | [diff] [blame] | 8 | #include <stddef.h> |
| 9 | |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 10 | #include <initializer_list> |
Jan Wilken Dörrie | a33bc99 | 2020-03-24 17:45:31 | [diff] [blame] | 11 | #include <tuple> |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 12 | #include <type_traits> |
| 13 | |
Peter Kasting | 0909bd19 | 2022-09-01 21:39:04 | [diff] [blame] | 14 | #include "base/containers/contains.h" |
| 15 | |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 16 | namespace base { |
| 17 | |
| 18 | // Checks if any of the elements in |ilist| is true. |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 19 | inline constexpr bool any_of(std::initializer_list<bool> ilist) { |
Peter Kasting | 0909bd19 | 2022-09-01 21:39:04 | [diff] [blame] | 20 | return base::Contains(ilist, true); |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 21 | } |
| 22 | |
| 23 | // Checks if all of the elements in |ilist| are true. |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 24 | inline constexpr bool all_of(std::initializer_list<bool> ilist) { |
Peter Kasting | 0909bd19 | 2022-09-01 21:39:04 | [diff] [blame] | 25 | return !base::Contains(ilist, false); |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 26 | } |
| 27 | |
| 28 | // Counts the elements in |ilist| that are equal to |value|. |
| 29 | // Similar to std::count for the case of constexpr initializer_list. |
| 30 | template <class T> |
| 31 | inline constexpr size_t count(std::initializer_list<T> ilist, T value) { |
| 32 | size_t c = 0; |
| 33 | for (const auto& v : ilist) { |
| 34 | c += (v == value); |
| 35 | } |
| 36 | return c; |
| 37 | } |
| 38 | |
Peter Kasting | de85e74 | 2022-06-01 17:41:54 | [diff] [blame] | 39 | constexpr size_t pack_npos = static_cast<size_t>(-1); |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 40 | |
| 41 | template <typename... Ts> |
| 42 | struct ParameterPack { |
| 43 | // Checks if |Type| occurs in the parameter pack. |
| 44 | template <typename Type> |
Andrew Rayskiy | 62991238 | 2023-10-18 22:58:42 | [diff] [blame] | 45 | using HasType = std::bool_constant<any_of({std::is_same_v<Type, Ts>...})>; |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 46 | |
| 47 | // Checks if the parameter pack only contains |Type|. |
| 48 | template <typename Type> |
Andrew Rayskiy | 62991238 | 2023-10-18 22:58:42 | [diff] [blame] | 49 | using OnlyHasType = std::bool_constant<all_of({std::is_same_v<Type, Ts>...})>; |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 50 | |
| 51 | // Checks if |Type| occurs only once in the parameter pack. |
| 52 | template <typename Type> |
Jan Wilken Dörrie | a33bc99 | 2020-03-24 17:45:31 | [diff] [blame] | 53 | using IsUniqueInPack = |
Andrew Rayskiy | 62991238 | 2023-10-18 22:58:42 | [diff] [blame] | 54 | std::bool_constant<count({std::is_same_v<Type, Ts>...}, true) == 1>; |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 55 | |
| 56 | // Returns the zero-based index of |Type| within |Pack...| or |pack_npos| if |
| 57 | // it's not within the pack. |
| 58 | template <typename Type> |
| 59 | static constexpr size_t IndexInPack() { |
| 60 | size_t index = 0; |
Andrew Rayskiy | 62991238 | 2023-10-18 22:58:42 | [diff] [blame] | 61 | for (bool value : {std::is_same_v<Type, Ts>...}) { |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 62 | if (value) { |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 63 | return index; |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 64 | } |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 65 | index++; |
| 66 | } |
| 67 | return pack_npos; |
| 68 | } |
| 69 | |
| 70 | // Helper for extracting the Nth type from a parameter pack. |
| 71 | template <size_t N> |
Jan Wilken Dörrie | a33bc99 | 2020-03-24 17:45:31 | [diff] [blame] | 72 | using NthType = std::tuple_element_t<N, std::tuple<Ts...>>; |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 73 | |
| 74 | // Checks if every type in the parameter pack is the same. |
Jan Wilken Dörrie | a33bc99 | 2020-03-24 17:45:31 | [diff] [blame] | 75 | using IsAllSameType = |
Andrew Rayskiy | 62991238 | 2023-10-18 22:58:42 | [diff] [blame] | 76 | std::bool_constant<all_of({std::is_same_v<NthType<0>, Ts>...})>; |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 77 | }; |
| 78 | |
| 79 | } // namespace base |
| 80 | |
| 81 | #endif // BASE_PARAMETER_PACK_H_ |