Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

104 righe
3.0 KiB

  1. #pragma once
  2. #include <cpputils/mp/misc/when.h>
  3. #include <cpputils/mp/misc/tag_of.h>
  4. #include <cpputils/mp/misc/default.h>
  5. #include <cpputils/mp/core/const.h>
  6. #include <cpputils/mp/core/modifier.h>
  7. #include <cpputils/mp/core/conditionals.h>
  8. #include <cpputils/mp/container/type.h>
  9. #include <cpputils/mp/operations/hash.fwd.h>
  10. namespace utl {
  11. namespace mp {
  12. namespace __impl /* implementation */
  13. {
  14. template <typename T, typename = void>
  15. struct hash_integral_helper;
  16. template <typename Member, typename T>
  17. struct hash_integral_helper<Member T::*>
  18. {
  19. template <typename X>
  20. static constexpr auto apply(X const&)
  21. { return type_c<integral_constant<Member T::*, X::value>>; }
  22. };
  23. template <typename T>
  24. struct hash_integral_helper<T, enable_if<is_signed<T>>>
  25. {
  26. template <typename X>
  27. static constexpr auto apply(X const&)
  28. {
  29. constexpr signed long long x = X::value;
  30. return type_c<integral_constant<signed long long, x>>;
  31. }
  32. };
  33. template <typename T>
  34. struct hash_integral_helper<T, enable_if<is_unsigned<T>>>
  35. {
  36. template <typename X>
  37. static constexpr auto apply(X const&)
  38. {
  39. constexpr unsigned long long x = X::value;
  40. return type_c<integral_constant<unsigned long long, x>>;
  41. }
  42. };
  43. template <>
  44. struct hash_integral_helper<bool>
  45. {
  46. template <typename X>
  47. static constexpr auto apply(X const&)
  48. { return type_c<c_bool_t<X::value>>; }
  49. };
  50. template <>
  51. struct hash_integral_helper<char>
  52. {
  53. template <typename X>
  54. static constexpr auto apply(X const&)
  55. {
  56. using T = if_c<is_signed<char>::value, signed long long, unsigned long long>;
  57. constexpr T x = X::value;
  58. return type_c<integral_constant<T, x>>;
  59. }
  60. };
  61. template <typename T, typename>
  62. struct hash_impl
  63. : hash_impl<T, when<true>>
  64. { };
  65. template <typename Tag, bool condition>
  66. struct hash_impl<Tag, when<condition>>
  67. : default_
  68. {
  69. template <typename X>
  70. static constexpr auto apply(X const&) = delete;
  71. };
  72. template <typename T>
  73. struct hash_impl<tag_integral_constant<T>, when<true>>
  74. {
  75. template<typename X>
  76. static constexpr auto apply(const X& x)
  77. {
  78. using type = remove_cv<decltype(X::value)>;
  79. return hash_integral_helper<type>::apply(x);
  80. }
  81. };
  82. template<typename X>
  83. constexpr auto hash_t::operator()(const X& x) const
  84. {
  85. using tag_type = tag_of<X>;
  86. using hash_impl_type = hash_impl<tag_type>;
  87. return hash_impl_type::apply(x);
  88. }
  89. }
  90. }
  91. }