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