shared_array_nmt.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
  3. //
  4. // detail/shared_array_nmt.hpp - shared_array.hpp without member templates
  5. //
  6. // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
  7. // Copyright (c) 2001, 2002 Peter Dimov
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. //
  13. // See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
  14. //
  15. #include <boost/assert.hpp>
  16. #include <boost/checked_delete.hpp>
  17. #include <boost/throw_exception.hpp>
  18. #include <boost/smart_ptr/detail/atomic_count.hpp>
  19. #include <cstddef> // for std::ptrdiff_t
  20. #include <algorithm> // for std::swap
  21. #include <functional> // for std::less
  22. #include <new> // for std::bad_alloc
  23. namespace boost
  24. {
  25. template<class T> class shared_array
  26. {
  27. private:
  28. typedef detail::atomic_count count_type;
  29. public:
  30. typedef T element_type;
  31. explicit shared_array(T * p = 0): px(p)
  32. {
  33. #ifndef BOOST_NO_EXCEPTIONS
  34. try // prevent leak if new throws
  35. {
  36. pn = new count_type(1);
  37. }
  38. catch(...)
  39. {
  40. boost::checked_array_delete(p);
  41. throw;
  42. }
  43. #else
  44. pn = new count_type(1);
  45. if(pn == 0)
  46. {
  47. boost::checked_array_delete(p);
  48. boost::throw_exception(std::bad_alloc());
  49. }
  50. #endif
  51. }
  52. ~shared_array()
  53. {
  54. if(--*pn == 0)
  55. {
  56. boost::checked_array_delete(px);
  57. delete pn;
  58. }
  59. }
  60. shared_array(shared_array const & r) : px(r.px) // never throws
  61. {
  62. pn = r.pn;
  63. ++*pn;
  64. }
  65. shared_array & operator=(shared_array const & r)
  66. {
  67. shared_array(r).swap(*this);
  68. return *this;
  69. }
  70. void reset(T * p = 0)
  71. {
  72. BOOST_ASSERT(p == 0 || p != px);
  73. shared_array(p).swap(*this);
  74. }
  75. T * get() const // never throws
  76. {
  77. return px;
  78. }
  79. T & operator[](std::ptrdiff_t i) const // never throws
  80. {
  81. BOOST_ASSERT(px != 0);
  82. BOOST_ASSERT(i >= 0);
  83. return px[i];
  84. }
  85. long use_count() const // never throws
  86. {
  87. return *pn;
  88. }
  89. bool unique() const // never throws
  90. {
  91. return *pn == 1;
  92. }
  93. void swap(shared_array<T> & other) // never throws
  94. {
  95. std::swap(px, other.px);
  96. std::swap(pn, other.pn);
  97. }
  98. private:
  99. T * px; // contained pointer
  100. count_type * pn; // ptr to reference counter
  101. }; // shared_array
  102. template<class T, class U> inline bool operator==(shared_array<T> const & a, shared_array<U> const & b)
  103. {
  104. return a.get() == b.get();
  105. }
  106. template<class T, class U> inline bool operator!=(shared_array<T> const & a, shared_array<U> const & b)
  107. {
  108. return a.get() != b.get();
  109. }
  110. template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b)
  111. {
  112. return std::less<T*>()(a.get(), b.get());
  113. }
  114. template<class T> void swap(shared_array<T> & a, shared_array<T> & b)
  115. {
  116. a.swap(b);
  117. }
  118. } // namespace boost
  119. #endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED