aboutsummaryrefslogtreecommitdiff
path: root/tests/src/hash.cpp
blob: 94f252f8418631cdf16a47bdfdf80e3505cf8842 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "newtype/newtype.hpp"

#include <catch2/catch_template_test_macros.hpp>
#include <catch2/catch_test_macros.hpp>

#include <string>
#include <unordered_map>

TEMPLATE_TEST_CASE("Hash", "[hash]", std::string, int)
{
  GIVEN("A new_type not deriving nt::Hash")
  {
    using type_alias = nt::new_type<TestType, struct tag>;
    static_assert(nt::concepts::hashable<typename type_alias::base_type>);

    THEN("it is not hashable")
    {
      STATIC_REQUIRE_FALSE(nt::concepts::hashable<type_alias>);
    }
  }

  GIVEN("A new_type over a hashable type deriving nt::Hash")
  {
    using type_alias = nt::new_type<TestType, struct tag, deriving(nt::Hash)>;
    static_assert(nt::concepts::hashable<typename type_alias::base_type>);

    THEN("it is hashable")
    {
      STATIC_REQUIRE(nt::concepts::hashable<type_alias>);
    }
  }

  GIVEN("A new_type over a non-hashable type deriving nt::Hash")
  {
    struct non_hashable
    {
    };
    using type_alias = nt::new_type<non_hashable, struct tag, deriving(nt::Hash)>;
    static_assert(!nt::concepts::hashable<typename type_alias::base_type>);

    THEN("it is not hashable")
    {
      STATIC_REQUIRE_FALSE(nt::concepts::hashable<type_alias>);
    }
  }

  GIVEN("A hashable new_type")
  {
    using type_alias = nt::new_type<int, struct tag, deriving(nt::Hash)>;
    static_assert(nt::concepts::hashable<typename type_alias::base_type>);

    THEN("it can be used a the key in an unordered_map")
    {
      auto map = std::unordered_map<type_alias, int>{};
      map[type_alias{42}] = 43;
      REQUIRE(map[type_alias{42}] == 43);
    }
  }
}