Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

61 wiersze
1.8 KiB

  1. #pragma once
  2. #include <cpputils/mp/operations/hash.h>
  3. #include <cpputils/mp/operations/compare/equal.h>
  4. namespace utl {
  5. namespace mp {
  6. namespace intern {
  7. namespace __impl
  8. {
  9. template<typename H, size_t... I>
  10. struct bucket { };
  11. template<typename... Buckets>
  12. struct hash_table
  13. : Buckets...
  14. { };
  15. /* find indices */
  16. template<typename Hash, size_t... I>
  17. std::index_sequence<I...> find_indices_impl(const bucket<Hash, I...>&);
  18. template<typename Hash>
  19. std::index_sequence<> find_indices_impl(...);
  20. /* find index */
  21. template<template<size_t> class KeyAtIndex, typename Key>
  22. struct find_pred
  23. {
  24. template<typename Index>
  25. auto operator()(const Index&) const ->
  26. decltype(equal(std::declval<KeyAtIndex<Index::value>>(), std::declval<Key>()));
  27. };
  28. template<typename Indices, typename Key, template<size_t> class KeyAtIndex>
  29. struct find_index_impl
  30. { using type = decltype(find_if(Indices { }, find_pred<KeyAtIndex, Key> { })); };
  31. }
  32. template<typename Map, typename Key>
  33. struct find_indices
  34. {
  35. using hash = typename decltype(hash(std::declval<Key>()))::type;
  36. using type = decltype(__impl::find_indices_impl<hash>(std::declval<Map>()));
  37. };
  38. template<template<size_t> class KeyAtIndex, size_t N, typename Indices = std::make_index_sequence<N>>
  39. struct make_hash_table;
  40. template<template<size_t> class KeyAtIndex, size_t N, size_t... I>
  41. struct make_hash_table<KeyAtIndex, N, std::index_sequence<I...>>
  42. {
  43. using type = __impl::hash_table<
  44. __impl::bucket<typename decltype(hash(std::declval<KeyAtIndex<I>>()))::type, I>...
  45. >;
  46. };
  47. }
  48. }
  49. }