1 /* ///////////////////////////////////////////////////////////////////////
7 * Brief: scoped_array class - scoped array
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
20 * - default deleter: new_allocator<T>::array_deleter_type
21 * - custom deleter function object:
24 * void operator()(int *p)
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(...));
36 # error shared_ptr.h need be supported by c++.
39 /* ///////////////////////////////////////////////////////////////////////
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 /* ///////////////////////////////////////////////////////////////////////
52 #if defined(EXTL_COMPILER_IS_MSVC) && (_MSC_VER <= 1200)
53 # pragma warning(push)
54 # pragma warning(disable:4284) /* odd return type for operator-> */
57 /* ///////////////////////////////////////////////////////////////////////
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
82 typedef scoped_array
<T
, D
> class_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
;
97 /* Prohibit copy constructor and assignment
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
;
111 /// \name Constructors
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 */
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());
150 reference
operator[](index_type
const& index
) const
152 EXTL_ASSERT(NULL
!= m_ptr
);
153 EXTL_ASSERT(index
>= 0);
154 EXTL_ASSERT(is_valid());
158 const_pointer
get_ptr() const
160 EXTL_ASSERT(is_valid());
165 EXTL_ASSERT(is_valid());
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());
190 /* Reset the pointer */
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
>
204 EXTL_ASSERT(p
!= m_ptr
);
205 class_type(p
).swap(*this);
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
); }
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
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
; }
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 /* ///////////////////////////////////////////////////////////////////////
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
);
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
)
272 template< typename_param_k T
, typename_param_k D
>
273 inline void swap(scoped_array
<T
, D
>& lhs
, scoped_array
<T
, D
>& rhs
)
279 template< typename_param_k T
, typename_param_k D
>
280 inline T
const* get_ptr(scoped_array
<T
, D
> const& p
)
285 /* ///////////////////////////////////////////////////////////////////////
288 #ifdef EXTL_SCOPED_ARRAY_TEST_ENABLE
289 # include "unit_test/scoped_array_test.h"
292 /* ///////////////////////////////////////////////////////////////////////
297 /* ///////////////////////////////////////////////////////////////////////
300 #if defined(EXTL_COMPILER_IS_MSVC) && (_MSC_VER <= 1200)
301 # pragma warning(pop)
304 /* ///////////////////////////////////////////////////////////////////////
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
)
317 /* ::std namespace */
318 EXTL_STD_END_NAMESPACE
321 /* //////////////////////////////////////////////////////////////////// */
322 #endif /* EXTL_SMART_PTR_SCOPED_ARRAY_H */
323 /* //////////////////////////////////////////////////////////////////// */