1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Scott Collins <scc@mozilla.org> (original author of nsCOMPtr)
24 * L. David Baron <dbaron@dbaron.org>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #ifndef nsAutoPtr_h___
41 #define nsAutoPtr_h___
43 // Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
45 // For |already_AddRefed|, |NSCAP_Zero|,
46 // |NSCAP_DONT_PROVIDE_NONCONST_OPEQ|,
47 // |NSCAP_FEATURE_INLINE_STARTASSIGNMENT|
51 /*****************************************************************************/
53 // template <class T> class nsAutoPtrGetterTransfers;
63 return reinterpret_cast<void**>(&mRawPtr
);
74 // |class Ptr| helps us prevent implicit "copy construction"
75 // through |operator T*() const| from a |const nsAutoPtr<T>|
76 // because two implicit conversions in a row aren't allowed.
77 // It still allows assignment from T* through implicit conversion
78 // from |T*| to |nsAutoPtr<T>::Ptr|
100 typedef T element_type
;
111 // default constructor
115 nsAutoPtr( Ptr aRawPtr
)
117 // construct from a raw pointer (of the right type)
121 nsAutoPtr( nsAutoPtr
<T
>& aSmartPtr
)
122 : mRawPtr( aSmartPtr
.forget() )
123 // Construct by transferring ownership from another smart pointer.
128 // Assignment operators
132 // assign from a raw pointer (of the right type)
138 nsAutoPtr
<T
>& operator=( nsAutoPtr
<T
>& rhs
)
139 // assign by transferring ownership from another smart pointer.
141 assign(rhs
.forget());
145 // Other pointer operators
150 Prefer the implicit conversion provided automatically by
151 |operator T*() const|. Use |get()| _only_ to resolve
160 ...makes an |nsAutoPtr| act like its underlying raw pointer
161 type whenever it is used in a context where a raw pointer
162 is expected. It is this operator that makes an |nsAutoPtr|
163 substitutable for a raw pointer.
165 Prefer the implicit use of this operator to calling |get()|,
166 except where necessary to resolve ambiguity.
183 NS_PRECONDITION(mRawPtr
!= 0, "You can't dereference a NULL nsAutoPtr with operator->().");
187 #ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
188 // broken version for IRIX
192 // This is not intended to be used by clients. See |address_of|
195 return const_cast<nsAutoPtr
<T
>*>(this);
198 #else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
202 // This is not intended to be used by clients. See |address_of|
210 // This is not intended to be used by clients. See |address_of|
216 #endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
222 NS_PRECONDITION(mRawPtr
!= 0, "You can't dereference a NULL nsAutoPtr with operator*().");
229 #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
230 return reinterpret_cast<T
**>(begin_assignment());
233 return reinterpret_cast<T
**>(&mRawPtr
);
238 #ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
240 // This is the broken version for IRIX, which can't handle the version below.
245 address_of( const nsAutoPtr
<T
>& aPtr
)
247 return aPtr
.get_address();
250 #else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
255 address_of( nsAutoPtr
<T
>& aPtr
)
257 return aPtr
.get_address();
263 address_of( const nsAutoPtr
<T
>& aPtr
)
265 return aPtr
.get_address();
268 #endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
271 class nsAutoPtrGetterTransfers
275 This class is designed to be used for anonymous temporary objects in the
276 argument list of calls that return COM interface pointers, e.g.,
278 nsAutoPtr<IFoo> fooP;
279 ...->GetTransferedPointer(getter_Transfers(fooP))
281 DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_Transfers()| instead.
283 When initialized with a |nsAutoPtr|, as in the example above, it returns
284 a |void**|, a |T**|, or an |nsISupports**| as needed, that the
285 outer call (|GetTransferedPointer| in this case) can fill in.
287 This type should be a nested class inside |nsAutoPtr<T>|.
292 nsAutoPtrGetterTransfers( nsAutoPtr
<T
>& aSmartPtr
)
293 : mTargetSmartPtr(aSmartPtr
)
295 // nothing else to do
300 return reinterpret_cast<void**>(mTargetSmartPtr
.StartAssignment());
305 return mTargetSmartPtr
.StartAssignment();
311 return *(mTargetSmartPtr
.StartAssignment());
315 nsAutoPtr
<T
>& mTargetSmartPtr
;
320 nsAutoPtrGetterTransfers
<T
>
321 getter_Transfers( nsAutoPtr
<T
>& aSmartPtr
)
323 Used around a |nsAutoPtr| when
324 ...makes the class |nsAutoPtrGetterTransfers<T>| invisible.
327 return nsAutoPtrGetterTransfers
<T
>(aSmartPtr
);
332 // Comparing two |nsAutoPtr|s
334 template <class T
, class U
>
337 operator==( const nsAutoPtr
<T
>& lhs
, const nsAutoPtr
<U
>& rhs
)
339 return static_cast<const T
*>(lhs
.get()) == static_cast<const U
*>(rhs
.get());
343 template <class T
, class U
>
346 operator!=( const nsAutoPtr
<T
>& lhs
, const nsAutoPtr
<U
>& rhs
)
348 return static_cast<const T
*>(lhs
.get()) != static_cast<const U
*>(rhs
.get());
352 // Comparing an |nsAutoPtr| to a raw pointer
354 template <class T
, class U
>
357 operator==( const nsAutoPtr
<T
>& lhs
, const U
* rhs
)
359 return static_cast<const T
*>(lhs
.get()) == static_cast<const U
*>(rhs
);
362 template <class T
, class U
>
365 operator==( const U
* lhs
, const nsAutoPtr
<T
>& rhs
)
367 return static_cast<const U
*>(lhs
) == static_cast<const T
*>(rhs
.get());
370 template <class T
, class U
>
373 operator!=( const nsAutoPtr
<T
>& lhs
, const U
* rhs
)
375 return static_cast<const T
*>(lhs
.get()) != static_cast<const U
*>(rhs
);
378 template <class T
, class U
>
381 operator!=( const U
* lhs
, const nsAutoPtr
<T
>& rhs
)
383 return static_cast<const U
*>(lhs
) != static_cast<const T
*>(rhs
.get());
386 // To avoid ambiguities caused by the presence of builtin |operator==|s
387 // creating a situation where one of the |operator==| defined above
388 // has a better conversion for one argument and the builtin has a
389 // better conversion for the other argument, define additional
390 // |operator==| without the |const| on the raw pointer.
391 // See bug 65664 for details.
393 #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
394 template <class T
, class U
>
397 operator==( const nsAutoPtr
<T
>& lhs
, U
* rhs
)
399 return static_cast<const T
*>(lhs
.get()) == const_cast<const U
*>(rhs
);
402 template <class T
, class U
>
405 operator==( U
* lhs
, const nsAutoPtr
<T
>& rhs
)
407 return const_cast<const U
*>(lhs
) == static_cast<const T
*>(rhs
.get());
410 template <class T
, class U
>
413 operator!=( const nsAutoPtr
<T
>& lhs
, U
* rhs
)
415 return static_cast<const T
*>(lhs
.get()) != const_cast<const U
*>(rhs
);
418 template <class T
, class U
>
421 operator!=( U
* lhs
, const nsAutoPtr
<T
>& rhs
)
423 return const_cast<const U
*>(lhs
) != static_cast<const T
*>(rhs
.get());
429 // Comparing an |nsAutoPtr| to |0|
434 operator==( const nsAutoPtr
<T
>& lhs
, NSCAP_Zero
* rhs
)
435 // specifically to allow |smartPtr == 0|
437 return static_cast<const void*>(lhs
.get()) == reinterpret_cast<const void*>(rhs
);
443 operator==( NSCAP_Zero
* lhs
, const nsAutoPtr
<T
>& rhs
)
444 // specifically to allow |0 == smartPtr|
446 return reinterpret_cast<const void*>(lhs
) == static_cast<const void*>(rhs
.get());
452 operator!=( const nsAutoPtr
<T
>& lhs
, NSCAP_Zero
* rhs
)
453 // specifically to allow |smartPtr != 0|
455 return static_cast<const void*>(lhs
.get()) != reinterpret_cast<const void*>(rhs
);
461 operator!=( NSCAP_Zero
* lhs
, const nsAutoPtr
<T
>& rhs
)
462 // specifically to allow |0 != smartPtr|
464 return reinterpret_cast<const void*>(lhs
) != static_cast<const void*>(rhs
.get());
468 #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
470 // We need to explicitly define comparison operators for `int'
471 // because the compiler is lame.
476 operator==( const nsAutoPtr
<T
>& lhs
, int rhs
)
477 // specifically to allow |smartPtr == 0|
479 return static_cast<const void*>(lhs
.get()) == reinterpret_cast<const void*>(rhs
);
485 operator==( int lhs
, const nsAutoPtr
<T
>& rhs
)
486 // specifically to allow |0 == smartPtr|
488 return reinterpret_cast<const void*>(lhs
) == static_cast<const void*>(rhs
.get());
491 #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
493 /*****************************************************************************/
495 // template <class T> class nsAutoArrayPtrGetterTransfers;
505 return reinterpret_cast<void**>(&mRawPtr
);
520 typedef T element_type
;
531 // default constructor
535 nsAutoArrayPtr( T
* aRawPtr
)
537 // construct from a raw pointer (of the right type)
541 nsAutoArrayPtr( nsAutoArrayPtr
<T
>& aSmartPtr
)
542 : mRawPtr( aSmartPtr
.forget() )
543 // Construct by transferring ownership from another smart pointer.
548 // Assignment operators
552 // assign from a raw pointer (of the right type)
558 nsAutoArrayPtr
<T
>& operator=( nsAutoArrayPtr
<T
>& rhs
)
559 // assign by transferring ownership from another smart pointer.
561 assign(rhs
.forget());
565 // Other pointer operators
570 Prefer the implicit conversion provided automatically by
571 |operator T*() const|. Use |get()| _only_ to resolve
580 ...makes an |nsAutoArrayPtr| act like its underlying raw pointer
581 type whenever it is used in a context where a raw pointer
582 is expected. It is this operator that makes an |nsAutoArrayPtr|
583 substitutable for a raw pointer.
585 Prefer the implicit use of this operator to calling |get()|,
586 except where necessary to resolve ambiguity.
603 NS_PRECONDITION(mRawPtr
!= 0, "You can't dereference a NULL nsAutoArrayPtr with operator->().");
607 #ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
608 // broken version for IRIX
612 // This is not intended to be used by clients. See |address_of|
615 return const_cast<nsAutoArrayPtr
<T
>*>(this);
618 #else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
622 // This is not intended to be used by clients. See |address_of|
628 const nsAutoArrayPtr
<T
>*
630 // This is not intended to be used by clients. See |address_of|
636 #endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
642 NS_PRECONDITION(mRawPtr
!= 0, "You can't dereference a NULL nsAutoArrayPtr with operator*().");
649 #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
650 return reinterpret_cast<T
**>(begin_assignment());
653 return reinterpret_cast<T
**>(&mRawPtr
);
658 #ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
660 // This is the broken version for IRIX, which can't handle the version below.
665 address_of( const nsAutoArrayPtr
<T
>& aPtr
)
667 return aPtr
.get_address();
670 #else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
675 address_of( nsAutoArrayPtr
<T
>& aPtr
)
677 return aPtr
.get_address();
682 const nsAutoArrayPtr
<T
>*
683 address_of( const nsAutoArrayPtr
<T
>& aPtr
)
685 return aPtr
.get_address();
688 #endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
691 class nsAutoArrayPtrGetterTransfers
695 This class is designed to be used for anonymous temporary objects in the
696 argument list of calls that return COM interface pointers, e.g.,
698 nsAutoArrayPtr<IFoo> fooP;
699 ...->GetTransferedPointer(getter_Transfers(fooP))
701 DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_Transfers()| instead.
703 When initialized with a |nsAutoArrayPtr|, as in the example above, it returns
704 a |void**|, a |T**|, or an |nsISupports**| as needed, that the
705 outer call (|GetTransferedPointer| in this case) can fill in.
707 This type should be a nested class inside |nsAutoArrayPtr<T>|.
712 nsAutoArrayPtrGetterTransfers( nsAutoArrayPtr
<T
>& aSmartPtr
)
713 : mTargetSmartPtr(aSmartPtr
)
715 // nothing else to do
720 return reinterpret_cast<void**>(mTargetSmartPtr
.StartAssignment());
725 return mTargetSmartPtr
.StartAssignment();
731 return *(mTargetSmartPtr
.StartAssignment());
735 nsAutoArrayPtr
<T
>& mTargetSmartPtr
;
740 nsAutoArrayPtrGetterTransfers
<T
>
741 getter_Transfers( nsAutoArrayPtr
<T
>& aSmartPtr
)
743 Used around a |nsAutoArrayPtr| when
744 ...makes the class |nsAutoArrayPtrGetterTransfers<T>| invisible.
747 return nsAutoArrayPtrGetterTransfers
<T
>(aSmartPtr
);
752 // Comparing two |nsAutoArrayPtr|s
754 template <class T
, class U
>
757 operator==( const nsAutoArrayPtr
<T
>& lhs
, const nsAutoArrayPtr
<U
>& rhs
)
759 return static_cast<const T
*>(lhs
.get()) == static_cast<const U
*>(rhs
.get());
763 template <class T
, class U
>
766 operator!=( const nsAutoArrayPtr
<T
>& lhs
, const nsAutoArrayPtr
<U
>& rhs
)
768 return static_cast<const T
*>(lhs
.get()) != static_cast<const U
*>(rhs
.get());
772 // Comparing an |nsAutoArrayPtr| to a raw pointer
774 template <class T
, class U
>
777 operator==( const nsAutoArrayPtr
<T
>& lhs
, const U
* rhs
)
779 return static_cast<const T
*>(lhs
.get()) == static_cast<const U
*>(rhs
);
782 template <class T
, class U
>
785 operator==( const U
* lhs
, const nsAutoArrayPtr
<T
>& rhs
)
787 return static_cast<const U
*>(lhs
) == static_cast<const T
*>(rhs
.get());
790 template <class T
, class U
>
793 operator!=( const nsAutoArrayPtr
<T
>& lhs
, const U
* rhs
)
795 return static_cast<const T
*>(lhs
.get()) != static_cast<const U
*>(rhs
);
798 template <class T
, class U
>
801 operator!=( const U
* lhs
, const nsAutoArrayPtr
<T
>& rhs
)
803 return static_cast<const U
*>(lhs
) != static_cast<const T
*>(rhs
.get());
806 // To avoid ambiguities caused by the presence of builtin |operator==|s
807 // creating a situation where one of the |operator==| defined above
808 // has a better conversion for one argument and the builtin has a
809 // better conversion for the other argument, define additional
810 // |operator==| without the |const| on the raw pointer.
811 // See bug 65664 for details.
813 #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
814 template <class T
, class U
>
817 operator==( const nsAutoArrayPtr
<T
>& lhs
, U
* rhs
)
819 return static_cast<const T
*>(lhs
.get()) == const_cast<const U
*>(rhs
);
822 template <class T
, class U
>
825 operator==( U
* lhs
, const nsAutoArrayPtr
<T
>& rhs
)
827 return const_cast<const U
*>(lhs
) == static_cast<const T
*>(rhs
.get());
830 template <class T
, class U
>
833 operator!=( const nsAutoArrayPtr
<T
>& lhs
, U
* rhs
)
835 return static_cast<const T
*>(lhs
.get()) != const_cast<const U
*>(rhs
);
838 template <class T
, class U
>
841 operator!=( U
* lhs
, const nsAutoArrayPtr
<T
>& rhs
)
843 return const_cast<const U
*>(lhs
) != static_cast<const T
*>(rhs
.get());
849 // Comparing an |nsAutoArrayPtr| to |0|
854 operator==( const nsAutoArrayPtr
<T
>& lhs
, NSCAP_Zero
* rhs
)
855 // specifically to allow |smartPtr == 0|
857 return static_cast<const void*>(lhs
.get()) == reinterpret_cast<const void*>(rhs
);
863 operator==( NSCAP_Zero
* lhs
, const nsAutoArrayPtr
<T
>& rhs
)
864 // specifically to allow |0 == smartPtr|
866 return reinterpret_cast<const void*>(lhs
) == static_cast<const void*>(rhs
.get());
872 operator!=( const nsAutoArrayPtr
<T
>& lhs
, NSCAP_Zero
* rhs
)
873 // specifically to allow |smartPtr != 0|
875 return static_cast<const void*>(lhs
.get()) != reinterpret_cast<const void*>(rhs
);
881 operator!=( NSCAP_Zero
* lhs
, const nsAutoArrayPtr
<T
>& rhs
)
882 // specifically to allow |0 != smartPtr|
884 return reinterpret_cast<const void*>(lhs
) != static_cast<const void*>(rhs
.get());
888 #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
890 // We need to explicitly define comparison operators for `int'
891 // because the compiler is lame.
896 operator==( const nsAutoArrayPtr
<T
>& lhs
, int rhs
)
897 // specifically to allow |smartPtr == 0|
899 return static_cast<const void*>(lhs
.get()) == reinterpret_cast<const void*>(rhs
);
905 operator==( int lhs
, const nsAutoArrayPtr
<T
>& rhs
)
906 // specifically to allow |0 == smartPtr|
908 return reinterpret_cast<const void*>(lhs
) == static_cast<const void*>(rhs
.get());
911 #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
914 /*****************************************************************************/
916 // template <class T> class nsRefPtrGetterAddRefs;
924 assign_with_AddRef( T
* rawPtr
)
928 assign_assuming_AddRef(rawPtr
);
934 assign_assuming_AddRef(0);
935 return reinterpret_cast<void**>(&mRawPtr
);
939 assign_assuming_AddRef( T
* newPtr
)
951 typedef T element_type
;
963 // default constructor
967 nsRefPtr( const nsRefPtr
<T
>& aSmartPtr
)
968 : mRawPtr(aSmartPtr
.mRawPtr
)
975 nsRefPtr( T
* aRawPtr
)
977 // construct from a raw pointer (of the right type)
983 nsRefPtr( const already_AddRefed
<T
>& aSmartPtr
)
984 : mRawPtr(aSmartPtr
.mRawPtr
)
985 // construct from |dont_AddRef(expr)|
989 // Assignment operators
992 operator=( const nsRefPtr
<T
>& rhs
)
993 // copy assignment operator
995 assign_with_AddRef(rhs
.mRawPtr
);
1001 // assign from a raw pointer (of the right type)
1003 assign_with_AddRef(rhs
);
1008 operator=( const already_AddRefed
<T
>& rhs
)
1009 // assign from |dont_AddRef(expr)|
1011 assign_assuming_AddRef(rhs
.mRawPtr
);
1015 // Other pointer operators
1018 swap( nsRefPtr
<T
>& rhs
)
1019 // ...exchange ownership with |rhs|; can save a pair of refcount operations
1021 T
* temp
= rhs
.mRawPtr
;
1022 rhs
.mRawPtr
= mRawPtr
;
1028 // ...exchange ownership with |rhs|; can save a pair of refcount operations
1037 // return the value of mRawPtr and null out mRawPtr. Useful for
1038 // already_AddRefed return values.
1047 // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
1048 // Useful to avoid unnecessary AddRef/Release pairs with "out"
1051 NS_ASSERTION(rhs
, "Null pointer passed to forget!");
1059 Prefer the implicit conversion provided automatically by |operator T*() const|.
1060 Use |get()| to resolve ambiguity or to get a castable pointer.
1063 return const_cast<T
*>(mRawPtr
);
1068 ...makes an |nsRefPtr| act like its underlying raw pointer type whenever it
1069 is used in a context where a raw pointer is expected. It is this operator
1070 that makes an |nsRefPtr| substitutable for a raw pointer.
1072 Prefer the implicit use of this operator to calling |get()|, except where
1073 necessary to resolve ambiguity.
1082 NS_PRECONDITION(mRawPtr
!= 0, "You can't dereference a NULL nsRefPtr with operator->().");
1086 #ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
1087 // broken version for IRIX
1091 // This is not intended to be used by clients. See |address_of|
1094 return const_cast<nsRefPtr
<T
>*>(this);
1097 #else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
1101 // This is not intended to be used by clients. See |address_of|
1109 // This is not intended to be used by clients. See |address_of|
1115 #endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
1121 NS_PRECONDITION(mRawPtr
!= 0, "You can't dereference a NULL nsRefPtr with operator*().");
1128 #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
1129 return reinterpret_cast<T
**>(begin_assignment());
1131 assign_assuming_AddRef(0);
1132 return reinterpret_cast<T
**>(&mRawPtr
);
1137 #ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
1139 // This is the broken version for IRIX, which can't handle the version below.
1144 address_of( const nsRefPtr
<T
>& aPtr
)
1146 return aPtr
.get_address();
1149 #else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
1154 address_of( nsRefPtr
<T
>& aPtr
)
1156 return aPtr
.get_address();
1162 address_of( const nsRefPtr
<T
>& aPtr
)
1164 return aPtr
.get_address();
1167 #endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
1170 class nsRefPtrGetterAddRefs
1174 This class is designed to be used for anonymous temporary objects in the
1175 argument list of calls that return COM interface pointers, e.g.,
1177 nsRefPtr<IFoo> fooP;
1178 ...->GetAddRefedPointer(getter_AddRefs(fooP))
1180 DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
1182 When initialized with a |nsRefPtr|, as in the example above, it returns
1183 a |void**|, a |T**|, or an |nsISupports**| as needed, that the
1184 outer call (|GetAddRefedPointer| in this case) can fill in.
1186 This type should be a nested class inside |nsRefPtr<T>|.
1191 nsRefPtrGetterAddRefs( nsRefPtr
<T
>& aSmartPtr
)
1192 : mTargetSmartPtr(aSmartPtr
)
1194 // nothing else to do
1199 return reinterpret_cast<void**>(mTargetSmartPtr
.StartAssignment());
1204 return mTargetSmartPtr
.StartAssignment();
1210 return *(mTargetSmartPtr
.StartAssignment());
1214 nsRefPtr
<T
>& mTargetSmartPtr
;
1219 nsRefPtrGetterAddRefs
<T
>
1220 getter_AddRefs( nsRefPtr
<T
>& aSmartPtr
)
1222 Used around a |nsRefPtr| when
1223 ...makes the class |nsRefPtrGetterAddRefs<T>| invisible.
1226 return nsRefPtrGetterAddRefs
<T
>(aSmartPtr
);
1231 // Comparing two |nsRefPtr|s
1233 template <class T
, class U
>
1236 operator==( const nsRefPtr
<T
>& lhs
, const nsRefPtr
<U
>& rhs
)
1238 return static_cast<const T
*>(lhs
.get()) == static_cast<const U
*>(rhs
.get());
1242 template <class T
, class U
>
1245 operator!=( const nsRefPtr
<T
>& lhs
, const nsRefPtr
<U
>& rhs
)
1247 return static_cast<const T
*>(lhs
.get()) != static_cast<const U
*>(rhs
.get());
1251 // Comparing an |nsRefPtr| to a raw pointer
1253 template <class T
, class U
>
1256 operator==( const nsRefPtr
<T
>& lhs
, const U
* rhs
)
1258 return static_cast<const T
*>(lhs
.get()) == static_cast<const U
*>(rhs
);
1261 template <class T
, class U
>
1264 operator==( const U
* lhs
, const nsRefPtr
<T
>& rhs
)
1266 return static_cast<const U
*>(lhs
) == static_cast<const T
*>(rhs
.get());
1269 template <class T
, class U
>
1272 operator!=( const nsRefPtr
<T
>& lhs
, const U
* rhs
)
1274 return static_cast<const T
*>(lhs
.get()) != static_cast<const U
*>(rhs
);
1277 template <class T
, class U
>
1280 operator!=( const U
* lhs
, const nsRefPtr
<T
>& rhs
)
1282 return static_cast<const U
*>(lhs
) != static_cast<const T
*>(rhs
.get());
1285 // To avoid ambiguities caused by the presence of builtin |operator==|s
1286 // creating a situation where one of the |operator==| defined above
1287 // has a better conversion for one argument and the builtin has a
1288 // better conversion for the other argument, define additional
1289 // |operator==| without the |const| on the raw pointer.
1290 // See bug 65664 for details.
1292 #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
1293 template <class T
, class U
>
1296 operator==( const nsRefPtr
<T
>& lhs
, U
* rhs
)
1298 return static_cast<const T
*>(lhs
.get()) == const_cast<const U
*>(rhs
);
1301 template <class T
, class U
>
1304 operator==( U
* lhs
, const nsRefPtr
<T
>& rhs
)
1306 return const_cast<const U
*>(lhs
) == static_cast<const T
*>(rhs
.get());
1309 template <class T
, class U
>
1312 operator!=( const nsRefPtr
<T
>& lhs
, U
* rhs
)
1314 return static_cast<const T
*>(lhs
.get()) != const_cast<const U
*>(rhs
);
1317 template <class T
, class U
>
1320 operator!=( U
* lhs
, const nsRefPtr
<T
>& rhs
)
1322 return const_cast<const U
*>(lhs
) != static_cast<const T
*>(rhs
.get());
1328 // Comparing an |nsRefPtr| to |0|
1333 operator==( const nsRefPtr
<T
>& lhs
, NSCAP_Zero
* rhs
)
1334 // specifically to allow |smartPtr == 0|
1336 return static_cast<const void*>(lhs
.get()) == reinterpret_cast<const void*>(rhs
);
1342 operator==( NSCAP_Zero
* lhs
, const nsRefPtr
<T
>& rhs
)
1343 // specifically to allow |0 == smartPtr|
1345 return reinterpret_cast<const void*>(lhs
) == static_cast<const void*>(rhs
.get());
1351 operator!=( const nsRefPtr
<T
>& lhs
, NSCAP_Zero
* rhs
)
1352 // specifically to allow |smartPtr != 0|
1354 return static_cast<const void*>(lhs
.get()) != reinterpret_cast<const void*>(rhs
);
1360 operator!=( NSCAP_Zero
* lhs
, const nsRefPtr
<T
>& rhs
)
1361 // specifically to allow |0 != smartPtr|
1363 return reinterpret_cast<const void*>(lhs
) != static_cast<const void*>(rhs
.get());
1367 #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
1369 // We need to explicitly define comparison operators for `int'
1370 // because the compiler is lame.
1375 operator==( const nsRefPtr
<T
>& lhs
, int rhs
)
1376 // specifically to allow |smartPtr == 0|
1378 return static_cast<const void*>(lhs
.get()) == reinterpret_cast<const void*>(rhs
);
1384 operator==( int lhs
, const nsRefPtr
<T
>& rhs
)
1385 // specifically to allow |0 == smartPtr|
1387 return reinterpret_cast<const void*>(lhs
) == static_cast<const void*>(rhs
.get());
1390 #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
1392 /*****************************************************************************/
1394 #endif // !defined(nsAutoPtr_h___)