jle_cpp_tk  0.0 2015-04-03 sh1:"d699093732dd5f321606d0ff7a6b63b229f1922c"
A small, safe, selft contained, soft-realtime C++ toolkit
shared_ptr.hpp
1 #include <memory>
2 #include <cstddef>
3 #include <exception>
4 #include <bits/shared_ptr.h>
5 
13 #ifndef JLE_SHARED_PTR_H
14 #define JLE_SHARED_PTR_H 1
15 
16 namespace jle
17 {
18 
19 
20 template<typename _Tp>
21 class weak_ptr;
22 
23 
38 template<typename _Tp, std::_Lock_policy _Lp = std::__default_lock_policy>
40 {
41 private:
42  std::shared_ptr<_Tp> ptr;
43 
44 public:
45 
50  constexpr shared_ptr() /*noexcept*/
51  : ptr() {}
52 
53  shared_ptr(const shared_ptr&) /*noexcept*/ = default;
54 
61  template<typename _Tp1>
62  explicit shared_ptr(_Tp1* __p)
63  : ptr(__p) {}
64 
65 
79  template<typename _Tp1, typename _Deleter>
80  shared_ptr(_Tp1* __p, _Deleter __d)
81  : ptr(__p, __d) {}
82 
83 
97  template<typename _Deleter>
98  shared_ptr(nullptr_t __p, _Deleter __d)
99  : ptr(__p, __d) {}
100 
116  template<typename _Tp1, typename _Deleter, typename _Alloc>
117  shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
118  : ptr(__p, __d, __a) {}
119 
135  template<typename _Deleter, typename _Alloc>
136  shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
137  : ptr(__p, __d, __a) {}
138 
139 
140 // /**
141 // * @brief Constructs a %shared_ptr instance that stores @a __p
142 // * and shares ownership with @a __r.
143 // * @param __r A %shared_ptr.
144 // * @param __p A pointer that will remain valid while @a *__r is valid.
145 // * @post get() == __p && use_count() == __r.use_count()
146 // *
147 // * This can be used to construct a @c shared_ptr to a sub-object
148 // * of an object managed by an existing @c shared_ptr.
149 // *
150 // * @code
151 // * shared_ptr< pair<int,int> > pii(new pair<int,int>());
152 // * shared_ptr<int> pi(pii, &pii->first);
153 // * assert(pii.use_count() == 2);
154 // * @endcode
155 // */
156 // template<typename _Tp1>
157 // shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) /*noexcept*/
158 // : PENDING
159 
160 
161 
162  std::shared_ptr<_Tp> __internal_dangerous__get_std_shared_ptr(void) const { return ptr; }
163 
171  template<typename _Tp1, typename = typename
172  std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
173  shared_ptr(const shared_ptr<_Tp1>& __r) /*noexcept*/
174  : ptr(std::shared_ptr<_Tp>(__r.__internal_dangerous__get_std_shared_ptr())) {}
175 
181  shared_ptr(shared_ptr&& __r) /*noexcept*/
182  : ptr(__r.ptr) {}
183 
184 
190  explicit shared_ptr(std::shared_ptr<_Tp>&& __ptr) /*noexcept*/
191  : ptr(__ptr) {}
192 
198  template<typename _Tp1, typename = typename
199  std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
200  shared_ptr(shared_ptr<_Tp1>&& __r) /*noexcept*/
201  : ptr(__r.ptr) {}
202 
203 
212  template<typename _Tp1>
213  explicit shared_ptr(const weak_ptr<_Tp1>& __r)
214  : ptr(__r.ptr) {}
215 
216  template<typename _Tp1, typename _Del>
217  shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
218  : ptr(__r.ptr) {}
219 
225  constexpr shared_ptr(nullptr_t __p) /*noexcept*/
226  : ptr(__p){}
227 
228  explicit shared_ptr(const std::shared_ptr<_Tp>& _ptr)
229  : ptr(_ptr) {}
230 
231  shared_ptr& operator=(const shared_ptr&) /*noexcept*/ = default;
232 
233  template<typename _Tp1>
234  shared_ptr&
235  operator=(const shared_ptr<_Tp1>& __r) /*noexcept*/
236  {
237  ptr=__r;
238  return *this;
239  }
240 
241 
242  shared_ptr&
243  operator=(shared_ptr&& __r) /*noexcept*/
244  {
245  ptr =__r.ptr;
246  return *this;
247  }
248 
249  template<class _Tp1>
250  shared_ptr&
251  operator=(shared_ptr<_Tp1>&& __r) /*noexcept*/
252  {
253  ptr = __r.ptr;
254  return *this;
255  }
256 
257  template<typename _Tp1, typename _Del>
258  shared_ptr&
259  operator=(std::unique_ptr<_Tp1, _Del>&& __r)
260  {
261  ptr = __r.ptr;
262  return *this;
263  }
264 
265 
266 
267 
268 
269 
270 
271 
272  void
273  reset() /*noexcept*/
274  { ptr.reset(); }
275 
276  template<typename _Tp1>
277  void
278  reset(_Tp1* __p) // _Tp1 must be complete.
279  { ptr.reset(__p); }
280 
281  template<typename _Tp1, typename _Deleter>
282  void
283  reset(_Tp1* __p, _Deleter __d)
284  { ptr.reset(__p, __d); }
285 
286  template<typename _Tp1, typename _Deleter, typename _Alloc>
287  void
288  reset(_Tp1* __p, _Deleter __d, _Alloc __a)
289  { ptr.reset(__p, __d, __a); }
290 
291 
292  // Allow class instantiation when _Tp is [cv-qual] void.
293  typename std::add_lvalue_reference<_Tp>::type
294  operator*() const
295  {
296  check_ptr();
297  return *ptr;
298  }
299 
300  _Tp*
301  operator->() const
302  {
303  check_ptr();
304  return ptr.get();
305  }
306 
307 
308  bool expired(void) const {
309  return ((ptr.get()==nullptr) ? true: false);
310  }
311 
312  _Tp*
313  get() const
314  {
315  check_ptr();
316  return ptr.get();
317  }
318 
319  explicit operator bool() const // never throws
320  { return bool(ptr); }
321 
322  bool
323  unique() const /*noexcept*/
324  { return ptr.unique(); }
325 
326  long
327  use_count() const /*noexcept*/
328  { return ptr.use_count(); }
329 
330  void
331  swap(std::__shared_ptr<_Tp, _Lp>& __other) /*noexcept*/
332  {
333  ptr.swap(__other);
334  }
335 
336  template<typename _Tp1>
337  bool
338  owner_before(std::__shared_ptr<_Tp1, _Lp> const& __rhs) const
339  { return ptr.owner_before(__rhs); }
340 
341  template<typename _Tp1>
342  bool
343  owner_before(std::__weak_ptr<_Tp1, _Lp> const& __rhs) const
344  { return ptr.owner_before(__rhs); }
345 
346 // protected:
347 // // This constructor is non-standard, it is used by allocate_shared.
348 // template<typename _Alloc, typename... _Args>
349 // __shared_ptr(std::_Sp_make_shared_tag __tag, const _Alloc& __a,
350 // _Args&&... __args)
351 // : ptr(__a, __args... {}
352 //
353 // template<typename _Tp1, std::_Lock_policy _Lp1, typename _Alloc,
354 // typename... _Args>
355 // friend __shared_ptr<_Tp1, _Lp1>
356 // __allocate_shared(const _Alloc& __a, _Args&&... __args);
357 //
358 // // This constructor is used by __weak_ptr::lock() and
359 // // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
360 // __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
361 // : ptr(__r, std::nothrow) {}
362 //
363 // friend class __weak_ptr<_Tp, _Lp>;
364 //
365 // private:
366 // void*
367 // _M_get_deleter(const std::type_info& __ti) const /*noexcept*/
368 // { return ptr._M_get_deleter(__ti); }
369 //
370 // template<typename _Tp1>
371 // static _Tp1*
372 // _S_raw_ptr(_Tp1* __ptr)
373 // { return __ptr; }
374 //
375 // template<typename _Tp1>
376 // static auto
377 // _S_raw_ptr(_Tp1 __ptr) -> decltype(std::__addressof(*__ptr))
378 // { return std::__addressof(*__ptr); }
379 //
380 // template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
381 // template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
382 //
383 // template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
384 // friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) /*noexcept*/;
385 //
386 // _Tp* _M_ptr; // Contained pointer.
387 // __shared_count<_Lp> _M_refcount; // Reference counter.
388 // };
389 
390 
391 
392 private:
393  void check_ptr(void) const
394  {
395  if (expired())
396  throw std::runtime_error("shared_ptr pointer not valid");
397  }
398 
399 // // This constructor is non-standard, it is used by allocate_shared.
400 // template<typename _Alloc, typename... _Args>
401 // shared_ptr(std::_Sp_make_shared_tag __tag, const _Alloc& __a,
402 // _Args&&... __args)
403 // : ptr(__tag, __a, __args...) {}
404 //
405 // template<typename _Tp1, typename _Alloc, typename... _Args>
406 // friend shared_ptr<_Tp1>
407 // allocate_shared(const _Alloc& __a, _Args&&... __args);
408 //
409 // // This constructor is non-standard, it is used by weak_ptr::lock().
410 // shared_ptr(const jle::weak_ptr<_Tp>& __r, std::nothrow_t)
411 // : ptr(__r, std::nothrow) {}
412 //
413  friend class jle::weak_ptr<_Tp>;
414 };
415 
416 // 20.7.2.2.7 shared_ptr comparisons
417 template<typename _Tp1, typename _Tp2>
418 inline bool
419 operator==(const shared_ptr<_Tp1>& __a,
420  const shared_ptr<_Tp2>& __b) /*noexcept*/
421 { return __a.get() == __b.get(); }
422 
423 template<typename _Tp>
424 inline bool
425 operator==(const shared_ptr<_Tp>& __a, nullptr_t) /*noexcept*/
426 { return !__a; }
427 
428 template<typename _Tp>
429 inline bool
430 operator==(nullptr_t, const shared_ptr<_Tp>& __a) /*noexcept*/
431 { return !__a; }
432 
433 template<typename _Tp1, typename _Tp2>
434 inline bool
435 operator!=(const shared_ptr<_Tp1>& __a,
436  const shared_ptr<_Tp2>& __b) /*noexcept*/
437 { return __a.get() != __b.get(); }
438 
439 template<typename _Tp>
440 inline bool
441 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) /*noexcept*/
442 { return (bool)__a; }
443 
444 template<typename _Tp>
445 inline bool
446 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) /*noexcept*/
447 { return (bool)__a; }
448 
449 template<typename _Tp1, typename _Tp2>
450 inline bool
451 operator<(const shared_ptr<_Tp1>& __a,
452  const shared_ptr<_Tp2>& __b) /*noexcept*/
453 {
454  typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
455  return std::less<_CT>()(__a.get(), __b.get());
456 }
457 
458 template<typename _Tp>
459 inline bool
460 operator<(const shared_ptr<_Tp>& __a, nullptr_t) /*noexcept*/
461 { return std::less<_Tp*>()(__a.get(), nullptr); }
462 
463 template<typename _Tp>
464 inline bool
465 operator<(nullptr_t, const shared_ptr<_Tp>& __a) /*noexcept*/
466 { return std::less<_Tp*>()(nullptr, __a.get()); }
467 
468 template<typename _Tp1, typename _Tp2>
469 inline bool
470 operator<=(const shared_ptr<_Tp1>& __a,
471  const shared_ptr<_Tp2>& __b) /*noexcept*/
472 { return !(__b < __a); }
473 
474 template<typename _Tp>
475 inline bool
476 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) /*noexcept*/
477 { return !(nullptr < __a); }
478 
479 template<typename _Tp>
480 inline bool
481 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) /*noexcept*/
482 { return !(__a < nullptr); }
483 
484 template<typename _Tp1, typename _Tp2>
485 inline bool
486 operator>(const shared_ptr<_Tp1>& __a,
487  const shared_ptr<_Tp2>& __b) /*noexcept*/
488 { return (__b < __a); }
489 
490 template<typename _Tp>
491 inline bool
492 operator>(const shared_ptr<_Tp>& __a, nullptr_t) /*noexcept*/
493 { return std::less<_Tp*>()(nullptr, __a.get()); }
494 
495 template<typename _Tp>
496 inline bool
497 operator>(nullptr_t, const shared_ptr<_Tp>& __a) /*noexcept*/
498 { return std::less<_Tp*>()(__a.get(), nullptr); }
499 
500 template<typename _Tp1, typename _Tp2>
501 inline bool
502 operator>=(const shared_ptr<_Tp1>& __a,
503  const shared_ptr<_Tp2>& __b) /*noexcept*/
504 { return !(__a < __b); }
505 
506 template<typename _Tp>
507 inline bool
508 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) /*noexcept*/
509 { return !(__a < nullptr); }
510 
511 template<typename _Tp>
512 inline bool
513 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) /*noexcept*/
514 { return !(nullptr < __a); }
515 
516 //template<typename _Tp>
517 //struct less<shared_ptr<_Tp>> : public std::_Sp_less<shared_ptr<_Tp>>
518 //{ };
519 
520 // 20.7.2.2.8 shared_ptr specialized algorithms.
521 template<typename _Tp>
522 inline void
523 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) /*noexcept*/
524 { __a.swap(__b); }
525 
526 // 20.7.2.2.9 shared_ptr casts.
527 template<typename _Tp, typename _Tp1>
528 inline shared_ptr<_Tp>
529 static_pointer_cast(const shared_ptr<_Tp1>& __r) /*noexcept*/
530 { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); }
531 
532 template<typename _Tp, typename _Tp1>
533 inline shared_ptr<_Tp>
534 const_pointer_cast(const shared_ptr<_Tp1>& __r) /*noexcept*/
535 { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); }
536 
537 template<typename _Tp, typename _Tp1>
538 inline shared_ptr<_Tp>
539 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) /*noexcept*/
540 {
541  if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
542 return shared_ptr<_Tp>(__r, __p);
543  return shared_ptr<_Tp>();
544 }
545 
546 
566 template<typename _Tp>
567 class weak_ptr
568 {
569 private:
570  std::weak_ptr<_Tp> ptr;
571  void check_ptr(void) const
572  {
573  if (expired())
574  throw std::runtime_error("shared_ptr pointer not valid");
575  }
576 
577 public:
578  constexpr weak_ptr() /*noexcept*/
579  : ptr() { }
580 
581  template<typename _Tp1, typename = typename
582  std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
583  weak_ptr(const weak_ptr<_Tp1>& __r) /*noexcept*/
584  : ptr(__r) { }
585 
586  template<typename _Tp1, typename = typename
587  std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
588  weak_ptr(const shared_ptr<_Tp1>& __r) /*noexcept*/
589  : ptr(__r.ptr) { }
590 
591  template<typename _Tp1>
592  weak_ptr&
593  operator=(const weak_ptr<_Tp1>& __r) /*noexcept*/
594  {
595  ptr=__r;
596  return *this;
597  }
598 
599  template<typename _Tp1>
600  weak_ptr&
601  operator=(const jle::shared_ptr<_Tp1>& __r) /*noexcept*/
602  {
603  ptr=__r.ptr;
604  return *this;
605  }
606 
608  lock() const
609  {
610  if(expired())
611  return shared_ptr<_Tp>();
612  else
613  {
614  return jle::shared_ptr<_Tp>(ptr.lock());
615  }
616  }
617 
618  bool expired(void) const {
619  return ptr.expired();
620  }
621 
622 };
623 
624 // 20.7.2.3.6 weak_ptr specialized algorithms.
625 template<typename _Tp>
626 inline void
627 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) /*noexcept*/
628 { __a.swap(__b); }
629 
630 
632 template<typename _Tp>
633 struct owner_less;
634 
636 template<typename _Tp>
637 struct owner_less<shared_ptr<_Tp>>
638 : public std::_Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
639 { };
640 
642 template<typename _Tp>
643 struct owner_less<weak_ptr<_Tp>>
644 : public std::_Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
645 { };
646 
650 template<typename _Tp>
652 {
653 protected:
654  constexpr enable_shared_from_this() /*noexcept*/ { }
655 
656  enable_shared_from_this(const enable_shared_from_this&) /*noexcept*/ { }
657 
659  operator=(const enable_shared_from_this&) /*noexcept*/
660  { return *this; }
661 
663 
664 public:
666  shared_from_this()
667  { return shared_ptr<_Tp>(this->_M_weak_this); }
668 
670  shared_from_this() const
671  { return shared_ptr<const _Tp>(this->_M_weak_this); }
672 
673 private:
674  template<typename _Tp1>
675 void
676 _M_weak_assign(_Tp1* __p, const std::__shared_count<>& __n) const /*noexcept*/
677 { _M_weak_this._M_assign(__p, __n); }
678 
679  template<typename _Tp1>
680 friend void
681 __enable_shared_from_this_helper(const std::__shared_count<>& __pn,
682  const enable_shared_from_this* __pe,
683  const _Tp1* __px) /*noexcept*/
684 {
685  if (__pe != 0)
686  __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
687 }
688 
689  mutable weak_ptr<_Tp> _M_weak_this;
690 };
691 
692 /*
693 * @brief Create an object that is owned by a shared_ptr.
694 * @param __a An allocator.
695 * @param __args Arguments for the @a _Tp object's constructor.
696 * @return A shared_ptr that owns the newly created object.
697 * @throw An exception thrown from @a _Alloc::allocate or from the
698 * constructor of @a _Tp.
699 *
700 * A copy of @a __a will be used to allocate memory for the shared_ptr
701 * and the new object.
702 */
703 //template<typename _Tp, typename _Alloc, typename... _Args>
704 //inline shared_ptr<_Tp>
705 //allocate_shared(const _Alloc& __a, _Args&&... __args)
706 //{
707 // return shared_ptr<_Tp>(std::_Sp_make_shared_tag(), __a,
708 // std::forward<_Args>(__args)...);
709 //}
710 
718 template<typename _Tp, typename... _Args>
719 inline shared_ptr<_Tp>
720 make_shared(_Args&&... __args)
721 {
722  std::shared_ptr<_Tp> ptr = std::make_shared<_Tp>(__args...);
723  return jle::shared_ptr<_Tp>((ptr));
724 }
725 //template<typename _Tp>
726 //inline jle::shared_ptr<_Tp>
727 //make_shared(_Tp _arg)
728 //{
729 // std::shared_ptr<_Tp> ptr = std::make_shared<_Tp>(_arg);
730 // return jle::shared_ptr<_Tp>((ptr));
731 //}
732 
733 
734 //template<typename _Tp, typename... _Args>
735 //inline jle::shared_ptr<_Tp>
736 //make_shared(_Args&&... __args)
737 //{
738 // std::shared_ptr<_Tp> ptr = std::make_shared<_Tp, _Args...>(__args...);
739 // return jle::shared_ptr<_Tp>((ptr));
740 //}
741 
742 
743 }; // namespace jle
744 
745 #endif // JLE_SHARED_PTR_H
shared_ptr(_Tp1 *__p, _Deleter __d)
Construct a shared_ptr that owns the pointer __p and the deleter __d.
Definition: shared_ptr.hpp:80
Definition: http_server.h:9
shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
Construct a shared_ptr that owns a null pointer and the deleter __d.
Definition: shared_ptr.hpp:136
constexpr shared_ptr()
Construct an empty shared_ptr.
Definition: shared_ptr.hpp:50
shared_ptr< _Tp > make_shared(_Args &&...__args)
Create an object that is owned by a shared_ptr.
Definition: shared_ptr.hpp:720
Base class allowing use of member function shared_from_this.
Definition: shared_ptr.hpp:651
shared_ptr(const shared_ptr< _Tp1 > &__r)
If __r is empty, constructs an empty shared_ptr; otherwise construct a shared_ptr that shares ownersh...
Definition: shared_ptr.hpp:173
shared_ptr(const weak_ptr< _Tp1 > &__r)
Constructs a shared_ptr that shares ownership with __r and stores a copy of the pointer stored in __r...
Definition: shared_ptr.hpp:213
shared_ptr(std::shared_ptr< _Tp > &&__ptr)
Move-constructs a shared_ptr instance from __r.
Definition: shared_ptr.hpp:190
shared_ptr(_Tp1 *__p)
Construct a shared_ptr that owns the pointer __p.
Definition: shared_ptr.hpp:62
shared_ptr(shared_ptr< _Tp1 > &&__r)
Move-constructs a shared_ptr instance from __r.
Definition: shared_ptr.hpp:200
shared_ptr(shared_ptr &&__r)
Move-constructs a shared_ptr instance from __r.
Definition: shared_ptr.hpp:181
A safe std smart pointer WRAPPER.
Definition: shared_ptr.hpp:39
constexpr shared_ptr(nullptr_t __p)
Construct an empty shared_ptr.
Definition: shared_ptr.hpp:225
A safe std weak_ptr WRAPPER.
Definition: shared_ptr.hpp:21
shared_ptr(nullptr_t __p, _Deleter __d)
Construct a shared_ptr that owns a null pointer and the deleter __d.
Definition: shared_ptr.hpp:98
shared_ptr(_Tp1 *__p, _Deleter __d, _Alloc __a)
Construct a shared_ptr that owns the pointer __p and the deleter __d.
Definition: shared_ptr.hpp:117
Primary template owner_less.
Definition: shared_ptr.hpp:633
generic namespace
Definition: alarm.cpp:12