blob: c0ffb58bc22e327df69c2205597455c35bd52acf [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2019 The Chromium Authors
Alex Clarke8906d052019-03-13 14:58:042// 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örriea33bc992020-03-24 17:45:318#include <stddef.h>
9
Alex Clarke8906d052019-03-13 14:58:0410#include <initializer_list>
Jan Wilken Dörriea33bc992020-03-24 17:45:3111#include <tuple>
Alex Clarke8906d052019-03-13 14:58:0412#include <type_traits>
13
Peter Kasting0909bd192022-09-01 21:39:0414#include "base/containers/contains.h"
15
Alex Clarke8906d052019-03-13 14:58:0416namespace base {
17
18// Checks if any of the elements in |ilist| is true.
Alex Clarke8906d052019-03-13 14:58:0419inline constexpr bool any_of(std::initializer_list<bool> ilist) {
Peter Kasting0909bd192022-09-01 21:39:0420 return base::Contains(ilist, true);
Alex Clarke8906d052019-03-13 14:58:0421}
22
23// Checks if all of the elements in |ilist| are true.
Alex Clarke8906d052019-03-13 14:58:0424inline constexpr bool all_of(std::initializer_list<bool> ilist) {
Peter Kasting0909bd192022-09-01 21:39:0425 return !base::Contains(ilist, false);
Alex Clarke8906d052019-03-13 14:58:0426}
27
28// Counts the elements in |ilist| that are equal to |value|.
29// Similar to std::count for the case of constexpr initializer_list.
30template <class T>
31inline 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 Kastingde85e742022-06-01 17:41:5439constexpr size_t pack_npos = static_cast<size_t>(-1);
Alex Clarke8906d052019-03-13 14:58:0440
41template <typename... Ts>
42struct ParameterPack {
43 // Checks if |Type| occurs in the parameter pack.
44 template <typename Type>
Andrew Rayskiy629912382023-10-18 22:58:4245 using HasType = std::bool_constant<any_of({std::is_same_v<Type, Ts>...})>;
Alex Clarke8906d052019-03-13 14:58:0446
47 // Checks if the parameter pack only contains |Type|.
48 template <typename Type>
Andrew Rayskiy629912382023-10-18 22:58:4249 using OnlyHasType = std::bool_constant<all_of({std::is_same_v<Type, Ts>...})>;
Alex Clarke8906d052019-03-13 14:58:0450
51 // Checks if |Type| occurs only once in the parameter pack.
52 template <typename Type>
Jan Wilken Dörriea33bc992020-03-24 17:45:3153 using IsUniqueInPack =
Andrew Rayskiy629912382023-10-18 22:58:4254 std::bool_constant<count({std::is_same_v<Type, Ts>...}, true) == 1>;
Alex Clarke8906d052019-03-13 14:58:0455
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 Rayskiy629912382023-10-18 22:58:4261 for (bool value : {std::is_same_v<Type, Ts>...}) {
Peter Kasting134ef9af2024-12-28 02:30:0962 if (value) {
Alex Clarke8906d052019-03-13 14:58:0463 return index;
Peter Kasting134ef9af2024-12-28 02:30:0964 }
Alex Clarke8906d052019-03-13 14:58:0465 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örriea33bc992020-03-24 17:45:3172 using NthType = std::tuple_element_t<N, std::tuple<Ts...>>;
Alex Clarke8906d052019-03-13 14:58:0473
74 // Checks if every type in the parameter pack is the same.
Jan Wilken Dörriea33bc992020-03-24 17:45:3175 using IsAllSameType =
Andrew Rayskiy629912382023-10-18 22:58:4276 std::bool_constant<all_of({std::is_same_v<NthType<0>, Ts>...})>;
Alex Clarke8906d052019-03-13 14:58:0477};
78
79} // namespace base
80
81#endif // BASE_PARAMETER_PACK_H_