~chaffra/+junk/trilinos

« back to all changes in this revision

Viewing changes to packages/teuchos/src/Teuchos_PtrDecl.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme, Christophe Prud'homme, Johannes Ring
  • Date: 2009-12-13 12:53:22 UTC
  • mfrom: (5.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091213125322-in0nrdjc55deqsw9
Tags: 10.0.3.dfsg-1
[Christophe Prud'homme]
* New upstream release

[Johannes Ring]
* debian/patches/libname.patch: Add prefix 'libtrilinos_' to all
  libraries. 
* debian/patches/soname.patch: Add soversion to libraries.
* debian/watch: Update download URL.
* debian/control:
  - Remove python-numeric from Build-Depends (virtual package).
  - Remove automake and autotools from Build-Depends and add cmake to
    reflect switch to CMake.
  - Add python-support to Build-Depends.
* debian/rules: 
  - Cleanup and updates for switch to CMake.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// @HEADER
 
2
// ***********************************************************************
 
3
// 
 
4
//                    Teuchos: Common Tools Package
 
5
//                 Copyright (2004) Sandia Corporation
 
6
// 
 
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.
 
9
// 
 
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.
 
14
//  
 
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.
 
19
//  
 
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
 
23
// USA
 
24
// Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
 
25
// 
 
26
// ***********************************************************************
 
27
// @HEADER
 
28
 
 
29
 
 
30
#ifndef TEUCHOS_PTR_DECL_HPP
 
31
#define TEUCHOS_PTR_DECL_HPP
 
32
 
 
33
 
 
34
#include "Teuchos_RCPDecl.hpp"
 
35
#include "Teuchos_dyn_cast.hpp"
 
36
 
 
37
 
 
38
namespace Teuchos {
 
39
 
 
40
 
 
41
/** \brief Simple wrapper class for raw pointers to single objects where no
 
42
 * persisting relationship exists.
 
43
 *
 
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.
 
50
 *
 
51
 * The main advantages of using this class over a raw pointer however are:
 
52
 *
 
53
 * <ul>
 
54
 *
 
55
 * <li> <tt>Ptr</tt> objects always default construct to null
 
56
 *
 
57
 * <li> <tt>Ptr</tt> objects will throw exceptions on attempts to dereference
 
58
 * the underlying null pointer when debugging support is compiled in.
 
59
 *
 
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.
 
64
 *
 
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.
 
68
 *
 
69
 * </ul>
 
70
 *
 
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.
 
77
 *
 
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
 
84
 * <tt>get()</tt>.
 
85
 *
 
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.
 
89
 */
 
90
template<class T>
 
91
class Ptr {
 
92
public:
 
93
 
 
94
  /** \brief Default construct to NULL.
 
95
   *
 
96
   * <b>Postconditons:</b><ul>
 
97
   * <li> <tt>this->get() == NULL</tt>
 
98
   * </ul>
 
99
   */
 
100
  inline Ptr( ENull null_in = null );
 
101
 
 
102
  /** \brief Construct given a raw pointer.
 
103
   *
 
104
   * <b>Postconditons:</b><ul>
 
105
   * <li> <tt>this->get() == ptr</tt>
 
106
   * </ul>
 
107
   *
 
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.
 
112
   */
 
113
  inline explicit Ptr( T *ptr );
 
114
 
 
115
  /** \brief Copy construct from same type.
 
116
   *
 
117
   * <b>Postconditons:</b><ul>
 
118
   * <li> <tt>this->get() == ptr.get()</tt>
 
119
   * </ul>
 
120
   */
 
121
  inline Ptr(const Ptr<T>& ptr);
 
122
 
 
123
  /** \brief Copy construct from another type.
 
124
   *
 
125
   * <b>Postconditons:</b><ul>
 
126
   * <li> <tt>this->get() == ptr.get()</tt> (unless virtual base classes
 
127
   *      are involved)
 
128
   * </ul>
 
129
   */
 
130
  template<class T2>
 
131
  inline Ptr(const Ptr<T2>& ptr);
 
132
 
 
133
  /** \brief Shallow copy of the underlying pointer.
 
134
   *
 
135
   * <b>Postconditons:</b><ul>
 
136
   * <li> <tt>this->get() == ptr.get()</tt>
 
137
   * </ul>
 
138
   */
 
139
  Ptr<T>& operator=(const Ptr<T>& ptr);
 
140
 
 
141
  /** \brief Pointer (<tt>-></tt>) access to members of underlying object.
 
142
   *
 
143
   * <b>Preconditions:</b><ul>
 
144
   * <li> <tt>this->get() != NULL</tt> (throws <tt>std::logic_error</tt>)
 
145
   * </ul>
 
146
   */
 
147
  inline T* operator->() const;
 
148
 
 
149
  /** \brief Dereference the underlying object.
 
150
   *
 
151
   * <b>Preconditions:</b><ul>
 
152
   * <li> <tt>this->get() != NULL</tt> (throws <tt>std::logic_error</tt>)
 
153
   * </ul>
 
154
   */
 
155
  inline T& operator*() const;
 
156
 
 
157
  /** \brief Get the raw C++ pointer to the underlying object. */
 
158
  inline T* get() const;
 
159
 
 
160
  /** \brief Get the raw C++ pointer to the underlying object. */
 
161
  inline T* getRawPtr() const;
 
162
 
 
163
  /** \brief Throws <tt>std::logic_error</tt> if <tt>this->get()==NULL</tt>,
 
164
   * otherwise returns reference to <tt>*this</tt>.
 
165
   */
 
166
  inline const Ptr<T>& assert_not_null() const;
 
167
 
 
168
  /** \brief Return a copy of *this. */
 
169
  inline const Ptr<T> ptr() const;
 
170
 
 
171
private:
 
172
 
 
173
  T *ptr_;
 
174
 
 
175
#ifdef TEUCHOS_DEBUG
 
176
  RCP<T> rcp_;
 
177
#endif
 
178
 
 
179
  void debug_assert_not_null() const
 
180
    {
 
181
#ifdef TEUCHOS_DEBUG
 
182
      assert_not_null();
 
183
#endif
 
184
    }
 
185
 
 
186
  inline void debug_assert_valid_ptr() const;
 
187
 
 
188
public: // Bad bad bad
 
189
 
 
190
#ifdef TEUCHOS_DEBUG
 
191
  Ptr( const RCP<T> &p );
 
192
  T* access_private_ptr() const
 
193
    { return ptr_; }
 
194
  const RCP<T> access_rcp() const
 
195
    { return rcp_; }
 
196
#endif
 
197
 
 
198
 
 
199
};
 
200
 
 
201
 
 
202
/** \brief create a non-persisting (required or optional) output
 
203
 * argument for a function call.
 
204
 *
 
205
 * \relates Ptr
 
206
 */
 
207
template<typename T> inline
 
208
Ptr<T> outArg( T& arg )
 
209
{
 
210
  return Ptr<T>(&arg);
 
211
}
 
212
 
 
213
 
 
214
/** \brief create a non-persisting (required or optional) input/output
 
215
 * argument for a function call.
 
216
 *
 
217
 * \relates Ptr
 
218
 */
 
219
template<typename T> inline
 
220
Ptr<T> inOutArg( T& arg )
 
221
{
 
222
  return Ptr<T>(&arg);
 
223
}
 
224
 
 
225
 
 
226
/** \brief create a general <tt>Ptr</tt> input argument for a function call
 
227
 * from a reference.
 
228
 *
 
229
 * \relates Ptr
 
230
 */
 
231
template<typename T> inline
 
232
Ptr<const T> ptrInArg( T& arg )
 
233
{
 
234
  return Ptr<const T>(&arg);
 
235
}
 
236
 
 
237
 
 
238
/** \brief create a non-persisting non-const optional input argument
 
239
for a function call.
 
240
 *
 
241
 * \relates Ptr
 
242
 */
 
243
template<typename T> inline
 
244
Ptr<T> optInArg( T& arg )
 
245
{
 
246
  return Ptr<T>(&arg);
 
247
}
 
248
 
 
249
 
 
250
/** \brief create a non-persisting const optional input argument for a
 
251
function call.
 
252
 *
 
253
 * \relates Ptr
 
254
 */
 
255
template<typename T> inline
 
256
Ptr<const T> constOptInArg( T& arg )
 
257
{
 
258
  return Ptr<const T>(&arg);
 
259
}
 
260
 
 
261
 
 
262
/** \brief Create a pointer to a object from an object reference.
 
263
 *
 
264
 * \relates Ptr
 
265
 */
 
266
template<typename T> inline
 
267
Ptr<T> ptrFromRef( T& arg )
 
268
{
 
269
  return Ptr<T>(&arg);
 
270
}
 
271
 
 
272
 
 
273
/** \brief Create an RCP<T> from a Ptr<T> object.
 
274
 *
 
275
 * \relates RCP
 
276
 */
 
277
template<typename T> inline
 
278
RCP<T> rcpFromPtr( const Ptr<T>& ptr )
 
279
{
 
280
  if (is_null(ptr))
 
281
    return null;
 
282
#ifdef TEUCHOS_DEBUG
 
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();
 
288
#endif
 
289
  return rcpFromRef(*ptr);
 
290
}
 
291
 
 
292
 
 
293
/** \brief Create a pointer to an object from a raw pointer.
 
294
 *
 
295
 * \relates Ptr
 
296
 */
 
297
template<typename T> inline
 
298
Ptr<T> ptr( T* p )
 
299
{
 
300
  return Ptr<T>(p);
 
301
}
 
302
 
 
303
 
 
304
/** \brief Create a pointer from a const object given a non-const object
 
305
 * reference.
 
306
 *
 
307
 * <b>Warning!</b> Do not call this function if <tt>T</tt> is already const or
 
308
 * a compilation error will occur!
 
309
 *
 
310
 * \relates Ptr
 
311
 */
 
312
template<typename T> inline
 
313
Ptr<const T> constPtr( T& arg )
 
314
{
 
315
  return Ptr<const T>(&arg);
 
316
}
 
317
 
 
318
 
 
319
/** \brief Returns true if <tt>p.get()==NULL</tt>.
 
320
 *
 
321
 * \relates Ptr
 
322
 */
 
323
template<class T> inline
 
324
bool is_null( const Ptr<T> &p )
 
325
{
 
326
  return p.get() == 0;
 
327
}
 
328
 
 
329
 
 
330
/** \brief Returns true if <tt>p.get()!=NULL</tt>
 
331
 *
 
332
 * \relates Ptr
 
333
 */
 
334
template<class T> inline
 
335
bool nonnull( const Ptr<T> &p )
 
336
{
 
337
  return p.get() != 0;
 
338
}
 
339
 
 
340
 
 
341
/** \brief Returns true if <tt>p.get()==NULL</tt>.
 
342
 *
 
343
 * \relates Ptr
 
344
 */
 
345
template<class T> inline
 
346
bool operator==( const Ptr<T> &p, ENull )
 
347
{
 
348
  return p.get() == 0;
 
349
}
 
350
 
 
351
 
 
352
/** \brief Returns true if <tt>p.get()!=NULL</tt>.
 
353
 *
 
354
 * \relates Ptr
 
355
 */
 
356
template<class T>
 
357
bool operator!=( const Ptr<T> &p, ENull )
 
358
{
 
359
  return p.get() != 0;
 
360
}
 
361
 
 
362
 
 
363
/** \brief Return true if two <tt>Ptr</tt> objects point to the same object.
 
364
 *
 
365
 * \relates Ptr
 
366
 */
 
367
template<class T1, class T2>
 
368
bool operator==( const Ptr<T1> &p1, const Ptr<T2> &p2 )
 
369
{
 
370
  return p1.get() == p2.get();
 
371
}
 
372
 
 
373
 
 
374
/** \brief Return true if two <tt>Ptr</tt> objects do not point to the same
 
375
 * object.
 
376
 *
 
377
 * \relates Ptr
 
378
 */
 
379
template<class T1, class T2>
 
380
bool operator!=( const Ptr<T1> &p1, const Ptr<T2> &p2 )
 
381
{
 
382
  return p1.get() != p2.get();
 
383
}
 
384
 
 
385
 
 
386
/** \brief Implicit cast of underlying <tt>Ptr</tt> type from <tt>T1*</tt> to
 
387
 * <tt>T2*</tt>.
 
388
 *
 
389
 * The function will compile only if (<tt>T2* p2 = p1.get();</tt>) compiles.
 
390
 *
 
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
 
393
 * allowed by C++.
 
394
 *
 
395
 * \relates Ptr
 
396
 */
 
397
template<class T2, class T1>
 
398
Ptr<T2> ptr_implicit_cast(const Ptr<T1>& p1)
 
399
{
 
400
  return Ptr<T2>(p1.get()); // Will only compile if conversion is legal!
 
401
}
 
402
 
 
403
 
 
404
/** \brief Static cast of underlying <tt>Ptr</tt> type from <tt>T1*</tt> to
 
405
 * <tt>T2*</tt>.
 
406
 *
 
407
 * The function will compile only if (<tt>static_cast<T2*>(p1.get());</tt>)
 
408
 * compiles.
 
409
 *
 
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>.
 
414
 *
 
415
 * \relates Ptr
 
416
 */
 
417
template<class T2, class T1>
 
418
Ptr<T2> ptr_static_cast(const Ptr<T1>& p1)
 
419
{
 
420
  return Ptr<T2>(static_cast<T2*>(p1.get())); // Will only compile if conversion is legal!
 
421
}
 
422
 
 
423
 
 
424
/** \brief Constant cast of underlying <tt>Ptr</tt> type from <tt>T1*</tt> to
 
425
 * <tt>T2*</tt>.
 
426
 *
 
427
 * This function will compile only if (<tt>const_cast<T2*>(p1.get());</tt>)
 
428
 * compiles.
 
429
 *
 
430
 * \relates Ptr
 
431
 */
 
432
template<class T2, class T1>
 
433
Ptr<T2> ptr_const_cast(const Ptr<T1>& p1)
 
434
{
 
435
  return Ptr<T2>(const_cast<T2*>(p1.get())); // Will only compile if conversion is legal!
 
436
}
 
437
 
 
438
 
 
439
/** \brief Dynamic cast of underlying <tt>Ptr</tt> type from <tt>T1*</tt> to
 
440
 * <tt>T2*</tt>.
 
441
 *
 
442
 * \param p1 [in] The smart pointer casting from
 
443
 *
 
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.
 
447
 *
 
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>.
 
457
 * </ul>
 
458
 *
 
459
 * This function will compile only if (<tt>dynamic_cast<T2*>(p1.get());</tt>)
 
460
 * compiles.
 
461
 *
 
462
 * \relates Ptr
 
463
 */
 
464
template<class T2, class T1>
 
465
Ptr<T2> ptr_dynamic_cast(
 
466
  const Ptr<T1>& p1, bool throw_on_fail = false
 
467
  )
 
468
{
 
469
  if( p1.get() ) {
 
470
    T2 *check = NULL;
 
471
    if(throw_on_fail)
 
472
      check = &dyn_cast<T2>(*p1);
 
473
    else
 
474
      check = dynamic_cast<T2*>(p1.get());
 
475
    if(check) {
 
476
      return Ptr<T2>(check);
 
477
    }
 
478
  }
 
479
  return null;
 
480
}
 
481
 
 
482
 
 
483
/** \brief Output stream inserter.
 
484
 *
 
485
 * The implementation of this function just print pointer addresses and
 
486
 * therefore puts no restrictions on the data types involved.
 
487
 *
 
488
 * \relates Ptr
 
489
 */
 
490
template<class T>
 
491
std::ostream& operator<<( std::ostream& out, const Ptr<T>& p );
 
492
 
 
493
 
 
494
} // namespace Teuchos
 
495
 
 
496
 
 
497
#endif // TEUCHOS_PTR_DECL_HPP