parameter_pack.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. #include "base/template_util.h"
  11. #include "build/build_config.h"
  12. namespace base {
  13. // Checks if any of the elements in |ilist| is true.
  14. // Similar to std::any_of for the case of constexpr initializer_list.
  15. inline constexpr bool any_of(std::initializer_list<bool> ilist) {
  16. for (auto c : ilist) {
  17. if (c)
  18. return true;
  19. }
  20. return false;
  21. }
  22. // Checks if all of the elements in |ilist| are true.
  23. // Similar to std::all_of for the case of constexpr initializer_list.
  24. inline constexpr bool all_of(std::initializer_list<bool> ilist) {
  25. for (auto c : ilist) {
  26. if (!c)
  27. return false;
  28. }
  29. return true;
  30. }
  31. // Counts the elements in |ilist| that are equal to |value|.
  32. // Similar to std::count for the case of constexpr initializer_list.
  33. template <class T>
  34. inline constexpr size_t count(std::initializer_list<T> ilist, T value) {
  35. size_t c = 0;
  36. for (const auto& v : ilist) {
  37. c += (v == value);
  38. }
  39. return c;
  40. }
  41. constexpr size_t pack_npos = -1;
  42. template <typename... Ts>
  43. struct ParameterPack {
  44. // Checks if |Type| occurs in the parameter pack.
  45. template <typename Type>
  46. using HasType = bool_constant<any_of({std::is_same<Type, Ts>::value...})>;
  47. // Checks if the parameter pack only contains |Type|.
  48. template <typename Type>
  49. using OnlyHasType = 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. 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. bool_constant<all_of({std::is_same<NthType<0>, Ts>::value...})>;
  72. };
  73. } // namespace base
  74. #endif // BASE_PARAMETER_PACK_H_