aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/containers/flat_hash/lib/value_markers.h
blob: 99351586b50c9069d3bf2c7a846ec92bd29f4b20 (plain) (blame)
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once

#include "concepts/value_marker.h"

#include <type_traits>
#include <tuple>

namespace NFlatHash {

namespace NSet {

template <auto Value>
struct TStaticValueMarker {
    using value_type = decltype(Value);

    constexpr auto Create() const noexcept {
        return Value;
    }

    template <class U>
    bool Equals(const U& rhs) const {
        return Value == rhs;
    }
};

static_assert(NConcepts::ValueMarkerV<TStaticValueMarker<5>>);

template <class T>
class TEqValueMarker {
public:
    using value_type = T;

    template <class V, class = std::enable_if_t<std::is_constructible_v<T, std::decay_t<V>>>>
    TEqValueMarker(V&& v) : Value_(std::forward<V>(v)) {}

    TEqValueMarker(const TEqValueMarker&) = default;
    TEqValueMarker(TEqValueMarker&&) = default;

    TEqValueMarker& operator=(const TEqValueMarker&) = default;
    TEqValueMarker& operator=(TEqValueMarker&&) = default;

    const T& Create() const noexcept {
        return Value_;
    }

    template <class U>
    bool Equals(const U& rhs) const {
        return Value_ == rhs;
    }

private:
    T Value_;
};

static_assert(NConcepts::ValueMarkerV<TEqValueMarker<int>>);

}  // namespace NSet

namespace NMap {

template <auto Key, class T>
class TStaticValueMarker {
    static_assert(std::is_default_constructible_v<T>);

public:
    using value_type = std::pair<decltype(Key), T>;

    TStaticValueMarker() = default;

    TStaticValueMarker(const TStaticValueMarker&) {}
    TStaticValueMarker(TStaticValueMarker&&) {}

    TStaticValueMarker& operator=(const TStaticValueMarker&) noexcept { return *this; }
    TStaticValueMarker& operator=(TStaticValueMarker&&) noexcept { return *this; }

    std::pair<decltype(Key), const T&> Create() const noexcept { return { Key, Value_ }; }

    template <class U>
    bool Equals(const U& rhs) const {
        return Key == rhs.first;
    }

private:
    T Value_;
};

static_assert(NConcepts::ValueMarkerV<TStaticValueMarker<5, int>>);

template <class Key, class T>
class TEqValueMarker {
    static_assert(std::is_default_constructible_v<T>);

public:
    using value_type = std::pair<Key, T>;

    template <class V, class = std::enable_if_t<std::is_constructible_v<Key, std::decay_t<V>>>>
    TEqValueMarker(V&& v) : Key_(std::forward<V>(v)) {}

    TEqValueMarker(const TEqValueMarker& vm)
        : Key_(vm.Key_) {}
    TEqValueMarker(TEqValueMarker&& vm) noexcept(std::is_nothrow_move_constructible_v<Key>
                                                 && std::is_nothrow_constructible_v<T>)
        : Key_(std::move(vm.Key_)) {}

    TEqValueMarker& operator=(const TEqValueMarker& vm) {
        Key_ = vm.Key_;
        return *this;
    }
    TEqValueMarker& operator=(TEqValueMarker&& vm) noexcept(std::is_nothrow_move_assignable_v<Key>) {
        Key_ = std::move(vm.Key_);
        return *this;
    }

    auto Create() const noexcept { return std::tie(Key_, Value_); }

    template <class U>
    bool Equals(const U& rhs) const {
        return Key_ == rhs.first;
    }

private:
    Key Key_;
    T Value_;
};

static_assert(NConcepts::ValueMarkerV<TEqValueMarker<int, int>>);

}  // namespace NMap

}  // namespace NFlatHash