CBMC
cow.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Copy on write class
4 
5 Author: Reuben Thomas, reuben.thomas@diffblue.com
6 
7 \*******************************************************************/
8 
9 #ifndef CPROVER_UTIL_COW_H
10 #define CPROVER_UTIL_COW_H
11 
12 #include "invariant.h"
13 #include "small_shared_ptr.h"
14 
15 #include <limits>
16 
23 template <typename T>
24 class copy_on_writet final
25 {
26 public:
27  // Note that this *is* the default constructor. An invariant of a
28  // copy-on-write object is that it is never null.
29  template <typename... Ts>
30  explicit copy_on_writet(Ts &&... ts)
31  : t_(make_small_shared_ptr<T>(std::forward<Ts>(ts)...))
32  {
33  INVARIANT(
35  "newly-constructed COW pointers must be shareable");
36  }
37 
39  : t_(
40  pointee_is_shareable(*rhs.t_) ? rhs.t_
41  : make_small_shared_ptr<T>(*rhs.t_))
42  {
43  INVARIANT(
45  "newly-constructed COW pointers must be shareable");
46  }
47 
49  {
50  auto copy(rhs);
51  swap(copy);
52  return *this;
53  }
54 
56  {
57  swap(rhs);
58  }
59 
61  {
62  swap(rhs);
63  return *this;
64  }
65 
66  void swap(copy_on_writet &rhs)
67  {
68  std::swap(t_, rhs.t_);
69  }
70 
71  const T &read() const
72  {
73  return *t_;
74  }
75 
76  T &write(bool mark_shareable)
77  {
78  if(pointee_use_count(*t_) != 1)
79  {
80  t_ = make_small_shared_ptr<T>(*t_);
81  }
82  INVARIANT(
83  pointee_use_count(*t_) == 1,
84  "mutable references to a COW pointer must be unique");
85  pointee_set_shareable(*t_, mark_shareable);
86  return *t_;
87  }
88 
89  // Ideally these would be non-members, but they depend on private member t_
90 
91  template <typename U>
92  bool operator==(const copy_on_writet<U> &rhs) const
93  {
94  return t_ == rhs.t_;
95  }
96 
97  template <typename U>
98  bool operator!=(const copy_on_writet<U> &rhs) const
99  {
100  return t_ != rhs.t_;
101  }
102 
103  template <typename U>
104  bool operator<(const copy_on_writet<U> &rhs) const
105  {
106  return t_ < rhs.t_;
107  }
108 
109  template <typename U>
110  bool operator>(const copy_on_writet<U> &rhs) const
111  {
112  return t_ > rhs.t_;
113  }
114 
115  template <typename U>
116  bool operator<=(const copy_on_writet<U> &rhs) const
117  {
118  return t_ <= rhs.t_;
119  }
120 
121  template <typename U>
122  bool operator>=(const copy_on_writet<U> &rhs) const
123  {
124  return t_ >= rhs.t_;
125  }
126 
127 private:
129 };
130 
132 
137 template <typename Num>
139 {
140 public:
142 
144  {
145  }
146 
148  {
149  return *this;
150  }
151 
153  {
154  }
155 
157  {
158  return *this;
159  }
160 
162  {
163  INVARIANT(
164  is_shareable(),
165  "cannot increment the use count of a non-shareable reference");
166  ++use_count_;
167  }
168 
170  {
171  INVARIANT(
172  is_shareable(),
173  "cannot decrement the use count of a non-shareable reference");
174  --use_count_;
175  }
176 
177  Num use_count() const
178  {
179  return is_shareable() ? use_count_ : 1;
180  }
181 
182  void set_shareable(bool u)
183  {
184  use_count_ = u ? 1 : unshareable;
185  }
186 
187  bool is_shareable() const
188  {
189  return use_count_ != unshareable;
190  }
191 
192 protected:
194 
195 private:
202  static const Num unshareable;
203  Num use_count_ = 0;
204 };
205 
206 template <typename Num>
208  (std::numeric_limits<Num>::max)(); // suppress macro expansion on windows
209 
217 
218 template <typename Num>
220 {
222 }
223 
224 template <typename Num>
226 {
228 }
229 
230 template <typename Num>
232 {
233  return p.use_count();
234 }
235 
236 template <typename Num, typename T>
238 {
239  p.set_use_count(count);
240 }
241 
242 template <typename Num>
244 {
245  p.set_shareable(u);
246 }
247 
248 template <typename Num>
250 {
251  return p.is_shareable();
252 }
253 
254 #endif
A helper class to store use-counts of copy-on-write objects.
Definition: cow.h:139
void increment_use_count()
Definition: cow.h:161
copy_on_write_pointeet(const copy_on_write_pointeet &)
Definition: cow.h:143
~copy_on_write_pointeet()=default
copy_on_write_pointeet & operator=(const copy_on_write_pointeet &)
Definition: cow.h:147
void set_shareable(bool u)
Definition: cow.h:182
void decrement_use_count()
Definition: cow.h:169
static const Num unshareable
A special sentry value which will be assigned to use_count_ if a mutable reference to the held object...
Definition: cow.h:202
copy_on_write_pointeet()=default
bool is_shareable() const
Definition: cow.h:187
copy_on_write_pointeet & operator=(copy_on_write_pointeet &&)
Definition: cow.h:156
copy_on_write_pointeet(copy_on_write_pointeet &&)
Definition: cow.h:152
Num use_count() const
Definition: cow.h:177
A utility class for writing types with copy-on-write behaviour (like irep).
Definition: cow.h:25
bool operator>(const copy_on_writet< U > &rhs) const
Definition: cow.h:110
copy_on_writet & operator=(copy_on_writet &&rhs)
Definition: cow.h:60
bool operator>=(const copy_on_writet< U > &rhs) const
Definition: cow.h:122
bool operator<=(const copy_on_writet< U > &rhs) const
Definition: cow.h:116
bool operator!=(const copy_on_writet< U > &rhs) const
Definition: cow.h:98
copy_on_writet(const copy_on_writet &rhs)
Definition: cow.h:38
copy_on_writet & operator=(const copy_on_writet &rhs)
Definition: cow.h:48
bool operator==(const copy_on_writet< U > &rhs) const
Definition: cow.h:92
const T & read() const
Definition: cow.h:71
small_shared_ptrt< T > t_
Definition: cow.h:128
void swap(copy_on_writet &rhs)
Definition: cow.h:66
bool operator<(const copy_on_writet< U > &rhs) const
Definition: cow.h:104
T & write(bool mark_shareable)
Definition: cow.h:76
copy_on_writet(copy_on_writet &&rhs)
Definition: cow.h:55
copy_on_writet(Ts &&... ts)
Definition: cow.h:30
This class is really similar to boost's intrusive_pointer, but can be a bit simpler seeing as we're o...
bool pointee_is_shareable(const copy_on_write_pointeet< Num > &p)
Definition: cow.h:249
void pointee_increment_use_count(copy_on_write_pointeet< Num > &p)
The following functions are required by copy_on_writet, and by default pass through to the member fun...
Definition: cow.h:219
void pointee_set_shareable(copy_on_write_pointeet< Num > &p, bool u)
Definition: cow.h:243
void pointee_decrement_use_count(copy_on_write_pointeet< Num > &p)
Definition: cow.h:225
Num pointee_use_count(const copy_on_write_pointeet< Num > &p)
Definition: cow.h:231
void pointee_set_use_count(copy_on_write_pointeet< Num > &p, T count)
Definition: cow.h:237
small_shared_ptrt< T > make_small_shared_ptr(Ts &&... ts)
This function is similar to std::make_unique and std::make_shared, and should be the preferred way of...