remove \r
[extl.git] / extl / smartptr / scoped_array.h
blob2a948ef367a7d9b5eea34a441870697e04768900
1 /* ///////////////////////////////////////////////////////////////////////
2 * File: scoped_array.h
4 * Created: 08.02.25
5 * Updated: 08.05.06
7 * Brief: scoped_array class - scoped array
9 * [<Home>]
10 * Copyright (c) 2008-2020, Waruqi All rights reserved.
11 * //////////////////////////////////////////////////////////////////// */
12 #ifndef EXTL_SMART_PTR_SCOPED_ARRAY_H
13 #define EXTL_SMART_PTR_SCOPED_ARRAY_H
15 /*!\file scoped_array.h
16 * \brief scoped_array class - scoped array
18 * - safe implicit conversion to the bool type
19 * - custom deleter
20 * - default deleter: new_allocator<T>::array_deleter_type
21 * - custom deleter function object:
22 * struct deleter
23 * {
24 * void operator()(int *p)
25 * {
26 * delete[] p;
27 * }
28 * };
29 * - usage:
30 * - shared_array<int, deleter > p(new int[10]); - using default deleter
31 * - shared_array<int, deleter > p(new int[10], deleter());
32 * - shared_array<int, deleter > p(new int[10], deleter(...));
35 #ifndef __cplusplus
36 # error shared_ptr.h need be supported by c++.
37 #endif
39 /* ///////////////////////////////////////////////////////////////////////
40 * Includes
42 #include "prefix.h"
43 #include "../utility/operator_bool.h"
44 #include "../memory/new_allocator.h"
45 #include "../counter/shared_counter.h"
46 #include "../algorithm/algorithm.h" /* for std_swap */
47 #include "../utility/uncopyable.h"
49 /* ///////////////////////////////////////////////////////////////////////
50 * Warnings
52 #if defined(EXTL_COMPILER_IS_MSVC) && (_MSC_VER <= 1200)
53 # pragma warning(push)
54 # pragma warning(disable:4284) /* odd return type for operator-> */
55 #endif
57 /* ///////////////////////////////////////////////////////////////////////
58 * ::extl namespace
60 EXTL_BEGIN_NAMESPACE
62 /*!\brief scoped_array class
64 * \param T The value type
65 * \param D The deleter type
67 * \ingroup extl_group_smart_ptr
69 template< typename_param_k T
70 #ifdef EXTL_TEMPLATE_CLASS_DEFAULT_ARGUMENT_SUPPORT
71 , typename_param_k D = typename_type_def_k new_allocator<T>::object_deleter_type
72 #else
73 , typename_param_k D
74 #endif
76 class scoped_array
77 : protected D
79 /// \name Types
80 /// @{
81 public:
82 typedef scoped_array<T, D> class_type;
83 typedef T value_type;
84 typedef value_type* pointer;
85 typedef value_type const* const_pointer;
86 typedef value_type& reference;
87 typedef value_type const& const_reference;
88 typedef D deleter_type;
89 typedef e_long_t index_type;
90 /// @}
92 private:
93 /// The pointer
94 pointer m_ptr;
96 private:
97 /* Prohibit copy constructor and assignment
98 * Note:
99 * Maybe EBO is not supported if uses extl::uncopyable,
100 * because some compilers do not support EBO_FORM_6 - EXTL_EBO_FORM_6_SUPPORT
102 scoped_array(class_type const&);
103 class_type& operator=(class_type const&);
105 /* Member template friend */
106 #ifdef EXTL_MEMBER_TEMPLATE_FRIEND_SUPPORT
107 template < typename_param_k T1, typename_param_k D1 >
108 friend class scoped_array;
109 #endif
111 /// \name Constructors
112 /// @{
113 public:
114 scoped_array()
115 : m_ptr(NULL), deleter_type()
119 explicit_k scoped_array(pointer p)
120 : m_ptr(p), deleter_type()
122 EXTL_ASSERT(is_valid());
125 scoped_array(pointer p, deleter_type const& del)
126 : m_ptr(p), deleter_type(del)
128 EXTL_ASSERT(is_valid());
131 ~scoped_array() EXTL_THROW_0()
133 EXTL_ASSERT(is_valid());
134 /* Destroys the resource */
135 deleter()(m_ptr);
137 #ifdef EXTL_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED_SUPPORT
138 template < typename_param_k T1 >
139 explicit_k scoped_array(T1* p)
140 : m_ptr(p), deleter_type()
142 EXTL_ASSERT(is_valid());
144 #endif
145 /// @}
147 /// \name Accessors
148 /// @{
149 public:
150 reference operator[](index_type const& index) const
152 EXTL_ASSERT(NULL != m_ptr);
153 EXTL_ASSERT(index >= 0);
154 EXTL_ASSERT(is_valid());
156 return m_ptr[index];
158 const_pointer get_ptr() const
160 EXTL_ASSERT(is_valid());
161 return m_ptr;
163 pointer get_ptr()
165 EXTL_ASSERT(is_valid());
166 return m_ptr;
168 /// @}
170 /// \name Mutators
171 /// @{
172 public:
173 /* swap */
174 void swap(class_type& other)
176 EXTL_ASSERT(is_valid());
177 std_swap(m_ptr, other.m_ptr);
178 EXTL_ASSERT(is_valid());
180 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
181 template < typename_param_k T1, typename_param_k D1 >
182 void swap(scoped_array<T1, D1>& other)
184 EXTL_ASSERT(is_valid());
185 std_swap(m_ptr, other.m_ptr);
186 EXTL_ASSERT(is_valid());
188 #endif
190 /* Reset the pointer */
191 void reset()
193 class_type().swap(*this);
195 void reset(pointer p)
197 EXTL_ASSERT(p != m_ptr);
198 class_type(p).swap(*this);
200 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
201 template < typename_param_k T1 >
202 void reset(T1* p)
204 EXTL_ASSERT(p != m_ptr);
205 class_type(p).swap(*this);
207 #endif
208 /// @}
210 public:
211 /// safe implicit conversion to the bool type
212 EXTL_OPERATOR_BOOL_DEFINE_TYPE_T(class_type, safe_bool_type);
213 operator safe_bool_type() const
215 return EXTL_OPERATOR_BOOL_RETURN_RESULT(m_ptr != NULL);
217 /// operator!() overload
218 e_bool_t operator !() const { return (m_ptr == NULL); }
220 /// less than
221 e_bool_t lt(class_type const & rhs) const { return m_ptr < rhs.m_ptr; }
222 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
223 /// less than
224 template < typename_param_k T1, typename_param_k D1 >
225 e_bool_t lt(scoped_array<T1, D1> const & rhs) const { return m_ptr < rhs.m_ptr; }
226 #endif
228 private:
229 e_bool_t is_valid() const { return e_true_v; }
230 deleter_type& deleter() { return *this; }
231 deleter_type const& deleter() const { return *this; }
235 /* ///////////////////////////////////////////////////////////////////////
236 * Operators overload
238 template< typename_param_k T, typename_param_k D >
239 inline e_bool_t operator==(scoped_array<T, D> const& lhs, scoped_array<T, D> const& rhs)
241 return lhs.get_ptr() == rhs.get_ptr();
244 template< typename_param_k T, typename_param_k D >
245 inline e_bool_t operator!=(scoped_array<T, D> const& lhs, scoped_array<T, D> const& rhs)
247 return lhs.get_ptr() != rhs.get_ptr();
249 /* VC6.0: p != NULL */
250 #if defined(EXTL_COMPILER_IS_MSVC) && (_MSC_VER == 1200)
251 template< typename_param_k T, typename_param_k D >
252 inline e_bool_t operator==(scoped_array<T, D> const& lhs, void* rhs)
254 return lhs.get_ptr() == static_cast<T*>(rhs);
257 template< typename_param_k T, typename_param_k D >
258 inline e_bool_t operator!=(scoped_array<T, D> const& lhs, void* rhs)
260 return lhs.get_ptr() != static_cast<T*>(rhs);
262 #endif
265 template< typename_param_k T, typename_param_k D >
266 inline e_bool_t operator<(scoped_array<T, D> const& lhs, scoped_array<T, D> const& rhs)
268 return lhs.lt(rhs);
271 /// swap
272 template< typename_param_k T, typename_param_k D >
273 inline void swap(scoped_array<T, D>& lhs, scoped_array<T, D>& rhs)
275 lhs.swap(rhs);
278 /// get pointer shim
279 template< typename_param_k T, typename_param_k D >
280 inline T const* get_ptr(scoped_array<T, D> const& p)
282 return p.get_ptr();
285 /* ///////////////////////////////////////////////////////////////////////
286 * Unit-testing
288 #ifdef EXTL_SCOPED_ARRAY_TEST_ENABLE
289 # include "unit_test/scoped_array_test.h"
290 #endif
292 /* ///////////////////////////////////////////////////////////////////////
293 * ::extl namespace
295 EXTL_END_NAMESPACE
297 /* ///////////////////////////////////////////////////////////////////////
298 * Warnings
300 #if defined(EXTL_COMPILER_IS_MSVC) && (_MSC_VER <= 1200)
301 # pragma warning(pop)
302 #endif
304 /* ///////////////////////////////////////////////////////////////////////
305 * std::swap
307 #if !defined(EXTL_NO_STL) && \
308 !defined(EXTL_NO_NAMESPACE)
309 /* ::std namespace */
310 EXTL_STD_BEGIN_NAMESPACE
312 template< typename_param_k T, typename_param_k D >
313 inline void swap(EXTL_NS(scoped_array)<T, D>& lhs, EXTL_NS(scoped_array)<T, D>& rhs)
315 lhs.swap(rhs);
317 /* ::std namespace */
318 EXTL_STD_END_NAMESPACE
319 #endif
321 /* //////////////////////////////////////////////////////////////////// */
322 #endif /* EXTL_SMART_PTR_SCOPED_ARRAY_H */
323 /* //////////////////////////////////////////////////////////////////// */