Skip to content

Commit 5a1c3f8

Browse files
committed
add unique_ref::operators < and ==
1 parent e27fd7b commit 5a1c3f8

2 files changed

Lines changed: 90 additions & 5 deletions

File tree

src/utki/unique_ref.hpp

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,13 @@ class unique_ref
6969
* Must not be null, otherwise it causes undefined behaviour.
7070
*/
7171
explicit unique_ref(std::unique_ptr<object_type> ptr) :
72-
p(std::move(ptr)){ASSERT(this->p)}
72+
p(std::move(ptr))
73+
{
74+
utki::assert(this->p, SL);
75+
}
7376

74-
// there should be no default constructor, as unique_ref cannot be nullptr
75-
unique_ref() = delete;
77+
// there should be no default constructor, as unique_ref cannot be nullptr
78+
unique_ref() = delete;
7679

7780
unique_ref(const unique_ref&) = delete;
7881
unique_ref& operator=(const unique_ref&) = delete;
@@ -96,7 +99,7 @@ class unique_ref
9699
unique_ref(unique_ref<other_object_type>&& sr) noexcept :
97100
p(std::move(sr.p))
98101
{
99-
ASSERT(this->p)
102+
utki::assert(this->p, SL);
100103
}
101104

102105
/**
@@ -106,7 +109,7 @@ class unique_ref
106109
*/
107110
constexpr object_type& get() const noexcept
108111
{
109-
ASSERT(this->p)
112+
utki::assert(this->p, SL);
110113
return *this->p;
111114
}
112115

@@ -118,6 +121,49 @@ class unique_ref
118121
{
119122
return this->get();
120123
}
124+
125+
/**
126+
* @brief Less-than operator for comparison with another object.
127+
* Needed for using unique_ref in ordered containers (e.g. std::set).
128+
* Effecively calls opearator<() of the pointed-to object.
129+
* @return true if this object is less than the other object.
130+
* @return false otherwise.
131+
*/
132+
friend constexpr bool operator<(const unique_ref& r, const object_type& o) noexcept
133+
{
134+
return r.get() < o;
135+
}
136+
137+
/**
138+
* @brief Equality operator for comparison with another object.
139+
* Needed for using unique_ref in ordered containers (e.g. std::set).
140+
* Effectively calls operator==() of the pointed-to object.
141+
* @param r - left hand side of the operator.
142+
* @param o - right hand side of the operator.
143+
* @return true if this object is equal to the other object.
144+
* @return false otherwise.
145+
*/
146+
friend constexpr bool operator==(const unique_ref& r, const object_type& o) noexcept
147+
{
148+
return r.get() == o;
149+
}
150+
151+
/**
152+
* @brief Equality operator for comparison with another object.
153+
* Needed for using unique_ref in ordered containers (e.g. std::set).
154+
* Effectively calls operator==() of the pointed-to object.
155+
* @param l - left hand side of the operator.
156+
* @param r - right hand side of the operator.
157+
* @return true if this object is equal to the other object.
158+
* @return false otherwise.
159+
*/
160+
friend constexpr bool operator==(
161+
const unique_ref& l, //
162+
const unique_ref& r
163+
) noexcept
164+
{
165+
return l.get() == r.get();
166+
}
121167
};
122168

123169
/**

tests/unit/src/unique_ref.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include <algorithm>
2+
#include <set>
23

34
#include <tst/check.hpp>
45
#include <tst/set.hpp>
56
#include <utki/unique_ref.hpp>
7+
#include <utki/utility.hpp>
68

79
namespace {
810
const std::string etalon = "hello world!";
@@ -21,6 +23,16 @@ struct a0 {
2123
a0& operator=(a0&&) = default;
2224

2325
virtual ~a0() = default;
26+
27+
bool operator<(const a0& r) const noexcept
28+
{
29+
return this < &r;
30+
}
31+
32+
bool operator==(const a0& r) const noexcept
33+
{
34+
return this == &r;
35+
}
2436
};
2537

2638
struct a1 : public a0 {
@@ -165,5 +177,32 @@ const tst::set set("unique_ref", [](tst::suite& suite) {
165177
tst::check_eq(vec[1].get().a_0, 3, SL);
166178
tst::check_eq(vec[2].get().a_0, 1, SL);
167179
});
180+
181+
suite.add("use_with_std_set", []() {
182+
std::set<utki::unique_ref<a0>> set;
183+
184+
auto v1 = utki::make_unique<a0>(1);
185+
auto v2 = utki::make_unique<a0>(2);
186+
auto v3 = utki::make_unique<a0>(3);
187+
188+
auto& v1r = v1.get();
189+
auto& v2r = v2.get();
190+
auto& v3r = v3.get();
191+
192+
set.insert(std::move(v1));
193+
set.insert(std::move(v2));
194+
195+
tst::check_eq(set.size(), size_t(2), SL);
196+
197+
for(auto& v : set) {
198+
tst::check(v.get().a_0 == 1 || v.get().a_0 == 2, SL);
199+
}
200+
201+
tst::check(!utki::contains(set, v3), SL);
202+
203+
tst::check(utki::contains(set, v1r), SL);
204+
tst::check(utki::contains(set, v2r), SL);
205+
tst::check(!utki::contains(set, v3r), SL);
206+
});
168207
});
169208
} // namespace

0 commit comments

Comments
 (0)