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 | namespacebase{ |
| 17 | |
| 18 | // Checks if any of the elements in |ilist| is true. |
Alex Clarke | 8906d05 | 2019-03-13 14:58:04 | [diff] [blame] | 19 | inlineconstexprbool any_of(std::initializer_list<bool> ilist){ |
Peter Kasting | 0909bd19 | 2022-09-01 21:39:04 | [diff] [blame] | 20 | returnbase::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 | inlineconstexprbool 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 | inlineconstexprsize_t count(std::initializer_list<T> ilist, T value){ |
| 32 | size_t c=0; |
| 33 | for(constauto& v: ilist){ |
| 34 | c+=(v== value); |
| 35 | } |
| 36 | return c; |
| 37 | } |
| 38 | |
Peter Kasting | de85e74 | 2022-06-01 17:41:54 | [diff] [blame] | 39 | constexprsize_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 | structParameterPack{ |
| 43 | // Checks if |Type| occurs in the parameter pack. |
| 44 | template<typenameType> |
Andrew Rayskiy | 62991238 | 2023-10-18 22:58:42 | [diff] [blame] | 45 | usingHasType= 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<typenameType> |
Andrew Rayskiy | 62991238 | 2023-10-18 22:58:42 | [diff] [blame] | 49 | usingOnlyHasType= 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<typenameType> |
Jan Wilken Dörrie | a33bc99 | 2020-03-24 17:45:31 | [diff] [blame] | 53 | usingIsUniqueInPack= |
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<typenameType> |
| 59 | staticconstexprsize_tIndexInPack(){ |
| 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 | usingNthType= 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 | usingIsAllSameType= |
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_ |