Skip to content

Commit 22170b7

Browse files
committed
Add intrusive copy-on-write class
1 parent d86342e commit 22170b7

File tree

3 files changed

+87
-12
lines changed

3 files changed

+87
-12
lines changed

src/util/cow.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#pragma once
2+
3+
template <typename T> class cow final {
4+
public:
5+
cow() = default;
6+
7+
template <typename... Ts>
8+
explicit cow(Ts &&... ts) : t_(new T(std::forward<Ts>(ts)...)) {
9+
t_->increment_use_count();
10+
}
11+
12+
cow(const cow &rhs) {
13+
if (!rhs.t_->is_unshareable()) {
14+
t_ = rhs.t_;
15+
t_->increment_use_count();
16+
} else {
17+
t_ = new T(*t_);
18+
}
19+
}
20+
21+
cow &operator=(const cow &rhs) {
22+
auto copy(rhs);
23+
swap(copy);
24+
return *this;
25+
}
26+
27+
cow(cow &&rhs) { swap(rhs); }
28+
29+
cow &operator=(cow &&rhs) {
30+
swap(rhs);
31+
return *this;
32+
}
33+
34+
~cow() {
35+
if (t_->is_unshareable()) {
36+
delete t_;
37+
} else {
38+
t_->decrement_use_count();
39+
if (t_->get_use_count() == 0) {
40+
delete t_;
41+
}
42+
}
43+
}
44+
45+
void swap(cow &rhs) {
46+
using std::swap;
47+
swap(t_, rhs.t_);
48+
}
49+
50+
const T &operator*() const { return *t_; }
51+
52+
T &write(bool mark_unshareable) {
53+
if (!t_->is_unshareable() && t_->get_use_count() != 1) {
54+
55+
} else {
56+
57+
}
58+
}
59+
60+
private:
61+
T *t_ = nullptr;
62+
};
63+
64+
class cow_base {
65+
public:
66+
cow_base() = default;
67+
cow_base(const cow_base &) {}
68+
cow_base &operator=(const cow_base &) {}
69+
cow_base(cow_base &&) {}
70+
cow_base &operator=(cow_base &&) {}
71+
72+
void increment_use_count() { use_count_ += 1; }
73+
void decrement_use_count() { use_count_ -= 1; }
74+
std::size_t get_use_count() const { return use_count_; }
75+
76+
void set_unshareable(bool u) { use_count_ = u ? unshareable : 1; }
77+
bool is_unshareable() { return use_count_ == unshareable; }
78+
79+
protected:
80+
~cow_base() = default;
81+
82+
private:
83+
static const std::size_t unshareable =
84+
std::numeric_limits<std::size_t>::max();
85+
std::size_t use_count_ = 0;
86+
};

src/util/irep.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,6 @@ Author: Daniel Kroening, [email protected]
2222
#include <iostream>
2323
#endif
2424

25-
#ifdef SHARING
26-
small_shared_ptrt<irept::dt>& irept::get_empty_dt()
27-
{
28-
// Putting this in a function makes sure that it exists the first time that
29-
// the function is called, which solves undefined-order-of-static-init issues.
30-
static small_shared_ptrt<dt> empty=make_small_shared_ptr<dt>();
31-
return empty;
32-
}
33-
#endif
34-
3525
/*******************************************************************\
3626
3727
Function: named_subt_lower_bound

src/util/irep.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,7 @@ class irept
215215
};
216216

217217
#ifdef SHARING
218-
static small_shared_ptrt<dt> &get_empty_dt();
219-
small_shared_ptrt<dt> data=get_empty_dt();
218+
small_shared_ptrt<dt> data=make_small_shared_ptr<dt>();
220219
#else
221220
dt data;
222221
#endif

0 commit comments

Comments
 (0)