| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef BASE_PARAMETER_PACK_H_ |
| #define BASE_PARAMETER_PACK_H_ |
| |
| #include <stddef.h> |
| |
| #include <initializer_list> |
| #include <tuple> |
| #include <type_traits> |
| |
| #include "base/template_util.h" |
| #include "build/build_config.h" |
| |
| namespace base { |
| |
| // Checks if any of the elements in |ilist| is true. |
| // Similar to std::any_of for the case of constexpr initializer_list. |
| inline constexpr bool any_of(std::initializer_list<bool> ilist) { |
| for (auto c : ilist) { |
| if (c) |
| return true; |
| } |
| return false; |
| } |
| |
| // Checks if all of the elements in |ilist| are true. |
| // Similar to std::all_of for the case of constexpr initializer_list. |
| inline constexpr bool all_of(std::initializer_list<bool> ilist) { |
| for (auto c : ilist) { |
| if (!c) |
| return false; |
| } |
| return true; |
| } |
| |
| // Counts the elements in |ilist| that are equal to |value|. |
| // Similar to std::count for the case of constexpr initializer_list. |
| template <class T> |
| inline constexpr size_t count(std::initializer_list<T> ilist, T value) { |
| size_t c = 0; |
| for (const auto& v : ilist) { |
| c += (v == value); |
| } |
| return c; |
| } |
| |
| constexpr size_t pack_npos = -1; |
| |
| template <typename... Ts> |
| struct ParameterPack { |
| // Checks if |Type| occurs in the parameter pack. |
| template <typename Type> |
| using HasType = bool_constant<any_of({std::is_same<Type, Ts>::value...})>; |
| |
| // Checks if the parameter pack only contains |Type|. |
| template <typename Type> |
| using OnlyHasType = bool_constant<all_of({std::is_same<Type, Ts>::value...})>; |
| |
| // Checks if |Type| occurs only once in the parameter pack. |
| template <typename Type> |
| using IsUniqueInPack = |
| bool_constant<count({std::is_same<Type, Ts>::value...}, true) == 1>; |
| |
| // Returns the zero-based index of |Type| within |Pack...| or |pack_npos| if |
| // it's not within the pack. |
| template <typename Type> |
| static constexpr size_t IndexInPack() { |
| size_t index = 0; |
| for (bool value : {std::is_same<Type, Ts>::value...}) { |
| if (value) |
| return index; |
| index++; |
| } |
| return pack_npos; |
| } |
| |
| // Helper for extracting the Nth type from a parameter pack. |
| template <size_t N> |
| using NthType = std::tuple_element_t<N, std::tuple<Ts...>>; |
| |
| // Checks if every type in the parameter pack is the same. |
| using IsAllSameType = |
| bool_constant<all_of({std::is_same<NthType<0>, Ts>::value...})>; |
| }; |
| |
| } // namespace base |
| |
| #endif // BASE_PARAMETER_PACK_H_ |