libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
shared_ptr.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2002 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 #include "stdafx.h"
20 
21 #define BOOST_TEST_MODULE libjmmcg_tests
22 #include <boost/test/included/unit_test.hpp>
23 
24 #include <boost/mpl/list.hpp>
25 
26 #include "core/shared_ptr.hpp"
27 
28 using namespace libjmmcg;
29 using namespace ppd;
30 
31 typedef boost::mpl::list<
35 
36 template<class Mdl>
37 struct base : public sp_counter_type<long, api_lock_traits<platform_api, Mdl>> {
38  ~base() noexcept(true) {}
39 
40  bool __fastcall operator<(base const &a) const noexcept(true) {
41  return this<&a;
42  }
43 };
44 template<class Mdl>
45 struct derived final : public base<Mdl> {
46  ~derived() noexcept(true) {}
47 };
48 template<class Mdl>
49 struct placement_dtor_test_t final : public sp_counter_type<long, api_lock_traits<platform_api, Mdl>, placement_dtor, api_lock_traits<platform_api, Mdl>::template atomic_counter_type> {
50  typedef placement_dtor<placement_dtor_test_t> deleter_t;
51 
52  const int val;
53 
54  placement_dtor_test_t() noexcept(true)
55  : val(42) {}
56  ~placement_dtor_test_t() noexcept(true) {}
57 
58  void deleter() override {
59  deleter_t().operator()(this);
60  }
61 
62  bool __fastcall operator<(placement_dtor_test_t const &a) const noexcept(true) {
63  return this<&a;
64  }
65 };
66 
67 template<class Mdl>
68 struct base_inh_t : public virtual sp_counter_itf_type<long> {
69  typedef api_lock_traits<platform_api, Mdl> lock_traits;
70  typedef sp_counter_itf_type<long> base;
71  typedef base atomic_ctr_t;
72 
73  virtual ~base_inh_t() noexcept(true) {
74  }
75  virtual int val() const noexcept(true)=0;
76 };
77 template<class Mdl, template<class> class Del>
78 struct derived_inh_t final : public base_inh_t<Mdl>, public sp_counter_type<long, api_lock_traits<platform_api, Mdl>, Del, api_lock_traits<platform_api, Mdl>::template atomic_counter_type> {
79  typedef Del<derived_inh_t> deleter_t;
80 
81  const int val_;
82 
83  explicit derived_inh_t(int i) noexcept(true)
84  : val_(i) {}
85  ~derived_inh_t() noexcept(true) {}
86 
87  int val() const noexcept(true) override {
88  return val_;
89  }
90 
91  void deleter() override {
92  deleter_t().operator()(this);
93  }
94 
95  bool __fastcall operator<(derived_inh_t const &a) const noexcept(true) {
96  return this<&a;
97  }
98 };
99 
100 template<class Mdl>
101 struct stack_test_t final : public sp_counter_type<long, api_lock_traits<platform_api, Mdl>, noop_dtor, api_lock_traits<platform_api, Mdl>::template noop_atomic_ctr> {
102  const int val;
103 
104  stack_test_t() noexcept(true)
105  : val(42) {}
106  ~stack_test_t() noexcept(true) {}
107 };
108 
109 BOOST_AUTO_TEST_SUITE(shared_ptr_tests)
110 
111 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor_shared_ptr, Mdl, thread_types)
112 {
113  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
114 
115  ptr_t a;
116  BOOST_CHECK_EQUAL(a.get(), static_cast<typename ptr_t::value_type *>(0));
117  BOOST_CHECK(!a);
118 }
119 
120 BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_shared_ptr, Mdl, thread_types)
121 {
122  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
123 
124  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
125  ptr_t a(ptr_a);
126  BOOST_CHECK_EQUAL(a.get(), ptr_a);
127  BOOST_CHECK(!(!a));
128  BOOST_CHECK(a.get().get()->sp_count()>0);
129  BOOST_CHECK(a.get().get()->sp_count()<2);
130 }
131 
132 BOOST_AUTO_TEST_CASE_TEMPLATE(placement_new_ctor_shared_ptr, Mdl, thread_types)
133 {
134  typedef shared_ptr<placement_dtor_test_t<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
135 
136  char buff[sizeof(typename ptr_t::value_type)];
137  typename ptr_t::value_type *ptr_a=new (buff) typename ptr_t::value_type;
138  ptr_t a(ptr_a);
139  BOOST_CHECK_EQUAL(a.get(), ptr_a);
140  BOOST_CHECK(!(!a));
141  BOOST_CHECK_EQUAL(a->val, 42);
142 }
143 
144 BOOST_AUTO_TEST_CASE_TEMPLATE(mixed_dtors_placement_new_ctor_shared_ptr, Mdl, thread_types)
145 {
146  typedef derived_inh_t<Mdl, default_delete> def_del_t;
147  typedef derived_inh_t<Mdl, placement_dtor> plment_del_t;
148  typedef shared_ptr<base_inh_t<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
149 
150  char buff[sizeof(plment_del_t)];
151  def_del_t *ptr_def_del=new def_del_t(42);
152  plment_del_t *ptr_plment_del=new (buff) plment_del_t(1066);
153  ptr_t sp_def_del(ptr_def_del);
154  ptr_t sp_plment_del(ptr_plment_del);
155  BOOST_CHECK_EQUAL(sp_def_del.get(), ptr_def_del);
156  BOOST_CHECK(!(!sp_def_del));
157  BOOST_CHECK_EQUAL(sp_def_del->val(), 42);
158  BOOST_CHECK_EQUAL(sp_plment_del.get(), ptr_plment_del);
159  BOOST_CHECK(!(!sp_plment_del));
160  BOOST_CHECK_EQUAL(sp_plment_del->val(), 1066);
161 }
162 
163 BOOST_AUTO_TEST_CASE_TEMPLATE(cctor_shared_ptr, Mdl, thread_types)
164 {
165  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
166 
167  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
168  ptr_t a(ptr_a);
169  ptr_t a1(a);
170  BOOST_CHECK_EQUAL(a.get(), a1.get());
171  BOOST_CHECK(a.get().get()->sp_count()>1);
172  BOOST_CHECK(a.get().get()->sp_count()<3);
173  BOOST_CHECK(a1.get().get()->sp_count()>1);
174  BOOST_CHECK(a1.get().get()->sp_count()<3);
175 }
176 
177 BOOST_AUTO_TEST_CASE_TEMPLATE(move_ctor_shared_ptr, Mdl, thread_types)
178 {
179  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
180 
181  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
182  ptr_t a(ptr_a);
183  ptr_t a1(std::move(a));
184  BOOST_CHECK_EQUAL(a1.get(), ptr_a);
185  BOOST_CHECK(a1.get().get()->sp_count()>0);
186  BOOST_CHECK(a1.get().get()->sp_count()<2);
187  BOOST_CHECK_EQUAL(a.get(), typename ptr_t::atomic_ptr_t());
188 }
189 
190 BOOST_AUTO_TEST_CASE_TEMPLATE(unique_ptr_ctor_shared_ptr, Mdl, thread_types)
191 {
192  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
193 
194  std::unique_ptr<typename ptr_t::value_type, typename ptr_t::value_type::deleter_t> ptr_a(new typename ptr_t::value_type);
195  ptr_t a(ptr_a);
196  BOOST_CHECK(a.get());
197  BOOST_CHECK_EQUAL(ptr_a.get(), static_cast<typename ptr_t::value_type *>(0));
198 }
199 
200 BOOST_AUTO_TEST_CASE_TEMPLATE(unique_ptr_move_ctor_shared_ptr, Mdl, thread_types)
201 {
202  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
203 
204  std::unique_ptr<typename ptr_t::value_type, typename ptr_t::value_type::deleter_t> ptr_a(new typename ptr_t::value_type);
205  ptr_t a(std::move(ptr_a));
206  BOOST_CHECK(dynamic_cast<typename ptr_t::value_type const *>(a.get().get()));
207 }
208 
209 BOOST_AUTO_TEST_CASE_TEMPLATE(reset_shared_ptr, Mdl, thread_types)
210 {
211  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
212 
213  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
214  ptr_t a(ptr_a);
215  a.reset();
216  BOOST_CHECK_EQUAL(a.get(), static_cast<typename ptr_t::value_type *>(0));
217  BOOST_CHECK(!a);
218 }
219 
220 BOOST_AUTO_TEST_CASE_TEMPLATE(assign_shared_ptr, Mdl, thread_types)
221 {
222  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
223 
224  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
225  ptr_t a(ptr_a);
226  ptr_t a1;
227  a1=a;
228  BOOST_CHECK_EQUAL(a.get(), a1.get());
229 }
230 
231 BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_assign_shared_ptr, Mdl, thread_types)
232 {
233  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
234 
235  ptr_t a;
236  a=ptr_t(new typename ptr_t::value_type);
237  BOOST_CHECK(a.get());
238 }
239 
240 BOOST_AUTO_TEST_CASE_TEMPLATE(unique_ptr_ctor_assign_shared_ptr, Mdl, thread_types)
241 {
242  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
243 
244  std::unique_ptr<typename ptr_t::value_type, typename ptr_t::value_type::deleter_t> ptr_a(new typename ptr_t::value_type);
245  ptr_t a;
246  a=ptr_t(ptr_a);
247  BOOST_CHECK(a.get());
248  BOOST_CHECK_EQUAL(ptr_a.get(), static_cast<typename ptr_t::value_type *>(0));
249 }
250 
251 BOOST_AUTO_TEST_CASE_TEMPLATE(equals_shared_ptr, Mdl, thread_types)
252 {
253  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
254 
255  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
256  ptr_t a(ptr_a);
257  ptr_t a1(a);
258  BOOST_CHECK(a==a1);
259  BOOST_CHECK(!(a!=a1));
260 }
261 
262 BOOST_AUTO_TEST_CASE_TEMPLATE(not_equals_shared_ptr, Mdl, thread_types)
263 {
264  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
265 
266  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
267  typename ptr_t::value_type *ptr_a1=new typename ptr_t::value_type;
268  ptr_t a(ptr_a);
269  ptr_t a1(ptr_a1);
270  BOOST_CHECK(a!=a1);
271  BOOST_CHECK(!(a==a1));
272 }
273 
274 BOOST_AUTO_TEST_CASE_TEMPLATE(equals_comparators_shared_ptr, Mdl, thread_types)
275 {
276  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
277 
278  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
279  ptr_t a(ptr_a);
280  ptr_t a1(a);
281  BOOST_CHECK(!(a<a1) && !(a>a1));
282 }
283 
284 BOOST_AUTO_TEST_CASE_TEMPLATE(not_equals_comparators_shared_ptr, Mdl, thread_types)
285 {
286  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
287 
288  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
289  typename ptr_t::value_type *ptr_a1=new typename ptr_t::value_type;
290  ptr_t a(ptr_a);
291  ptr_t a1(ptr_a1);
292  BOOST_CHECK((a<a1) || (a>a1));
293 }
294 
295 BOOST_AUTO_TEST_CASE_TEMPLATE(inheritance_wrapping, Mdl, thread_types)
296 {
297  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
298  typedef shared_ptr<derived<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_b_t;
299 
300  typename ptr_b_t::value_type *ptr_b=new typename ptr_b_t::value_type;
301  ptr_t b(ptr_b);
302  BOOST_CHECK(b.get()==ptr_b);
303 }
304 
305 BOOST_AUTO_TEST_CASE_TEMPLATE(shares_the_ptr, Mdl, thread_types)
306 {
307  typedef shared_ptr<base<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
308 
309  typename ptr_t::value_type *ptr_a=new typename ptr_t::value_type;
310  ptr_t a(ptr_a);
311  {
312  ptr_t a1(a);
313  BOOST_CHECK(a.get()==a1.get());
314  BOOST_CHECK(a==a1);
315  }
316  BOOST_CHECK(a.get()==ptr_a);
317 }
318 
319 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor_stack_test, Mdl, thread_types)
320 {
321  typedef shared_ptr<stack_test_t<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
322 
323  ptr_t a;
324  BOOST_CHECK_EQUAL(a.get(), static_cast<typename ptr_t::value_type *>(0));
325  BOOST_CHECK(!a);
326 }
327 
328 BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_stack_test, Mdl, thread_types)
329 {
330  typedef shared_ptr<stack_test_t<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
331 
332  typename ptr_t::value_type val_a;
333  ptr_t a(&val_a);
334  BOOST_CHECK(a.get()==&val_a);
335 }
336 
337 BOOST_AUTO_TEST_CASE_TEMPLATE(shares_stack_test, Mdl, thread_types)
338 {
339  typedef shared_ptr<stack_test_t<Mdl>, api_lock_traits<platform_api, Mdl>> ptr_t;
340 
341  typename ptr_t::value_type val_a;
342  ptr_t a(&val_a);
343  {
344  ptr_t a1(a);
345  BOOST_CHECK(a.get()==a1.get());
346  BOOST_CHECK(a==a1);
347  BOOST_CHECK_EQUAL(a1->val, 42);
348  }
349  BOOST_CHECK(a.get()==&val_a);
350  BOOST_CHECK_EQUAL(a->val, 42);
351 }
352 
353 BOOST_AUTO_TEST_SUITE_END()