2
// ***********************************************************************
4
// Teuchos: Common Tools Package
5
// Copyright (2004) Sandia Corporation
7
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8
// license for use of this work by or on behalf of the U.S. Government.
10
// This library is free software; you can redistribute it and/or modify
11
// it under the terms of the GNU Lesser General Public License as
12
// published by the Free Software Foundation; either version 2.1 of the
13
// License, or (at your option) any later version.
15
// This library is distributed in the hope that it will be useful, but
16
// WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
// Lesser General Public License for more details.
20
// You should have received a copy of the GNU Lesser General Public
21
// License along with this library; if not, write to the Free Software
22
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
26
// ***********************************************************************
30
#ifndef TEUCHOS_PTR_DECL_HPP
31
#define TEUCHOS_PTR_DECL_HPP
34
#include "Teuchos_RCPDecl.hpp"
35
#include "Teuchos_dyn_cast.hpp"
41
/** \brief Simple wrapper class for raw pointers to single objects where no
42
* persisting relationship exists.
44
* This class is meant to replace all but the lowest-level use of raw pointers
45
* that point to single objects where the use of <tt>RCP</tt> is not justified
46
* for performance or semantic reasons. When built in optimized mode, this
47
* class should impart little time overhead and should be exactly equivalent
48
* in the memory footprint to a raw C++ pointer and the only extra runtime
49
* overhead will be the default initalization to NULL.
51
* The main advantages of using this class over a raw pointer however are:
55
* <li> <tt>Ptr</tt> objects always default construct to null
57
* <li> <tt>Ptr</tt> objects will throw exceptions on attempts to dereference
58
* the underlying null pointer when debugging support is compiled in.
60
* <li> <tt>Ptr</tt> does not allow array-like operations like
61
* <tt>ptr[i]</tt>, <tt>++ptr</tt> or <tt>ptr+i</tt> that can only result in
62
* disaster when the a pointer points to only a single object that can not be
63
* assumed to be part of an array of objects.
65
* <li> <tt>Ptr</tt> is part of a system of types defined in <tt>Teuchos</tt>
66
* that keeps your code away from raw pointers which are the cause of most
67
* defects in C++ code.
71
* Debugging support is compiled in when the macro <tt>TEUCHOS_DEBUG</tt> is
72
* defined which happens automatically when <tt>--enable-teuchos-debug</tt> is
73
* specified on the configure line. When debugging support is not compiled
74
* in, the only overhead imparted by this class is it's default initialization
75
* to null. Therefore, this class can provide for very high performance on
76
* optimized builds of the code.
78
* An implicit conversion from a raw pointer to a <tt>Ptr</tt> object is okay
79
* since we don't assume any ownership of the object, hense the constructor
80
* taking a raw pointer is not declared explicit. However, this class does
81
* not support an implicit conversion to a raw pointer since we want to limit
82
* the exposure of raw pointers in our software. If we have to convert back
83
* to a raw pointer, then we want to make that explicit by calling
86
* This class should be used to replace most raw uses of C++ pointers to
87
* single objects where using the <tt>RCP</tt> class is not appropriate,
88
* unless the runtime cost of null-initialization it too expensive.
94
/** \brief Default construct to NULL.
96
* <b>Postconditons:</b><ul>
97
* <li> <tt>this->get() == NULL</tt>
100
inline Ptr( ENull null_in = null );
102
/** \brief Construct given a raw pointer.
104
* <b>Postconditons:</b><ul>
105
* <li> <tt>this->get() == ptr</tt>
108
* Note: This constructor is declared <tt>explicit</tt> so there is no
109
* implicit conversion from a raw C++ pointer to a <tt>Ptr</tt> object.
110
* This is meant to avoid cases where an uninitialized pointer is used to
111
* implicitly initialize one of these objects.
113
inline explicit Ptr( T *ptr );
115
/** \brief Copy construct from same type.
117
* <b>Postconditons:</b><ul>
118
* <li> <tt>this->get() == ptr.get()</tt>
121
inline Ptr(const Ptr<T>& ptr);
123
/** \brief Copy construct from another type.
125
* <b>Postconditons:</b><ul>
126
* <li> <tt>this->get() == ptr.get()</tt> (unless virtual base classes
131
inline Ptr(const Ptr<T2>& ptr);
133
/** \brief Shallow copy of the underlying pointer.
135
* <b>Postconditons:</b><ul>
136
* <li> <tt>this->get() == ptr.get()</tt>
139
Ptr<T>& operator=(const Ptr<T>& ptr);
141
/** \brief Pointer (<tt>-></tt>) access to members of underlying object.
143
* <b>Preconditions:</b><ul>
144
* <li> <tt>this->get() != NULL</tt> (throws <tt>std::logic_error</tt>)
147
inline T* operator->() const;
149
/** \brief Dereference the underlying object.
151
* <b>Preconditions:</b><ul>
152
* <li> <tt>this->get() != NULL</tt> (throws <tt>std::logic_error</tt>)
155
inline T& operator*() const;
157
/** \brief Get the raw C++ pointer to the underlying object. */
158
inline T* get() const;
160
/** \brief Get the raw C++ pointer to the underlying object. */
161
inline T* getRawPtr() const;
163
/** \brief Throws <tt>std::logic_error</tt> if <tt>this->get()==NULL</tt>,
164
* otherwise returns reference to <tt>*this</tt>.
166
inline const Ptr<T>& assert_not_null() const;
168
/** \brief Return a copy of *this. */
169
inline const Ptr<T> ptr() const;
179
void debug_assert_not_null() const
186
inline void debug_assert_valid_ptr() const;
188
public: // Bad bad bad
191
Ptr( const RCP<T> &p );
192
T* access_private_ptr() const
194
const RCP<T> access_rcp() const
202
/** \brief create a non-persisting (required or optional) output
203
* argument for a function call.
207
template<typename T> inline
208
Ptr<T> outArg( T& arg )
214
/** \brief create a non-persisting (required or optional) input/output
215
* argument for a function call.
219
template<typename T> inline
220
Ptr<T> inOutArg( T& arg )
226
/** \brief create a general <tt>Ptr</tt> input argument for a function call
231
template<typename T> inline
232
Ptr<const T> ptrInArg( T& arg )
234
return Ptr<const T>(&arg);
238
/** \brief create a non-persisting non-const optional input argument
243
template<typename T> inline
244
Ptr<T> optInArg( T& arg )
250
/** \brief create a non-persisting const optional input argument for a
255
template<typename T> inline
256
Ptr<const T> constOptInArg( T& arg )
258
return Ptr<const T>(&arg);
262
/** \brief Create a pointer to a object from an object reference.
266
template<typename T> inline
267
Ptr<T> ptrFromRef( T& arg )
273
/** \brief Create an RCP<T> from a Ptr<T> object.
277
template<typename T> inline
278
RCP<T> rcpFromPtr( const Ptr<T>& ptr )
283
// In a debug build, just grab out the WEAK RCP and return it. That way we
284
// can get dangling reference checking without having to turn on more
285
// expensive RCPNode tracing.
286
if (!is_null(ptr.access_rcp()))
287
return ptr.access_rcp();
289
return rcpFromRef(*ptr);
293
/** \brief Create a pointer to an object from a raw pointer.
297
template<typename T> inline
304
/** \brief Create a pointer from a const object given a non-const object
307
* <b>Warning!</b> Do not call this function if <tt>T</tt> is already const or
308
* a compilation error will occur!
312
template<typename T> inline
313
Ptr<const T> constPtr( T& arg )
315
return Ptr<const T>(&arg);
319
/** \brief Returns true if <tt>p.get()==NULL</tt>.
323
template<class T> inline
324
bool is_null( const Ptr<T> &p )
330
/** \brief Returns true if <tt>p.get()!=NULL</tt>
334
template<class T> inline
335
bool nonnull( const Ptr<T> &p )
341
/** \brief Returns true if <tt>p.get()==NULL</tt>.
345
template<class T> inline
346
bool operator==( const Ptr<T> &p, ENull )
352
/** \brief Returns true if <tt>p.get()!=NULL</tt>.
357
bool operator!=( const Ptr<T> &p, ENull )
363
/** \brief Return true if two <tt>Ptr</tt> objects point to the same object.
367
template<class T1, class T2>
368
bool operator==( const Ptr<T1> &p1, const Ptr<T2> &p2 )
370
return p1.get() == p2.get();
374
/** \brief Return true if two <tt>Ptr</tt> objects do not point to the same
379
template<class T1, class T2>
380
bool operator!=( const Ptr<T1> &p1, const Ptr<T2> &p2 )
382
return p1.get() != p2.get();
386
/** \brief Implicit cast of underlying <tt>Ptr</tt> type from <tt>T1*</tt> to
389
* The function will compile only if (<tt>T2* p2 = p1.get();</tt>) compiles.
391
* This is to be used for conversions up an inheritance hierarchy and from
392
* non-const to const and any other standard implicit pointer conversions
397
template<class T2, class T1>
398
Ptr<T2> ptr_implicit_cast(const Ptr<T1>& p1)
400
return Ptr<T2>(p1.get()); // Will only compile if conversion is legal!
404
/** \brief Static cast of underlying <tt>Ptr</tt> type from <tt>T1*</tt> to
407
* The function will compile only if (<tt>static_cast<T2*>(p1.get());</tt>)
410
* This can safely be used for conversion down an inheritance hierarchy with
411
* polymorphic types only if <tt>dynamic_cast<T2>(p1.get()) ==
412
* static_cast<T2>(p1.get())</tt>. If not then you have to use
413
* <tt>ptr_dynamic_cast<tt><T2>(p1)</tt>.
417
template<class T2, class T1>
418
Ptr<T2> ptr_static_cast(const Ptr<T1>& p1)
420
return Ptr<T2>(static_cast<T2*>(p1.get())); // Will only compile if conversion is legal!
424
/** \brief Constant cast of underlying <tt>Ptr</tt> type from <tt>T1*</tt> to
427
* This function will compile only if (<tt>const_cast<T2*>(p1.get());</tt>)
432
template<class T2, class T1>
433
Ptr<T2> ptr_const_cast(const Ptr<T1>& p1)
435
return Ptr<T2>(const_cast<T2*>(p1.get())); // Will only compile if conversion is legal!
439
/** \brief Dynamic cast of underlying <tt>Ptr</tt> type from <tt>T1*</tt> to
442
* \param p1 [in] The smart pointer casting from
444
* \param throw_on_fail [in] If <tt>true</tt> then if the cast fails (for
445
* <tt>p1.get()!=NULL) then a <tt>std::bad_cast</tt> std::exception is thrown
446
* with a very informative error message.
448
* <b>Postconditions:</b><ul>
449
* <li> If <tt>( p1.get()!=NULL && throw_on_fail==true && dynamic_cast<T2*>(p1.get())==NULL ) == true</tt>
450
* then an <tt>std::bad_cast</tt> std::exception is thrown with a very informative error message.
451
* <li> If <tt>( p1.get()!=NULL && dynamic_cast<T2*>(p1.get())!=NULL ) == true</tt>
452
* then <tt>return.get() == dynamic_cast<T2*>(p1.get())</tt>.
453
* <li> If <tt>( p1.get()!=NULL && throw_on_fail==false && dynamic_cast<T2*>(p1.get())==NULL ) == true</tt>
454
* then <tt>return.get() == NULL</tt>.
455
* <li> If <tt>( p1.get()==NULL ) == true</tt>
456
* then <tt>return.get() == NULL</tt>.
459
* This function will compile only if (<tt>dynamic_cast<T2*>(p1.get());</tt>)
464
template<class T2, class T1>
465
Ptr<T2> ptr_dynamic_cast(
466
const Ptr<T1>& p1, bool throw_on_fail = false
472
check = &dyn_cast<T2>(*p1);
474
check = dynamic_cast<T2*>(p1.get());
476
return Ptr<T2>(check);
483
/** \brief Output stream inserter.
485
* The implementation of this function just print pointer addresses and
486
* therefore puts no restrictions on the data types involved.
491
std::ostream& operator<<( std::ostream& out, const Ptr<T>& p );
494
} // namespace Teuchos
497
#endif // TEUCHOS_PTR_DECL_HPP