Om
owner.cpp
Go to the documentation of this file.
1 
15 #ifndef Om_Owner_
16 
17  #include "om/owner.hpp"
18 
19  #ifdef Om_Macro_Test_
20 
21  #include "om/default_copyable.hpp"
22  #include "om/shareable.hpp"
23 
24  #ifndef Om_Macro_Precompilation_
25 
26  #include "boost/test/unit_test.hpp"
27 
28  #endif
29 
30 namespace Om {
31 
32  BOOST_AUTO_TEST_SUITE(OwnerTest)
33 
34  namespace {
35 
36  class TestValue:
37  public DefaultCopyable<TestValue>,
38  public Shareable<> {
39 
40  public:
41 
42  explicit TestValue(int const theNumber):
43  thisNumber(theNumber) {}
44 
45  bool operator ==(TestValue const theTestValue) const {
46  return this->thisNumber == theTestValue.thisNumber;
47  }
48 
49  int thisNumber;
50 
51  };
52 
53  }
54 
55  BOOST_AUTO_TEST_CASE(LazinessTest) {
56  Owner<TestValue> theFirst(
57  std::auto_ptr<TestValue>(
58  new TestValue(1)
59  )
60  );
61  assert(theFirst);
62 
63  Owner<TestValue> const & theConstFirst = theFirst;
64  TestValue const & theFirstValue = *theConstFirst;
65 
66  Owner<TestValue> theSecond(theFirst);
67 
68  Owner<TestValue> const & theConstSecond = theSecond;
69  TestValue const & theSecondValue = *theConstSecond;
70 
71  BOOST_CHECK_EQUAL(
72  &theFirstValue,
73  &theSecondValue
74  );
75  }
76 
77  BOOST_AUTO_TEST_CASE(CopyTest) {
78  Owner<TestValue> theFirst(
79  std::auto_ptr<TestValue>(
80  new TestValue(1)
81  )
82  );
83  assert(theFirst);
84 
85  TestValue & theFirstValue = *theFirst;
86  BOOST_CHECK_EQUAL(
87  1,
88  theFirstValue.thisNumber
89  );
90  theFirstValue.thisNumber = 2;
91  BOOST_CHECK_EQUAL(
92  2,
93  theFirstValue.thisNumber
94  );
95 
96  Owner<TestValue> theSecond(theFirst);
97 
98  TestValue & theSecondValue = *theSecond;
99  BOOST_CHECK_EQUAL(
100  2,
101  theFirstValue.thisNumber
102  );
103  BOOST_CHECK_EQUAL(
104  2,
105  theSecondValue.thisNumber
106  );
107 
108  theSecondValue.thisNumber = 3;
109  theFirstValue.thisNumber = 4;
110 
111  Owner<TestValue> theThird(theFirst);
112  Owner<TestValue> theFourth(theThird);
113 
114  TestValue & theThirdValue = *theThird;
115  Owner<TestValue> const & theConstFourth = theFourth;
116  TestValue const & theFourthValue = *theConstFourth;
117  BOOST_CHECK_EQUAL(
118  4,
119  theFirstValue.thisNumber
120  );
121  BOOST_CHECK_EQUAL(
122  3,
123  theSecondValue.thisNumber
124  );
125  BOOST_CHECK_EQUAL(
126  4,
127  theThirdValue.thisNumber
128  );
129  BOOST_CHECK_EQUAL(
130  4,
131  theFourthValue.thisNumber
132  );
133 
134  theThirdValue.thisNumber = 5;
135  BOOST_CHECK_EQUAL(
136  4,
137  theFirstValue.thisNumber
138  );
139  BOOST_CHECK_EQUAL(
140  3,
141  theSecondValue.thisNumber
142  );
143  BOOST_CHECK_EQUAL(
144  5,
145  theThirdValue.thisNumber
146  );
147  BOOST_CHECK_EQUAL(
148  4,
149  theFourthValue.thisNumber
150  );
151  }
152 
153  BOOST_AUTO_TEST_SUITE_END()
154 
155 }
156 
157  #endif
158 
159 #else
160 
161  #ifndef Om_Macro_Precompilation_
162 
163  #include "boost/swap.hpp"
164 
165  #endif
166 
167 // MARK: - Om::Owner
168 
169  #define Template_ \
170  template <typename ThisValue>
171 
172  #define Type_ \
173  Om::Owner<ThisValue>
174 
175 // MARK: public (non-static)
176 
177 Template_
178 inline Type_::Owner():
179 thisValue(),
180 thisWasExposed() {}
181 
182 Template_
183 inline Type_::Owner(Owner const & theOwner):
184 thisValue(),
185 thisWasExposed() {
186  if (theOwner.thisWasExposed) {
187  assert(theOwner.thisValue);
188  this->thisValue.reset(
189  Copy(*theOwner.thisValue).release()
190  );
191  } else {
192  this->thisValue = theOwner.thisValue;
193  }
194 }
195 
196 Template_
197 template <typename TheValue>
198 inline Type_::Owner(
199  std::auto_ptr<TheValue> theValue
200 ):
201 thisValue(
202  theValue.release()
203 ),
204 thisWasExposed() {}
205 
206 Template_
207 inline Type_ & Type_::operator =(Owner theOwner) {
208  this->Swap(theOwner);
209  return *this;
210 }
211 
212 Template_
213 inline ThisValue & Type_::operator *() {
214  assert(this->thisValue);
215  if (
216  1 < this->thisValue->GetOwnerCount()
217  ) {
218  this->thisValue.reset(
219  Copy(*this->thisValue).release()
220  );
221  assert(this->thisValue);
222  }
223  this->thisWasExposed = true;
224  return *this->thisValue;
225 }
226 
227 Template_
228 inline ThisValue const & Type_::operator *() const {
229  assert(this->thisValue);
230  return *this->thisValue;
231 }
232 
233 Template_
234 inline ThisValue * Type_::operator ->() {
235  return &**this;
236 }
237 
238 Template_
239 inline ThisValue const * Type_::operator ->() const {
240  return &**this;
241 }
242 
243 Template_
244 inline bool Type_::operator !() const {
245  return !this->thisValue;
246 }
247 
248 Template_
249 inline Type_::operator Boolean() const {
250  return (
251  this->thisValue ?
252  &Owner::UncomparableBoolean :
253  0
254  );
255 }
256 
257 Template_
258 inline void Type_::Clear() {
259  this->thisValue.reset();
260  this->thisWasExposed = false;
261 }
262 
263 Template_
264 ThisValue * Type_::GetValue() {
265  return (
266  this->thisValue ?
267  &**this :
268  0
269  );
270 }
271 
272 Template_
273 ThisValue const * Type_::GetValue() const {
274  return this->thisValue.get();
275 }
276 
277 Template_
278 bool Type_::IsEmpty() const {
279  return !this->thisValue;
280 }
281 
282 Template_
283 template <typename TheValue>
284 inline void Type_::SetValue(
285  std::auto_ptr<TheValue> theValue
286 ) {
287  this->thisValue.reset(
288  theValue.release()
289  );
290  this->thisWasExposed = false;
291 }
292 
293 Template_
294 inline void Type_::Swap(Owner & theOwner) {
295  this->thisValue.swap(theOwner.thisValue);
296  boost::swap(
297  this->thisWasExposed,
298  theOwner.thisWasExposed
299  );
300 }
301 
302 // MARK: private (non-static)
303 
304 Template_
305 inline void Type_::UncomparableBoolean() const {}
306 
307  #undef Type_
308  #undef Template_
309 
310 // MARK: - boost::
311 
312 template <typename TheValue>
313 inline void boost::swap(
314  Om::Owner<TheValue> & theFirst,
315  Om::Owner<TheValue> & theSecond
316 ) {
317  theFirst.Swap(theSecond);
318 }
319 
320 #endif
A polymorphic object with value semantics.
Definition: owner.hpp:43
void Swap(Owner &)
Om header file.
The Om library.
Definition: code_point.hpp:26
bool operator==(Source::Source< TheItem > const &, Source::Source< TheItem > const &)
std::auto_ptr< TheCopyable > Copy(TheCopyable const &)
void swap(Om::Language::Expression &, Om::Language::Expression &)
Om header file.
Om header file.