Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_ArrayRCP.hpp
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 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_ARRAY_RCP_HPP
43 #define TEUCHOS_ARRAY_RCP_HPP
44 
45 
46 #include "Teuchos_ArrayRCPDecl.hpp"
47 #include "Teuchos_ArrayView.hpp"
48 #include "Teuchos_Assert.hpp"
49 #include "Teuchos_dyn_cast.hpp"
50 #include "Teuchos_as.hpp"
51 
52 
53 namespace Teuchos {
54 
55 
56 // Helper code (not for general clients)
57 
58 
59 template<class T> inline
60 RCPNode* ArrayRCP_createNewRCPNodeRawPtr( T* p, bool has_ownership_in )
61 {
62  return new RCPNodeTmpl<T,DeallocArrayDelete<T> >(
63  p, DeallocArrayDelete<T>(), has_ownership_in
64  );
65 }
66 
67 
68 template<class T, class Dealloc_T>
69 inline
70 RCPNode* ArrayRCP_createNewDeallocRCPNodeRawPtr(
71  T* p, Dealloc_T dealloc, bool has_ownership_in
72  )
73 {
74  return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in);
75 }
76 
77 
78 template<class T2, class T1>
79 class ArcpReinterpretCastEmbeddedObj
80 {
81 public:
82  typedef T2 ptr_t;
83  ArcpReinterpretCastEmbeddedObj()
84  : arcp_pod_(null)
85  {}
86  ArcpReinterpretCastEmbeddedObj(const ArrayRCP<T1> &arcp_pod)
87  : arcp_pod_(arcpCloneNode(arcp_pod)) // Unique reference count!
88  {}
89  // NOTE: The default copy constructor is allowed and does the right thing
90  ~ArcpReinterpretCastEmbeddedObj()
91  { freeMemory(); }
92  ArcpReinterpretCastEmbeddedObj&
93  operator=(const ArcpReinterpretCastEmbeddedObj& arceo)
94  {
95  assert(is_null(arceo.arcp_pod_)); // Can only be a catestrophic programming error!
96  freeMemory();
97  return *this;
98  }
99 private:
100  ArrayRCP<T1> arcp_pod_;
101  void freeMemory()
102  {
103  typedef typename ArrayRCP<T2>::iterator itr_t;
104  if (arcp_pod_.strong_count() == 1) {
105  ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(arcp_pod_);
106  for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) {
107  itr->~T2();
108  }
109  arcp_pod_ = null;
110  }
111  }
112 };
113 
114 
115 // Constructors/Destructors/Initializers
116 
117 template<class T> inline
119  : ptr_(NULL), lowerOffset_(0), upperOffset_(-1)
120 {}
121 
122 template<class T> inline
124  : ptr_(NULL), lowerOffset_(0), upperOffset_(-1)
125 {}
126 
127 
128 template<class T> inline
130  : ptr_(0), lowerOffset_(0), upperOffset_(-1)
131 {
132  *this = arcp<T>(n);
133  std::fill_n(begin(), n, val);
134 }
135 
136 template<class T> inline
137 ArrayRCP<const T>::ArrayRCP (size_type n, const T& val)
138  : ptr_(0), lowerOffset_(0), upperOffset_(-1)
139 {
140  // We can't call std::fill_n on a const T*, so we have to create a
141  // nonconst array first, fill it, and then convert to const.
142  ArrayRCP<T> nonconstArray (n, val);
143  *this = arcp_const_cast<const T> (nonconstArray);
144 }
145 
146 
147 template<class T> inline
149  T* p, size_type lowerOffset_in, size_type size_in,
150  bool has_ownership_in, const ERCPNodeLookup rcpNodeLookup
151  )
152  : ptr_(p),
153 #ifndef TEUCHOS_DEBUG
154  node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)),
155 #endif // TEUCHOS_DEBUG
156  lowerOffset_(lowerOffset_in),
157  upperOffset_(size_in + lowerOffset_in - 1)
158 {
159 #ifdef TEUCHOS_DEBUG
160  if (p) {
161  RCPNode* existing_RCPNode = 0;
162  if (!has_ownership_in && rcpNodeLookup==RCP_ENABLE_NODE_LOOKUP) {
163  existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p);
164  }
165  if (existing_RCPNode) {
166  // Will not call add_new_RCPNode(...)
167  node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
168  }
169  else {
170  // Will call add_new_RCPNode(...)
171  RCPNodeThrowDeleter nodeDeleter(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in));
172  node_ = RCPNodeHandle(
173  nodeDeleter.get(),
174  p, typeName(*p), concreteTypeName(*p),
175  has_ownership_in
176  );
177  nodeDeleter.release();
178  }
179  }
180 #else // NOT TEUCHOS_DEBUG
181  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
182 #endif // TEUCHOS_DEBUG
183 }
184 
185 template<class T> inline
187 ArrayRCP (const T* p, size_type lowerOffset_in, size_type size_in,
188  bool has_ownership_in, const ERCPNodeLookup rcpNodeLookup)
189  : ptr_(p),
190 #ifndef TEUCHOS_DEBUG
191  node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)),
192 #endif // TEUCHOS_DEBUG
193  lowerOffset_(lowerOffset_in),
194  upperOffset_(size_in + lowerOffset_in - 1)
195 {
196 #ifdef TEUCHOS_DEBUG
197  if (p) {
198  RCPNode* existing_RCPNode = 0;
199  if (! has_ownership_in && rcpNodeLookup == RCP_ENABLE_NODE_LOOKUP) {
200  existing_RCPNode = RCPNodeTracer::getExistingRCPNode (p);
201  }
202  if (existing_RCPNode) {
203  // Will not call add_new_RCPNode(...)
204  node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
205  }
206  else {
207  // Will call add_new_RCPNode(...)
208  RCPNodeThrowDeleter nodeDeleter (ArrayRCP_createNewRCPNodeRawPtr (p, has_ownership_in));
209  node_ = RCPNodeHandle(
210  nodeDeleter.get (),
211  p, typeName (*p), concreteTypeName (*p),
212  has_ownership_in
213  );
214  nodeDeleter.release ();
215  }
216  }
217 #else // NOT TEUCHOS_DEBUG
218  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
219 #endif // TEUCHOS_DEBUG
220 }
221 
222 
223 template<class T>
224 template<class Dealloc_T>
225 inline
227  T* p, size_type lowerOffset_in, size_type size_in,
228  Dealloc_T dealloc, bool has_ownership_in
229  )
230  : ptr_(p),
231 #ifndef TEUCHOS_DEBUG
232  node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)),
233 #endif // TEUCHOS_DEBUG
234  lowerOffset_(lowerOffset_in),
235  upperOffset_(size_in + lowerOffset_in - 1)
236 {
237 #ifdef TEUCHOS_DEBUG
238  if (p) {
239  node_ = RCPNodeHandle(
240  ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in),
241  p, typeName(*p), concreteTypeName(*p),
242  has_ownership_in
243  //, RCP_STRONG, false
244  );
245  }
246 #endif // TEUCHOS_DEBUG
247 }
248 
249 template<class T>
250 template<class Dealloc_T>
251 inline
253  const T* p, size_type lowerOffset_in, size_type size_in,
254  Dealloc_T dealloc, bool has_ownership_in
255  )
256  : ptr_(p),
257 #ifndef TEUCHOS_DEBUG
258  node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)),
259 #endif // TEUCHOS_DEBUG
260  lowerOffset_(lowerOffset_in),
261  upperOffset_(size_in + lowerOffset_in - 1)
262 {
263 #ifdef TEUCHOS_DEBUG
264  if (p) {
265  node_ = RCPNodeHandle(
266  ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in),
267  p, typeName(*p), concreteTypeName(*p),
268  has_ownership_in
269  //, RCP_STRONG, false
270  );
271  }
272 #endif // TEUCHOS_DEBUG
273 }
274 
275 
276 template<class T> inline
278  :ptr_(r_ptr.ptr_),
279  node_(r_ptr.node_),
280  lowerOffset_(r_ptr.lowerOffset_),
281  upperOffset_(r_ptr.upperOffset_)
282 {}
283 
284 template<class T> inline
286  :ptr_(r_ptr.ptr_),
287  node_(r_ptr.node_),
288  lowerOffset_(r_ptr.lowerOffset_),
289  upperOffset_(r_ptr.upperOffset_)
290 {}
291 
292 
293 template<class T> inline
295 
296 template<class T> inline
298 
299 
300 template<class T> inline
302 {
303  if( this == &r_ptr )
304  return *this; // Assignment to self
305  node_ = r_ptr.access_private_node(); // May throw in debug mode!
306  ptr_ = r_ptr.ptr_;
307  lowerOffset_ = r_ptr.lowerOffset_;
308  upperOffset_ = r_ptr.upperOffset_;
309  return *this;
310  // NOTE: It is critical that the assignment of ptr_ come *after* the
311  // assignment of node_ since node_ might throw an exception!
312 }
313 
314 template<class T> inline
317 {
318  if (this == &r_ptr) {
319  return *this; // Assignment to self
320  }
321  node_ = r_ptr.access_private_node (); // May throw in debug mode!
322  ptr_ = r_ptr.ptr_;
323  lowerOffset_ = r_ptr.lowerOffset_;
324  upperOffset_ = r_ptr.upperOffset_;
325  return *this;
326  // NOTE: The assignment of ptr_ MUST come after the assignment of
327  // node_, since that line of code might throw an exception!
328 }
329 
330 
331 // Object/Pointer Access Functions
332 
333 
334 template<class T> inline
335 bool ArrayRCP<T>::is_null() const {
336  return ptr_ == 0;
337 }
338 
339 template<class T> inline
340 bool ArrayRCP<const T>::is_null() const {
341  return ptr_ == 0;
342 }
343 
344 
345 template<class T> inline
347 {
348  debug_assert_valid_ptr();
349  debug_assert_in_range(0,1);
350  return ptr_;
351 }
352 
353 template<class T> inline
354 const T* ArrayRCP<const T>::operator->() const
355 {
356  debug_assert_valid_ptr();
357  debug_assert_in_range(0,1);
358  return ptr_;
359 }
360 
361 
362 template<class T> inline
364 {
365  debug_assert_valid_ptr();
366  debug_assert_in_range(0,1);
367  return *ptr_;
368 }
369 
370 template<class T> inline
371 const T& ArrayRCP<const T>::operator*() const
372 {
373  debug_assert_valid_ptr();
374  debug_assert_in_range(0,1);
375  return *ptr_;
376 }
377 
378 
379 template<class T> inline
381 {
382  if (ptr_) {
383  debug_assert_valid_ptr();
384  debug_assert_in_range(0,1);
385  }
386  return ptr_;
387 }
388 
389 template<class T> inline
390 const T* ArrayRCP<const T>::get() const
391 {
392  if (ptr_) {
393  debug_assert_valid_ptr();
394  debug_assert_in_range(0,1);
395  }
396  return ptr_;
397 }
398 
399 
400 template<class T> inline
402  return this->get();
403 }
404 
405 template<class T> inline
406 const T* ArrayRCP<const T>::getRawPtr() const {
407  return this->get();
408 }
409 
410 
411 template<class T> inline
413 {
414  debug_assert_valid_ptr();
415  debug_assert_in_range(offset,1);
416  return ptr_[offset];
417 }
418 
419 template<class T> inline
420 const T& ArrayRCP<const T>::operator[] (size_type offset) const
421 {
422  debug_assert_valid_ptr();
423  debug_assert_in_range(offset,1);
424  return ptr_[offset];
425 }
426 
427 
428 // Pointer Arithmetic Functions
429 
430 
431 template<class T> inline
433 {
434  debug_assert_valid_ptr();
435  ++ptr_;
436  --lowerOffset_;
437  --upperOffset_;
438  return *this;
439 }
440 
441 template<class T> inline
443 {
444  debug_assert_valid_ptr();
445  ++ptr_;
446  --lowerOffset_;
447  --upperOffset_;
448  return *this;
449 }
450 
451 
452 template<class T> inline
454 {
455  debug_assert_valid_ptr();
456  ArrayRCP<T> r_ptr = *this;
457  ++(*this);
458  return r_ptr;
459 }
460 
461 template<class T> inline
463 {
464  debug_assert_valid_ptr();
465  ArrayRCP<const T> r_ptr = *this;
466  ++(*this);
467  return r_ptr;
468 }
469 
470 
471 template<class T> inline
473 {
474  debug_assert_valid_ptr();
475  --ptr_;
476  ++lowerOffset_;
477  ++upperOffset_;
478  return *this;
479 }
480 
481 template<class T> inline
483 {
484  debug_assert_valid_ptr();
485  --ptr_;
486  ++lowerOffset_;
487  ++upperOffset_;
488  return *this;
489 }
490 
491 
492 template<class T> inline
494 {
495  debug_assert_valid_ptr();
496  ArrayRCP<T> r_ptr = *this;
497  --(*this);
498  return r_ptr;
499 }
500 
501 template<class T> inline
503 {
504  debug_assert_valid_ptr();
505  ArrayRCP<const T> r_ptr = *this;
506  --(*this);
507  return r_ptr;
508 }
509 
510 
511 template<class T> inline
513 {
514  debug_assert_valid_ptr();
515  ptr_ += offset;
516  lowerOffset_ -= offset;
517  upperOffset_ -= offset;
518  return *this;
519 }
520 
521 template<class T> inline
523 {
524  debug_assert_valid_ptr();
525  ptr_ += offset;
526  lowerOffset_ -= offset;
527  upperOffset_ -= offset;
528  return *this;
529 }
530 
531 
532 template<class T> inline
534 {
535  debug_assert_valid_ptr();
536  ptr_ -= offset;
537  lowerOffset_ += offset;
538  upperOffset_ += offset;
539  return *this;
540 }
541 
542 template<class T> inline
544 {
545  debug_assert_valid_ptr();
546  ptr_ -= offset;
547  lowerOffset_ += offset;
548  upperOffset_ += offset;
549  return *this;
550 }
551 
552 
553 template<class T> inline
555 {
556  ArrayRCP<T> r_ptr = *this;
557  r_ptr+=(offset);
558  return r_ptr;
559 }
560 
561 template<class T> inline
563 {
564  ArrayRCP<const T> r_ptr = *this;
565  r_ptr+=(offset);
566  return r_ptr;
567 }
568 
569 
570 template<class T> inline
572 {
573  ArrayRCP<T> r_ptr = *this;
574  r_ptr-=offset;
575  return r_ptr;
576 }
577 
578 template<class T> inline
579 ArrayRCP<const T> ArrayRCP<const T>::operator-(size_type offset) const
580 {
581  ArrayRCP<const T> r_ptr = *this;
582  r_ptr-=offset;
583  return r_ptr;
584 }
585 
586 
587 // Standard Container-Like Functions
588 
589 
590 template<class T> inline
592 {
593  debug_assert_valid_ptr();
594 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
595  return *this;
596 #else
597  return ptr_;
598 #endif
599 }
600 
601 template<class T> inline
603 {
604  debug_assert_valid_ptr();
605 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
606  return *this;
607 #else
608  return ptr_;
609 #endif
610 }
611 
612 
613 template<class T> inline
615 {
616  debug_assert_valid_ptr();
617 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
618  return *this + (upperOffset_ + 1);
619 #else
620  return ptr_ + (upperOffset_ + 1);
621 #endif
622 }
623 
624 template<class T> inline
626 {
627  debug_assert_valid_ptr();
628 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
629  return *this + (upperOffset_ + 1);
630 #else
631  return ptr_ + (upperOffset_ + 1);
632 #endif
633 }
634 
635 
636 // ArrayRCP Views
637 
638 
639 template<class T> inline
641 {
642  if (ptr_) {
643  debug_assert_valid_ptr();
644  const T *cptr = ptr_; // Will not compile if not legal!
645  return ArrayRCP<const T>(cptr, lowerOffset_, size(), node_);
646  }
647  return null;
648 }
649 
650 template<class T> inline
652  // Trivial implementation, since no need for conversion.
653  return *this;
654 }
655 
656 
657 template<class T> inline
659 ArrayRCP<T>::persistingView( size_type lowerOffset_in, size_type size_in ) const
660 {
661  if (size_in == 0) {
662  return null;
663  }
664  debug_assert_valid_ptr();
665  debug_assert_in_range(lowerOffset_in, size_in);
666  ArrayRCP<T> ptr = *this;
667  ptr.ptr_ = ptr.ptr_ + lowerOffset_in;
668  ptr.lowerOffset_ = 0;
669  ptr.upperOffset_ = size_in - 1;
670  return ptr;
671 }
672 
673 template<class T> inline
675 ArrayRCP<const T>::persistingView (size_type lowerOffset_in, size_type size_in) const
676 {
677  if (size_in == 0) {
678  return null;
679  }
680  debug_assert_valid_ptr();
681  debug_assert_in_range(lowerOffset_in, size_in);
682  ArrayRCP<const T> ptr = *this;
683  ptr.ptr_ = ptr.ptr_ + lowerOffset_in;
684  ptr.lowerOffset_ = 0;
685  ptr.upperOffset_ = size_in - 1;
686  return ptr;
687 }
688 
689 
690 // Size and extent query functions
691 
692 
693 template<class T> inline
694 typename ArrayRCP<T>::size_type
696 {
697  debug_assert_valid_ptr();
698  return lowerOffset_;
699 }
700 
701 template<class T> inline
704 {
705  debug_assert_valid_ptr();
706  return lowerOffset_;
707 }
708 
709 
710 template<class T> inline
711 typename ArrayRCP<T>::size_type
713 {
714  debug_assert_valid_ptr();
715  return upperOffset_;
716 }
717 
718 template<class T> inline
721 {
722  debug_assert_valid_ptr();
723  return upperOffset_;
724 }
725 
726 
727 template<class T> inline
728 typename ArrayRCP<T>::size_type
730 {
731  debug_assert_valid_ptr();
732  return upperOffset_ - lowerOffset_ + 1;
733 }
734 
735 template<class T> inline
738 {
739  debug_assert_valid_ptr();
740  return upperOffset_ - lowerOffset_ + 1;
741 }
742 
743 
744 // ArrayView views
745 
746 
747 template<class T> inline
748 ArrayView<T> ArrayRCP<T>::view( size_type lowerOffset_in, size_type size_in ) const
749 {
750  if (size_in == 0) {
751  return null;
752  }
753  debug_assert_valid_ptr();
754  debug_assert_in_range(lowerOffset_in,size_in);
755 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
756  return ArrayView<T>(persistingView(lowerOffset_in, size_in).create_weak());
757 #else
758  return arrayView(ptr_ + lowerOffset_in, size_in);
759 #endif
760  // ToDo: Implement checks for dangling references!
761 }
762 
763 template<class T> inline
765 ArrayRCP<const T>::view (size_type lowerOffset_in, size_type size_in) const
766 {
767  if (size_in == 0) {
768  return null;
769  }
770  debug_assert_valid_ptr();
771  debug_assert_in_range(lowerOffset_in,size_in);
772 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
773  return ArrayView<const T>(persistingView(lowerOffset_in, size_in).create_weak());
774 #else
775  return arrayView(ptr_ + lowerOffset_in, size_in);
776 #endif
777  // ToDo: Implement checks for dangling references!
778 }
779 
780 
781 template<class T> inline
782 ArrayView<T> ArrayRCP<T>::operator()( size_type lowerOffset_in, size_type size_in ) const
783 {
784  return view(lowerOffset_in, size_in);
785 }
786 
787 template<class T> inline
789 ArrayRCP<const T>::operator() (size_type lowerOffset_in, size_type size_in) const
790 {
791  return view (lowerOffset_in, size_in);
792 }
793 
794 
795 template<class T> inline
797 {
798  if (size()) {
799  return view(lowerOffset_, size());
800  }
801  return null;
802 }
803 
804 template<class T> inline
806 {
807  if (size()) {
808  return view(lowerOffset_, size());
809  }
810  return null;
811 }
812 
813 
814 // Implicit conversions
815 
816 
817 template<class T> inline
819 {
820  if (size()) {
821  return ArrayRCP<const T>(ptr_, lowerOffset_, size(), node_);
822  }
823  return null;
824 }
825 // The above operator does not exist in the partial specialization for
826 // const T, because it doesn't make sense in that case. (Many
827 // compilers warn if one tries to implement that operator, because
828 // that code would never get called.)
829 
830 
831 // std::vector like functions
832 //
833 // Assignment (deep copy) doesn't make sense for the "const T" partial
834 // specialization, so the assignment methods (assign() and deepCopy())
835 // are omitted in that case.
836 
837 
838 template<class T> inline
839 void ArrayRCP<T>::assign (size_type n, const T &val) {
840  *this = arcp<T> (n);
841  std::fill_n (this->begin (), n, val);
842 }
843 
844 
845 template<class T>
846 template<class Iter>
847 inline
848 void ArrayRCP<T>::assign (Iter first, Iter last) {
849  const size_type new_n = std::distance (first, last);
850  if (new_n != size ()) {
851  *this = arcp<T> (new_n);
852  }
853  std::copy (first, last, begin ());
854 }
855 
856 
857 template<class T> inline
858 void ArrayRCP<T>::resize(const size_type n, const T &val)
859 {
860 #ifdef TEUCHOS_DEBUG
861  TEUCHOS_ASSERT_EQUALITY(lowerOffset(), 0);
862 #endif
863  if (n == 0) {
864  clear();
865  return;
866  }
867  const size_type orig_n = size();
868  if (n != orig_n) {
869  ArrayRCP<T> tmp = *this;
870  *this = arcp<T>(n);
871  const size_type small_n = std::min(n, orig_n);
872  for (size_type i = 0; i < small_n; ++i)
873  (*this)[i] = tmp[i];
874  for (size_type i = orig_n; i < n; ++i)
875  (*this)[i] = val;
876  upperOffset_ = n-1;
877  }
878 }
879 
880 template<class T> inline
881 void ArrayRCP<const T>::resize (const size_type n, const T& val)
882 {
883 #ifdef TEUCHOS_DEBUG
884  TEUCHOS_ASSERT_EQUALITY(lowerOffset(), 0);
885 #endif
886  if (n == 0) {
887  clear ();
888  return;
889  }
890  const size_type orig_n = size ();
891  if (n != orig_n) {
892  ArrayRCP<const T> tmp = *this;
893  // It's not allowed to assign to the result of operator[] for a
894  // const right-hand side, so we have to assign to a temporary
895  // nonconst ArrayRCP (nonconstThis) first.
896  ArrayRCP<T> nonconstThis = arcp<T> (n);
897  const size_type small_n = std::min (n, orig_n);
898  for (size_type i = 0; i < small_n; ++i) {
899  nonconstThis[i] = tmp[i];
900  }
901  for (size_type i = orig_n; i < n; ++i) {
902  nonconstThis[i] = val;
903  }
904  *this = arcp_const_cast<const T> (nonconstThis);
905  upperOffset_ = n-1;
906  }
907 }
908 
909 
910 template<class T> inline
912  *this = null;
913 }
914 
915 template<class T> inline
917  *this = null;
918 }
919 
920 
921 // Misc functions
922 
923 
924 template<class T> inline
926 {
927  if (av.size() == 0) {
928  *this = null;
929  return;
930  }
931  assign(av.begin(), av.end());
932 }
933 
934 
935 // Reference counting
936 
937 
938 template<class T> inline
940  return node_.strength();
941 }
942 
943 template<class T> inline
945  return node_.strength();
946 }
947 
948 
949 template<class T> inline
951 {
952  if (ptr_)
953  return node_.is_valid_ptr();
954  return true;
955 }
956 
957 template<class T> inline
959 {
960  if (ptr_)
961  return node_.is_valid_ptr();
962  return true;
963 }
964 
965 
966 template<class T> inline
968 {
969  return node_.strong_count();
970 }
971 
972 template<class T> inline
974 {
975  return node_.strong_count();
976 }
977 
978 
979 template<class T> inline
981 {
982  return node_.weak_count();
983 }
984 
985 template<class T> inline
987 {
988  return node_.weak_count();
989 }
990 
991 
992 template<class T> inline
994 {
995  return node_.total_count();
996 }
997 
998 template<class T> inline
1000 {
1001  return node_.total_count();
1002 }
1003 
1004 
1005 template<class T> inline
1007 {
1008  node_.has_ownership(true);
1009 }
1010 
1011 template<class T> inline
1013 {
1014  node_.has_ownership(true);
1015 }
1016 
1017 
1018 template<class T> inline
1020 {
1021  return node_.has_ownership();
1022 }
1023 
1024 template<class T> inline
1026 {
1027  return node_.has_ownership();
1028 }
1029 
1030 
1031 template<class T> inline
1033 {
1034  debug_assert_valid_ptr();
1035  node_.has_ownership(false);
1036  return ptr_;
1037 }
1038 
1039 template<class T> inline
1040 const T* ArrayRCP<const T>::release()
1041 {
1042  debug_assert_valid_ptr();
1043  node_.has_ownership(false);
1044  return ptr_;
1045 }
1046 
1047 
1048 template<class T> inline
1050  debug_assert_valid_ptr ();
1051  return ArrayRCP<T> (ptr_, lowerOffset_, size (), node_.create_weak ());
1052 }
1053 
1054 template<class T> inline
1056  debug_assert_valid_ptr ();
1057  return ArrayRCP<const T> (ptr_, lowerOffset_, size (), node_.create_weak ());
1058 }
1059 
1060 
1061 template<class T> inline
1063  debug_assert_valid_ptr ();
1064  return ArrayRCP<T> (ptr_, lowerOffset_, size (), node_.create_strong ());
1065 }
1066 
1067 template<class T> inline
1069  debug_assert_valid_ptr ();
1070  return ArrayRCP<const T> (ptr_, lowerOffset_, size (), node_.create_strong ());
1071 }
1072 
1073 
1074 template<class T>
1075 template <class T2>
1076 inline
1078 {
1079  return node_.same_node (r_ptr.access_private_node ());
1080  // Note: above, r_ptr is *not* the same class type as *this so we can not
1081  // access its node_ member directly! This is an interesting detail to the
1082  // C++ protected/private protection mechanism!
1083 }
1084 
1085 template<class T>
1086 template <class T2>
1087 inline
1088 bool ArrayRCP<const T>::shares_resource (const ArrayRCP<T2>& r_ptr) const
1089 {
1090  return node_.same_node (r_ptr.access_private_node ());
1091  // Note: above, r_ptr is *not* the same class type as *this so we can not
1092  // access its node_ member directly! This is an interesting detail to the
1093  // C++ protected/private protection mechanism!
1094 }
1095 
1096 
1097 // Assertion Functions
1098 
1099 
1100 template<class T> inline
1101 const ArrayRCP<T>&
1103 {
1104  if(!ptr_)
1106  return *this;
1107 }
1108 
1109 template<class T> inline
1110 const ArrayRCP<const T>&
1112 {
1113  if (! ptr_) {
1114  throw_null_ptr_error (typeName (*this));
1115  }
1116  return *this;
1117 }
1118 
1119 
1120 template<class T> inline
1122 {
1123  if (ptr_) {
1124  node_.assert_valid_ptr (*this);
1125  }
1126  return *this;
1127 }
1128 
1129 template<class T> inline
1131 {
1132  if (ptr_) {
1133  node_.assert_valid_ptr (*this);
1134  }
1135  return *this;
1136 }
1137 
1138 
1139 template<class T> inline
1140 const ArrayRCP<T>&
1141 ArrayRCP<T>::assert_in_range( size_type lowerOffset_in, size_type size_in ) const
1142 {
1143  assert_not_null();
1145  !(
1146  (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_)
1147  &&
1148  size_in >= 0
1149  ),
1151  typeName(*this)<<"::assert_in_range:"
1152  " Error, [lowerOffset,lowerOffset+size-1] = ["
1153  <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the"
1154  " range ["<<lowerOffset_<<","<<upperOffset_<<"]!"
1155  );
1156  return *this;
1157 }
1158 
1159 template<class T> inline
1160 const ArrayRCP<const T>&
1162 assert_in_range (size_type lowerOffset_in, size_type size_in) const
1163 {
1164  assert_not_null ();
1166  !(
1167  (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_)
1168  &&
1169  size_in >= 0
1170  ),
1172  typeName (*this) << "::assert_in_range:"
1173  " Error, [lowerOffset,lowerOffset+size-1] = ["
1174  <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the"
1175  " range ["<<lowerOffset_<<","<<upperOffset_<<"]!"
1176  );
1177  return *this;
1178 }
1179 
1180 
1181 // very bad public functions
1182 
1183 
1184 template<class T> inline
1185 ArrayRCP<T>::ArrayRCP(
1186  T* p, size_type lowerOffset_in, size_type size_in,
1187  const RCPNodeHandle& node
1188  )
1189  :ptr_(p),
1190  node_(node),
1191  lowerOffset_(lowerOffset_in),
1192  upperOffset_(size_in + lowerOffset_in - 1)
1193 {}
1194 
1195 template<class T> inline
1197  const T* p, size_type lowerOffset_in, size_type size_in,
1198  const RCPNodeHandle& node
1199  )
1200  :ptr_(p),
1201  node_(node),
1202  lowerOffset_(lowerOffset_in),
1203  upperOffset_(size_in + lowerOffset_in - 1)
1204 {}
1205 
1206 
1207 template<class T> inline
1208 T* ArrayRCP<T>::access_private_ptr() const
1209 {
1210  return ptr_;
1211 }
1212 
1213 template<class T> inline
1214 const T* ArrayRCP<const T>::access_private_ptr () const
1215 {
1216  return ptr_;
1217 }
1218 
1219 
1220 template<class T> inline
1221 RCPNodeHandle& ArrayRCP<T>::nonconst_access_private_node()
1222 {
1223  return node_;
1224 }
1225 
1226 template<class T> inline
1227 RCPNodeHandle& ArrayRCP<const T>::nonconst_access_private_node()
1228 {
1229  return node_;
1230 }
1231 
1232 
1233 template<class T> inline
1234 const RCPNodeHandle& ArrayRCP<T>::access_private_node() const
1235 {
1236  return node_;
1237 }
1238 
1239 template<class T> inline
1240 const RCPNodeHandle& ArrayRCP<const T>::access_private_node() const
1241 {
1242  return node_;
1243 }
1244 
1245 
1246 // Array<void> and Array<const void> specializations
1247 
1248 
1250 {
1252 }
1253 
1254 
1256 {
1258 }
1259 
1260 
1261 } // end namespace Teuchos
1262 
1263 
1264 // ///////////////////////////////////////////
1265 // Non-member functions for ArrayRCP
1266 
1267 
1268 namespace Teuchos {
1269 namespace Utilities {
1270 template<class T1, class T2>
1271 inline void assert_shares_resource(
1272  const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2
1273  )
1274 {
1275 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1277  !p1.shares_resource(p2), IncompatibleIteratorsError,
1278  "Error, these iterators are *not* pointing to the same valid memory!"
1279  );
1280 #endif
1281 }
1282 } // namespace Utilities
1283 } // namespace Teuchos
1284 
1285 
1286 template<class T> inline
1288 Teuchos::arcp(
1289 T* p, typename ArrayRCP<T>::size_type lowerOffset
1290  ,typename ArrayRCP<T>::size_type size_in
1291  ,bool owns_mem
1292  )
1293 {
1294  return ArrayRCP<T>(p, lowerOffset, size_in, owns_mem);
1295 }
1296 
1297 
1298 template<class T, class Dealloc_T>
1299 inline
1301 Teuchos::arcp(
1302 T* p, typename ArrayRCP<T>::size_type lowerOffset
1303  ,typename ArrayRCP<T>::size_type size_in
1304  ,Dealloc_T dealloc, bool owns_mem
1305  )
1306 {
1307  return ArrayRCP<T>(p, lowerOffset, size_in, dealloc, owns_mem);
1308 }
1309 
1310 
1311 template<class T> inline
1313 Teuchos::arcp( typename ArrayRCP<T>::size_type size )
1314 {
1315 #ifdef TEUCHOS_DEBUG
1316  TEUCHOS_ASSERT_INEQUALITY( size, >=, 0 );
1317 #endif
1318  if (size == 0) {
1319  return null;
1320  }
1321  return ArrayRCP<T>(new T[size], 0, size, true);
1322 }
1323 
1324 
1325 template<class T> inline
1327 Teuchos::arcpCloneNode(const ArrayRCP<T> &a)
1328 {
1329  if (is_null(a)) {
1330  return null;
1331  }
1332  return arcpWithEmbeddedObj(a.getRawPtr(), a.lowerOffset(), a.size(),
1333  a, false);
1334 }
1335 
1336 
1337 template<class T> inline
1339 Teuchos::arcpClone( const ArrayView<const T> &v )
1340 {
1341  const ArrayRCP<T> new_arcp = arcp<T>(v.size());
1342  std::copy( v.begin(), v.end(), new_arcp.begin() );
1343  return new_arcp;
1344 }
1345 
1346 
1347 template<class T, class Embedded>
1349 Teuchos::arcpWithEmbeddedObjPreDestroy(
1350  T* p,
1351  typename ArrayRCP<T>::size_type lowerOffset,
1352  typename ArrayRCP<T>::size_type size,
1353  const Embedded &embedded,
1354  bool owns_mem
1355  )
1356 {
1357  return arcp(
1358  p, lowerOffset, size,
1359  embeddedObjDeallocArrayDelete<T>(embedded, PRE_DESTROY),
1360  owns_mem
1361  );
1362 }
1363 
1364 
1365 template<class T, class Embedded>
1367 Teuchos::arcpWithEmbeddedObjPostDestroy(
1368  T* p,
1369  typename ArrayRCP<T>::size_type lowerOffset,
1370  typename ArrayRCP<T>::size_type size,
1371  const Embedded &embedded,
1372  bool owns_mem
1373  )
1374 {
1375  return arcp(
1376  p, lowerOffset, size,
1377  embeddedObjDeallocArrayDelete<T>(embedded, POST_DESTROY),
1378  owns_mem
1379  );
1380 }
1381 
1382 
1383 template<class T, class Embedded>
1385 Teuchos::arcpWithEmbeddedObj(
1386  T* p,
1387  typename ArrayRCP<T>::size_type lowerOffset,
1388  typename ArrayRCP<T>::size_type size,
1389  const Embedded &embedded,
1390  bool owns_mem
1391  )
1392 {
1393  return arcpWithEmbeddedObjPostDestroy<T,Embedded>(
1394  p, lowerOffset, size, embedded, owns_mem );
1395 }
1396 
1397 
1398 template<class T> inline
1400 Teuchos::arcp( const RCP<std::vector<T> > &v )
1401 {
1402  if ( is_null(v) || !v->size() )
1403  return null;
1404  return arcpWithEmbeddedObjPostDestroy<T,RCP<std::vector<T> > >(
1405  &(*v)[0], 0, v->size(),
1406  v, false
1407  );
1408 }
1409 
1410 
1411 template<class T> inline
1413 Teuchos::arcp( const RCP<const std::vector<T> > &v )
1414 {
1415  if ( is_null(v) || !v->size() )
1416  return null;
1417  return arcpWithEmbeddedObjPostDestroy<const T,RCP<const std::vector<T> > >(
1418  &(*v)[0], 0, v->size(),
1419  v, false
1420  );
1421 }
1422 
1423 
1424 template<class T> inline
1426 Teuchos::arcpFromArrayView(const ArrayView<T> &av)
1427 {
1428 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1429  return av.access_private_arcp();
1430 #else
1431  return arcp(av.getRawPtr(), 0, av.size(), false);
1432 #endif
1433 }
1434 
1435 
1436 template<class T> inline
1438 Teuchos::get_std_vector( const ArrayRCP<T> &ptr )
1439 {
1440  return getEmbeddedObj<T, RCP<std::vector<T> > >(ptr);
1441 }
1442 
1443 
1444 template<class T> inline
1446 Teuchos::get_std_vector( const ArrayRCP<const T> &ptr )
1447 {
1448  return getEmbeddedObj<const T, RCP<const std::vector<T> > >(ptr);
1449 }
1450 
1451 
1452 template<class T> inline
1453 bool Teuchos::is_null( const ArrayRCP<T> &p )
1454 {
1455  return p.is_null();
1456 }
1457 
1458 
1459 template<class T> inline
1460 bool Teuchos::nonnull( const ArrayRCP<T> &p )
1461 {
1462  return !p.is_null();
1463 }
1464 
1465 
1466 template<class T> inline
1467 bool Teuchos::operator==( const ArrayRCP<T> &p, ENull )
1468 {
1469  return p.is_null();
1470 }
1471 
1472 
1473 template<class T> inline
1474 bool Teuchos::operator!=( const ArrayRCP<T> &p, ENull )
1475 {
1476  return !p.is_null();
1477 }
1478 
1479 
1480 template<class T1, class T2>
1481 inline
1482 bool Teuchos::operator==( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1483 {
1484  return p1.access_private_ptr() == p2.access_private_ptr();
1485 }
1486 
1487 
1488 template<class T1, class T2>
1489 inline
1490 bool Teuchos::operator!=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1491 {
1492  return p1.access_private_ptr() != p2.access_private_ptr();
1493 }
1494 
1495 
1496 template<class T1, class T2>
1497 inline
1498 bool Teuchos::operator<( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1499 {
1500  return p1.access_private_ptr() < p2.access_private_ptr();
1501 }
1502 
1503 
1504 template<class T1, class T2>
1505 inline
1506 bool Teuchos::operator<=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1507 {
1508  Utilities::assert_shares_resource(p1,p2);
1509  return p1.access_private_ptr() <= p2.access_private_ptr();
1510 }
1511 
1512 
1513 template<class T1, class T2>
1514 inline
1515 bool Teuchos::operator>( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1516 {
1517  Utilities::assert_shares_resource(p1,p2);
1518  return p1.access_private_ptr() > p2.access_private_ptr();
1519 }
1520 
1521 
1522 template<class T1, class T2>
1523 inline
1524 bool Teuchos::operator>=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1525 {
1526  Utilities::assert_shares_resource(p1,p2);
1527  return p1.access_private_ptr() >= p2.access_private_ptr();
1528 }
1529 
1530 
1531 template<class T>
1533 Teuchos::operator-( const ArrayRCP<T> &p1, const ArrayRCP<T> &p2 )
1534 {
1535  Utilities::assert_shares_resource(p1,p2);
1536  return p1.access_private_ptr() - p2.access_private_ptr();
1537 }
1538 
1539 
1540 template<class T2, class T1>
1541 inline
1543 Teuchos::arcp_reinterpret_cast(const ArrayRCP<T1>& p1)
1544 {
1545  typedef typename ArrayRCP<T1>::size_type size_type;
1546  const int sizeOfT1 = sizeof(T1);
1547  const int sizeOfT2 = sizeof(T2);
1548  size_type lowerOffset2 = (p1.lowerOffset()*sizeOfT1) / sizeOfT2;
1549  size_type upperOffset2 = ((p1.upperOffset()+1)*sizeOfT1) / sizeOfT2 - 1;
1550  T2 *ptr2 = reinterpret_cast<T2*>(p1.get());
1551  return ArrayRCP<T2>(
1552  ptr2, lowerOffset2, upperOffset2 - lowerOffset2 + 1,
1553  p1.access_private_node()
1554  );
1555  // Note: Above is just fine even if p1.get()==NULL!
1556 }
1557 
1558 
1559 template<class T2, class T1>
1561 Teuchos::arcp_reinterpret_cast_nonpod(const ArrayRCP<T1>& p1, const T2& val)
1562 {
1563  typedef typename ArrayRCP<T2>::iterator itr_t;
1564  ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(p1);
1565  for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) {
1566  new (&*itr) T2(val);
1567  }
1568  return arcpWithEmbeddedObj(
1569  arcp2.getRawPtr(), 0, arcp2.size(),
1570  ArcpReinterpretCastEmbeddedObj<T2, T1>(p1),
1571  false);
1572  // Above, the ownership of the memory is totally owned by the embedded
1573  // object and the default deallocator policy object does not do anything.
1574  // This is just fine.
1575 }
1576 
1577 
1578 template<class T2, class T1>
1579 inline
1581 Teuchos::arcp_const_cast(const ArrayRCP<T1>& p1)
1582 {
1583  T2 *ptr2 = const_cast<T2*>(p1.get());
1584  return ArrayRCP<T2>(
1585  ptr2, p1.lowerOffset(), p1.size(),
1586  p1.access_private_node()
1587  );
1588  // Note: Above is just fine even if p1.get()==NULL!
1589 }
1590 
1591 
1592 template<class T2, class T1>
1593 inline
1595 Teuchos::arcp_implicit_cast(const ArrayRCP<T1>& p1)
1596 {
1597  T2 * raw_ptr2 = p1.get();
1598  return ArrayRCP<T2>(
1599  raw_ptr2, p1.lowerOffset(), p1.size(),
1600  p1.access_private_node()
1601  );
1602  // Note: Above is just fine even if p1.get()==NULL!
1603 }
1604 
1605 
1606 template<class T1, class T2>
1607 inline
1608 void Teuchos::set_extra_data(
1609  const T1 &extra_data, const std::string& name,
1610  const Ptr<ArrayRCP<T2> > &p, EPrePostDestruction destroy_when,
1611  bool force_unique
1612  )
1613 {
1614  p->assert_not_null();
1615  p->nonconst_access_private_node().set_extra_data( any(extra_data), name, destroy_when,
1616  force_unique );
1617 }
1618 
1619 
1620 template<class T1, class T2>
1621 inline
1622 T1& Teuchos::get_extra_data( ArrayRCP<T2>& p, const std::string& name )
1623 {
1624  p.assert_not_null();
1625  return any_cast<T1>(
1626  p.nonconst_access_private_node().get_extra_data(
1627  TypeNameTraits<T1>::name(), name
1628  )
1629  );
1630 }
1631 
1632 
1633 template<class T1, class T2>
1634 inline
1635 const T1& Teuchos::get_extra_data( const ArrayRCP<T2>& p, const std::string& name )
1636 {
1637  p.assert_not_null();
1638  return any_cast<T1>(
1639  p.access_private_node().get_extra_data(
1640  TypeNameTraits<T1>::name() ,name
1641  )
1642  );
1643 }
1644 
1645 
1646 template<class T1, class T2>
1647 inline
1648 T1* Teuchos::get_optional_extra_data( ArrayRCP<T2>& p, const std::string& name )
1649 {
1650  p.assert_not_null();
1651  any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
1652  TypeNameTraits<T1>::name(), name);
1653  if( extra_data ) return &any_cast<T1>(*extra_data);
1654  return NULL;
1655 }
1656 
1657 
1658 template<class T1, class T2>
1659 inline
1660 const T1* Teuchos::get_optional_extra_data( const ArrayRCP<T2>& p, const std::string& name )
1661 {
1662  p.assert_not_null();
1663  any *extra_data = p.access_private_node().get_optional_extra_data(
1664  TypeNameTraits<T1>::name(), name);
1665  if( extra_data ) return &any_cast<T1>(*extra_data);
1666  return NULL;
1667 }
1668 
1669 
1670 template<class Dealloc_T, class T>
1671 inline
1672 const Dealloc_T&
1673 Teuchos::get_dealloc( const ArrayRCP<T>& p )
1674 {
1675  return get_nonconst_dealloc<Dealloc_T>(p);
1676 }
1677 
1678 
1679 template<class Dealloc_T, class T>
1680 inline
1681 Dealloc_T&
1682 Teuchos::get_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p )
1683 {
1684  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
1685  p.assert_not_null();
1686  RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
1687  *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
1688  p.access_private_node().node_ptr());
1690  dnode==NULL, NullReferenceError
1691  ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
1692  << "," << TypeNameTraits<T>::name() << ">(p): "
1693  << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
1694  << "\' does not match actual type of the node \'"
1695  << typeName(*p.access_private_node().node_ptr()) << "!"
1696  );
1697  return dnode->get_nonconst_dealloc();
1698 }
1699 
1700 
1701 template<class Dealloc_T, class T>
1702 inline
1703 const Dealloc_T*
1704 Teuchos::get_optional_dealloc( const ArrayRCP<T>& p )
1705 {
1706  return get_optional_dealloc<Dealloc_T>(p);
1707 }
1708 
1709 
1710 template<class Dealloc_T, class T>
1711 inline
1712 Dealloc_T*
1713 Teuchos::get_optional_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p )
1714 {
1715  p.assert_not_null();
1716  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
1717  RCPNT;
1718  RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
1719  if (dnode)
1720  return &dnode->get_nonconst_dealloc();
1721  return 0;
1722 }
1723 
1724 
1725 template<class TOrig, class Embedded, class T>
1726 const Embedded& Teuchos::getEmbeddedObj( const ArrayRCP<T>& p )
1727 {
1728  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t;
1729  return get_dealloc<Dealloc_t>(p).getObj();
1730 }
1731 
1732 
1733 template<class TOrig, class Embedded, class T>
1734 Embedded& Teuchos::getNonconstEmbeddedObj( const ArrayRCP<T>& p )
1735 {
1736  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t;
1737  return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
1738 }
1739 
1740 
1741 template<class T>
1742 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayRCP<T>& p )
1743 {
1744  // mfh 15 Sep 2015: Make sure that NULL pointers print consistently.
1745  // Clang 3.5 likes to print an empty string in that case, while GCC
1746  // prints 0. Thus, we test if the pointer is NULL and print 0 in
1747  // that case. This is important for MueLu tests, which compare
1748  // string print-outs.
1749  out
1750  << TypeNameTraits<ArrayRCP<T> >::name() << "{"
1751  << "ptr=";
1752  if (p.access_private_ptr () == NULL) {
1753  out << "0";
1754  } else {
1755  out << (const void*) (p.access_private_ptr ());
1756  }
1757  out
1758  <<",lowerOffset="<<p.lowerOffset()
1759  <<",upperOffset="<<p.upperOffset()
1760  <<",size="<<p.size()
1761  <<",node=" << p.access_private_node ()
1762  <<",strong_count="<<p.strong_count()
1763  <<",weak_count="<<p.weak_count()
1764  <<"}";
1765  return out;
1766  // NOTES:
1767  // * I can't find any alternative to this C cast (problems with char data)
1768  // * Don't range check the pointer since this code does not dereference it.
1769  // This is needed to allow printing the end() or past end() for debugging.
1770 }
1771 
1772 
1773 #endif // TEUCHOS_ARRAY_RCP_HPP
Definition of Teuchos::as, for conversions between types.
Partial specialization of ArrayRCP for const T.
Reference-counted smart pointer for managing arrays.
T * get() const
Get the raw C++ pointer to the underlying object.
const ArrayRCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
Ordinal size_type
Type representing the number of elements in an ArrayRCP or view thereof.
Ordinal difference_type
Type representing the difference between two size_type values.
iterator begin() const
Return an iterator to beginning of the array of data.
bool has_ownership() const
Returns true if this has ownership of object pointed to by this->get() in order to deallocate it.
T * iterator
Nonconstant iterator type used if bounds checking is disabled.
ArrayRCP(ENull null_arg=null)
Default constructor; initialize to an empty array.
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
ArrayRCP< T > arcp(const RCP< Array< T > > &v)
Wrap an RCP<Array<T> > object as an ArrayRCP<T> object.
ArrayRCP< T > arcpWithEmbeddedObj(T *p, typename ArrayRCP< T >::size_type lowerOffset, typename ArrayRCP< T >::size_type size, const Embedded &embedded, bool owns_mem=true)
Create an ArrayRCP with and also put in an embedded object.
const ArrayRCP< T > & assert_valid_ptr() const
If the object pointer is non-null, assert that it is still valid.
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
bool is_valid_ptr() const
Return whether the underlying object pointer is still valid.
ERCPStrength strength() const
Strength of the pointer.
int weak_count() const
Return the number of active RCP<> objects that have a "weak" reference to the underlying reference-co...
int total_count() const
Total count (strong_count() + weak_count()).
Partial specialization of ArrayView for const T.
Nonowning array view.
ArrayView< T > arrayView(T *p, typename ArrayView< T >::size_type size)
Construct a const or non-const view to const or non-const data.
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
T & get(ParameterList &l, const std::string &name)
A shorter name for getParameter().
Ptr< T > ptr(T *p)
Create a pointer to an object from a raw pointer.
Handle class that manages the RCPNode's reference counting.
Deletes a (non-owning) RCPNode but not it's underlying object in case of a throw.
void release()
Releaes the RCPNode pointer before the destructor is called.
static RCPNode * getExistingRCPNode(T *p)
Return a raw pointer to an existing owning RCPNode given the address to the underlying object if it e...
Node class to keep track of address and the reference count for a reference-counted utility class and...
TEUCHOSCORE_LIB_DLL_EXPORT void throw_null_ptr_error(const std::string &type_name)
Throw that a pointer passed into an RCP object is null.
Smart reference counting pointer class for automatic garbage collection.
ENull
Used to initialize a RCP object to NULL using an implicit conversion!
Range error exception class.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
This macro is designed to be a short version of TEUCHOS_TEST_FOR_EXCEPTION() that is easier to call.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
#define TEUCHOS_ASSERT_INEQUALITY(val1, comp, val2)
This macro is checks that an inequality between two numbers is satisified and if not then throws a go...
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
This macro is checks that to numbers are equal and if not then throws an exception with a good error ...
bool is_null(const boost::shared_ptr< T > &p)
Returns true if p.get()==NULL.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
std::string concreteTypeName(const T &t)
Template function for returning the type name of the actual concrete name of a passed-in object.
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
ERCPStrength
Used to specify if the pointer is weak or strong.
ERCPNodeLookup
Used to determine if RCPNode lookup is performed or not.
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...