|
1 #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED |
|
2 #define BOOST_SCOPED_ARRAY_HPP_INCLUDED |
|
3 |
|
4 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. |
|
5 // Copyright (c) 2001, 2002 Peter Dimov |
|
6 // |
|
7 // Distributed under the Boost Software License, Version 1.0. (See |
|
8 // accompanying file LICENSE_1_0.txt or copy at |
|
9 // http://www.boost.org/LICENSE_1_0.txt) |
|
10 // |
|
11 // http://www.boost.org/libs/smart_ptr/scoped_array.htm |
|
12 // |
|
13 |
|
14 #include <boost/assert.hpp> |
|
15 #include <boost/checked_delete.hpp> |
|
16 #include <boost/config.hpp> // in case ptrdiff_t not in std |
|
17 |
|
18 #include <boost/detail/workaround.hpp> |
|
19 |
|
20 #include <cstddef> // for std::ptrdiff_t |
|
21 |
|
22 namespace boost |
|
23 { |
|
24 |
|
25 // Debug hooks |
|
26 |
|
27 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) |
|
28 |
|
29 void sp_array_constructor_hook(void * p); |
|
30 void sp_array_destructor_hook(void * p); |
|
31 |
|
32 #endif |
|
33 |
|
34 // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to |
|
35 // is guaranteed, either on destruction of the scoped_array or via an explicit |
|
36 // reset(). Use shared_array or std::vector if your needs are more complex. |
|
37 |
|
38 template<class T> class scoped_array // noncopyable |
|
39 { |
|
40 private: |
|
41 |
|
42 T * ptr; |
|
43 |
|
44 scoped_array(scoped_array const &); |
|
45 scoped_array & operator=(scoped_array const &); |
|
46 |
|
47 typedef scoped_array<T> this_type; |
|
48 |
|
49 public: |
|
50 |
|
51 typedef T element_type; |
|
52 |
|
53 explicit scoped_array(T * p = 0) : ptr(p) // never throws |
|
54 { |
|
55 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) |
|
56 boost::sp_array_constructor_hook(ptr); |
|
57 #endif |
|
58 } |
|
59 |
|
60 ~scoped_array() // never throws |
|
61 { |
|
62 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) |
|
63 boost::sp_array_destructor_hook(ptr); |
|
64 #endif |
|
65 boost::checked_array_delete(ptr); |
|
66 } |
|
67 |
|
68 void reset(T * p = 0) // never throws |
|
69 { |
|
70 BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors |
|
71 this_type(p).swap(*this); |
|
72 } |
|
73 |
|
74 T & operator[](std::ptrdiff_t i) const // never throws |
|
75 { |
|
76 BOOST_ASSERT(ptr != 0); |
|
77 BOOST_ASSERT(i >= 0); |
|
78 return ptr[i]; |
|
79 } |
|
80 |
|
81 T * get() const // never throws |
|
82 { |
|
83 return ptr; |
|
84 } |
|
85 |
|
86 // implicit conversion to "bool" |
|
87 |
|
88 #if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) |
|
89 |
|
90 operator bool () const |
|
91 { |
|
92 return ptr != 0; |
|
93 } |
|
94 |
|
95 #elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) |
|
96 typedef T * (this_type::*unspecified_bool_type)() const; |
|
97 |
|
98 operator unspecified_bool_type() const // never throws |
|
99 { |
|
100 return ptr == 0? 0: &this_type::get; |
|
101 } |
|
102 |
|
103 #else |
|
104 |
|
105 typedef T * this_type::*unspecified_bool_type; |
|
106 |
|
107 operator unspecified_bool_type() const // never throws |
|
108 { |
|
109 return ptr == 0? 0: &this_type::ptr; |
|
110 } |
|
111 |
|
112 #endif |
|
113 |
|
114 bool operator! () const // never throws |
|
115 { |
|
116 return ptr == 0; |
|
117 } |
|
118 |
|
119 void swap(scoped_array & b) // never throws |
|
120 { |
|
121 T * tmp = b.ptr; |
|
122 b.ptr = ptr; |
|
123 ptr = tmp; |
|
124 } |
|
125 |
|
126 }; |
|
127 |
|
128 template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws |
|
129 { |
|
130 a.swap(b); |
|
131 } |
|
132 |
|
133 } // namespace boost |
|
134 |
|
135 #endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED |