parameter_pack.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_PARAMETER_PACK_H_
  5. #define BASE_PARAMETER_PACK_H_
  6. #include <stddef.h>
  7. #include <initializer_list>
  8. #include <tuple>
  9. #include <type_traits>
  10. namespace base {
  11. // Checks if any of the elements in |ilist| is true.
  12. // Similar to std::any_of for the case of constexpr initializer_list.
  13. inline constexpr bool any_of(std::initializer_list<bool> ilist) {
  14. for (auto c : ilist) {
  15. if (c)
  16. return true;
  17. }
  18. return false;
  19. }
  20. // Checks if all of the elements in |ilist| are true.
  21. // Similar to std::all_of for the case of constexpr initializer_list.
  22. inline constexpr bool all_of(std::initializer_list<bool> ilist) {
  23. for (auto c : ilist) {
  24. if (!c)
  25. return false;
  26. }
  27. return true;
  28. }
  29. // Counts the elements in |ilist| that are equal to |value|.
  30. // Similar to std::count for the case of constexpr initializer_list.
  31. template <class T>
  32. inline constexpr size_t count(std::initializer_list<T> ilist, T value) {
  33. size_t c = 0;
  34. for (const auto& v : ilist) {
  35. c += (v == value);
  36. }
  37. return c;
  38. }
  39. constexpr size_t pack_npos = static_cast<size_t>(-1);
  40. template <typename... Ts>
  41. struct ParameterPack {
  42. // Checks if |Type| occurs in the parameter pack.
  43. template <typename Type>
  44. using HasType =
  45. std::bool_constant<any_of({std::is_same<Type, Ts>::value...})>;
  46. // Checks if the parameter pack only contains |Type|.
  47. template <typename Type>
  48. using OnlyHasType =
  49. std::bool_constant<all_of({std::is_same<Type, Ts>::value...})>;
  50. // Checks if |Type| occurs only once in the parameter pack.
  51. template <typename Type>
  52. using IsUniqueInPack =
  53. std::bool_constant<count({std::is_same<Type, Ts>::value...}, true) == 1>;
  54. // Returns the zero-based index of |Type| within |Pack...| or |pack_npos| if
  55. // it's not within the pack.
  56. template <typename Type>
  57. static constexpr size_t IndexInPack() {
  58. size_t index = 0;
  59. for (bool value : {std::is_same<Type, Ts>::value...}) {
  60. if (value)
  61. return index;
  62. index++;
  63. }
  64. return pack_npos;
  65. }
  66. // Helper for extracting the Nth type from a parameter pack.
  67. template <size_t N>
  68. using NthType = std::tuple_element_t<N, std::tuple<Ts...>>;
  69. // Checks if every type in the parameter pack is the same.
  70. using IsAllSameType =
  71. std::bool_constant<all_of({std::is_same<NthType<0>, Ts>::value...})>;
  72. };
  73. } // namespace base
  74. #endif // BASE_PARAMETER_PACK_H_