Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_ArrayRCP.hpp
Go to the documentation of this file.
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 {
63  p, DeallocArrayDelete<T>(), has_ownership_in
64  );
65 }
66 
67 
68 template<class T, class Dealloc_T>
69 inline
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>
80 {
81 public:
82  typedef T2 ptr_t;
84  : arcp_pod_(null)
85  {}
87  : arcp_pod_(arcpCloneNode(arcp_pod)) // Unique reference count!
88  {}
89  // NOTE: The default copy constructor is allowed and does the right thing
91  { freeMemory(); }
94  {
95  assert(is_null(arceo.arcp_pod_)); // Can only be a catestrophic programming error!
96  freeMemory();
97  return *this;
98  }
99 private:
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
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));
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));
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) {
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) {
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
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
355 {
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
372 {
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_) {
395  }
396  return ptr_;
397 }
398 
399 
400 template<class T> inline
402  return this->get();
403 }
404 
405 template<class T> inline
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
421 {
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 {
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 {
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 {
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 {
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 {
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 {
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
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 {
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 {
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
676 {
677  if (size_in == 0) {
678  return null;
679  }
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 {
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 {
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 {
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  }
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
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
1041 {
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
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
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
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_)
1105  throw_null_ptr_error(typeName(*this));
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 // Deprecated
1182 
1183 
1184 template<class T> inline
1185 int ArrayRCP<T>::count() const {
1186  return node_.count();
1187 }
1188 
1189 template<class T> inline
1191  return node_.count();
1192 }
1193 
1194 
1195 // very bad public functions
1196 
1197 
1198 template<class T> inline
1200  T* p, size_type lowerOffset_in, size_type size_in,
1201  const RCPNodeHandle& node
1202  )
1203  :ptr_(p),
1204  node_(node),
1205  lowerOffset_(lowerOffset_in),
1206  upperOffset_(size_in + lowerOffset_in - 1)
1207 {}
1208 
1209 template<class T> inline
1211  const T* p, size_type lowerOffset_in, size_type size_in,
1212  const RCPNodeHandle& node
1213  )
1214  :ptr_(p),
1215  node_(node),
1216  lowerOffset_(lowerOffset_in),
1217  upperOffset_(size_in + lowerOffset_in - 1)
1218 {}
1219 
1220 
1221 template<class T> inline
1223 {
1224  return ptr_;
1225 }
1226 
1227 template<class T> inline
1228 const T* ArrayRCP<const T>::access_private_ptr () const
1229 {
1230  return ptr_;
1231 }
1232 
1233 
1234 template<class T> inline
1235 RCPNodeHandle& ArrayRCP<T>::nonconst_access_private_node()
1236 {
1237  return node_;
1238 }
1239 
1240 template<class T> inline
1241 RCPNodeHandle& ArrayRCP<const T>::nonconst_access_private_node()
1242 {
1243  return node_;
1244 }
1245 
1246 
1247 template<class T> inline
1248 const RCPNodeHandle& ArrayRCP<T>::access_private_node() const
1249 {
1250  return node_;
1251 }
1252 
1253 template<class T> inline
1254 const RCPNodeHandle& ArrayRCP<const T>::access_private_node() const
1255 {
1256  return node_;
1257 }
1258 
1259 
1260 // Array<void> and Array<const void> specializations
1261 
1262 
1264 {
1266 }
1267 
1268 
1270 {
1272 }
1273 
1274 
1275 } // end namespace Teuchos
1276 
1277 
1278 // ///////////////////////////////////////////
1279 // Non-member functions for ArrayRCP
1280 
1281 
1282 namespace Teuchos {
1283 namespace Utilities {
1284 template<class T1, class T2>
1286  const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2
1287  )
1288 {
1289 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1292  "Error, these iterators are *not* pointing to the same valid memory!"
1293  );
1294 #endif
1295 }
1296 } // namespace Utilities
1297 } // namespace Teuchos
1298 
1299 
1300 template<class T> inline
1302 Teuchos::arcp(
1303 T* p, typename ArrayRCP<T>::size_type lowerOffset
1304  ,typename ArrayRCP<T>::size_type size_in
1305  ,bool owns_mem
1306  )
1307 {
1308  return ArrayRCP<T>(p, lowerOffset, size_in, owns_mem);
1309 }
1310 
1311 
1312 template<class T, class Dealloc_T>
1313 inline
1315 Teuchos::arcp(
1316 T* p, typename ArrayRCP<T>::size_type lowerOffset
1317  ,typename ArrayRCP<T>::size_type size_in
1318  ,Dealloc_T dealloc, bool owns_mem
1319  )
1320 {
1321  return ArrayRCP<T>(p, lowerOffset, size_in, dealloc, owns_mem);
1322 }
1323 
1324 
1325 template<class T> inline
1327 Teuchos::arcp( typename ArrayRCP<T>::size_type size )
1328 {
1329 #ifdef TEUCHOS_DEBUG
1330  TEUCHOS_ASSERT_INEQUALITY( size, >=, 0 );
1331 #endif
1332  if (size == 0) {
1333  return null;
1334  }
1335  return ArrayRCP<T>(new T[size], 0, size, true);
1336 }
1337 
1338 
1339 template<class T> inline
1341 Teuchos::arcpCloneNode(const ArrayRCP<T> &a)
1342 {
1343  if (is_null(a)) {
1344  return null;
1345  }
1346  return arcpWithEmbeddedObj(a.getRawPtr(), a.lowerOffset(), a.size(),
1347  a, false);
1348 }
1349 
1350 
1351 template<class T> inline
1353 Teuchos::arcpClone( const ArrayView<const T> &v )
1354 {
1355  const ArrayRCP<T> new_arcp = arcp<T>(v.size());
1356  std::copy( v.begin(), v.end(), new_arcp.begin() );
1357  return new_arcp;
1358 }
1359 
1360 
1361 template<class T, class Embedded>
1363 Teuchos::arcpWithEmbeddedObjPreDestroy(
1364  T* p,
1365  typename ArrayRCP<T>::size_type lowerOffset,
1366  typename ArrayRCP<T>::size_type size,
1367  const Embedded &embedded,
1368  bool owns_mem
1369  )
1370 {
1371  return arcp(
1372  p, lowerOffset, size,
1373  embeddedObjDeallocArrayDelete<T>(embedded, PRE_DESTROY),
1374  owns_mem
1375  );
1376 }
1377 
1378 
1379 template<class T, class Embedded>
1381 Teuchos::arcpWithEmbeddedObjPostDestroy(
1382  T* p,
1383  typename ArrayRCP<T>::size_type lowerOffset,
1384  typename ArrayRCP<T>::size_type size,
1385  const Embedded &embedded,
1386  bool owns_mem
1387  )
1388 {
1389  return arcp(
1390  p, lowerOffset, size,
1391  embeddedObjDeallocArrayDelete<T>(embedded, POST_DESTROY),
1392  owns_mem
1393  );
1394 }
1395 
1396 
1397 template<class T, class Embedded>
1399 Teuchos::arcpWithEmbeddedObj(
1400  T* p,
1401  typename ArrayRCP<T>::size_type lowerOffset,
1402  typename ArrayRCP<T>::size_type size,
1403  const Embedded &embedded,
1404  bool owns_mem
1405  )
1406 {
1407  return arcpWithEmbeddedObjPostDestroy<T,Embedded>(
1408  p, lowerOffset, size, embedded, owns_mem );
1409 }
1410 
1411 
1412 template<class T> inline
1414 Teuchos::arcp( const RCP<std::vector<T> > &v )
1415 {
1416  if ( is_null(v) || !v->size() )
1417  return null;
1418  return arcpWithEmbeddedObjPostDestroy<T,RCP<std::vector<T> > >(
1419  &(*v)[0], 0, v->size(),
1420  v, false
1421  );
1422 }
1423 
1424 
1425 template<class T> inline
1427 Teuchos::arcp( const RCP<const std::vector<T> > &v )
1428 {
1429  if ( is_null(v) || !v->size() )
1430  return null;
1431  return arcpWithEmbeddedObjPostDestroy<const T,RCP<const std::vector<T> > >(
1432  &(*v)[0], 0, v->size(),
1433  v, false
1434  );
1435 }
1436 
1437 
1438 template<class T> inline
1440 Teuchos::arcpFromArrayView(const ArrayView<T> &av)
1441 {
1442 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1443  return av.access_private_arcp();
1444 #else
1445  return arcp(av.getRawPtr(), 0, av.size(), false);
1446 #endif
1447 }
1448 
1449 
1450 template<class T> inline
1452 Teuchos::get_std_vector( const ArrayRCP<T> &ptr )
1453 {
1454  return getEmbeddedObj<T, RCP<std::vector<T> > >(ptr);
1455 }
1456 
1457 
1458 template<class T> inline
1460 Teuchos::get_std_vector( const ArrayRCP<const T> &ptr )
1461 {
1462  return getEmbeddedObj<const T, RCP<const std::vector<T> > >(ptr);
1463 }
1464 
1465 
1466 template<class T> inline
1467 bool Teuchos::is_null( const ArrayRCP<T> &p )
1468 {
1469  return p.is_null();
1470 }
1471 
1472 
1473 template<class T> inline
1474 bool Teuchos::nonnull( const ArrayRCP<T> &p )
1475 {
1476  return !p.is_null();
1477 }
1478 
1479 
1480 template<class T> inline
1481 bool Teuchos::operator==( const ArrayRCP<T> &p, ENull )
1482 {
1483  return p.is_null();
1484 }
1485 
1486 
1487 template<class T> inline
1488 bool Teuchos::operator!=( const ArrayRCP<T> &p, ENull )
1489 {
1490  return !p.is_null();
1491 }
1492 
1493 
1494 template<class T1, class T2>
1495 inline
1496 bool Teuchos::operator==( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1497 {
1498  return p1.access_private_ptr() == p2.access_private_ptr();
1499 }
1500 
1501 
1502 template<class T1, class T2>
1503 inline
1504 bool Teuchos::operator!=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1505 {
1506  return p1.access_private_ptr() != p2.access_private_ptr();
1507 }
1508 
1509 
1510 template<class T1, class T2>
1511 inline
1512 bool Teuchos::operator<( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1513 {
1514  return p1.access_private_ptr() < p2.access_private_ptr();
1515 }
1516 
1517 
1518 template<class T1, class T2>
1519 inline
1520 bool Teuchos::operator<=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1521 {
1523  return p1.access_private_ptr() <= p2.access_private_ptr();
1524 }
1525 
1526 
1527 template<class T1, class T2>
1528 inline
1529 bool Teuchos::operator>( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1530 {
1532  return p1.access_private_ptr() > p2.access_private_ptr();
1533 }
1534 
1535 
1536 template<class T1, class T2>
1537 inline
1538 bool Teuchos::operator>=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
1539 {
1541  return p1.access_private_ptr() >= p2.access_private_ptr();
1542 }
1543 
1544 
1545 template<class T>
1547 Teuchos::operator-( const ArrayRCP<T> &p1, const ArrayRCP<T> &p2 )
1548 {
1550  return p1.access_private_ptr() - p2.access_private_ptr();
1551 }
1552 
1553 
1554 template<class T2, class T1>
1555 inline
1557 Teuchos::arcp_reinterpret_cast(const ArrayRCP<T1>& p1)
1558 {
1559  typedef typename ArrayRCP<T1>::size_type size_type;
1560  const int sizeOfT1 = sizeof(T1);
1561  const int sizeOfT2 = sizeof(T2);
1562  size_type lowerOffset2 = (p1.lowerOffset()*sizeOfT1) / sizeOfT2;
1563  size_type upperOffset2 = ((p1.upperOffset()+1)*sizeOfT1) / sizeOfT2 - 1;
1564  T2 *ptr2 = reinterpret_cast<T2*>(p1.get());
1565  return ArrayRCP<T2>(
1566  ptr2, lowerOffset2, upperOffset2 - lowerOffset2 + 1,
1567  p1.access_private_node()
1568  );
1569  // Note: Above is just fine even if p1.get()==NULL!
1570 }
1571 
1572 
1573 template<class T2, class T1>
1575 Teuchos::arcp_reinterpret_cast_nonpod(const ArrayRCP<T1>& p1, const T2& val)
1576 {
1577  typedef typename ArrayRCP<T2>::iterator itr_t;
1578  ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(p1);
1579  for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) {
1580  new (&*itr) T2(val);
1581  }
1582  return arcpWithEmbeddedObj(
1583  arcp2.getRawPtr(), 0, arcp2.size(),
1584  ArcpReinterpretCastEmbeddedObj<T2, T1>(p1),
1585  false);
1586  // Above, the ownership of the memory is totally owned by the embedded
1587  // object and the default deallocator policy object does not do anything.
1588  // This is just fine.
1589 }
1590 
1591 
1592 template<class T2, class T1>
1593 inline
1595 Teuchos::arcp_const_cast(const ArrayRCP<T1>& p1)
1596 {
1597  T2 *ptr2 = const_cast<T2*>(p1.get());
1598  return ArrayRCP<T2>(
1599  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 T2, class T1>
1607 inline
1609 Teuchos::arcp_implicit_cast(const ArrayRCP<T1>& p1)
1610 {
1611  T2 * raw_ptr2 = p1.get();
1612  return ArrayRCP<T2>(
1613  raw_ptr2, p1.lowerOffset(), p1.size(),
1614  p1.access_private_node()
1615  );
1616  // Note: Above is just fine even if p1.get()==NULL!
1617 }
1618 
1619 
1620 template<class T1, class T2>
1621 inline
1622 void Teuchos::set_extra_data(
1623  const T1 &extra_data, const std::string& name,
1624  const Ptr<ArrayRCP<T2> > &p, EPrePostDestruction destroy_when,
1625  bool force_unique
1626  )
1627 {
1628  p->assert_not_null();
1629  p->nonconst_access_private_node().set_extra_data( any(extra_data), name, destroy_when,
1630  force_unique );
1631 }
1632 
1633 
1634 template<class T1, class T2>
1635 inline
1636 T1& Teuchos::get_extra_data( ArrayRCP<T2>& p, const std::string& name )
1637 {
1638  p.assert_not_null();
1639  return any_cast<T1>(
1640  p.nonconst_access_private_node().get_extra_data(
1641  TypeNameTraits<T1>::name(), name
1642  )
1643  );
1644 }
1645 
1646 
1647 template<class T1, class T2>
1648 inline
1649 const T1& Teuchos::get_extra_data( const ArrayRCP<T2>& p, const std::string& name )
1650 {
1651  p.assert_not_null();
1652  return any_cast<T1>(
1653  p.access_private_node().get_extra_data(
1654  TypeNameTraits<T1>::name() ,name
1655  )
1656  );
1657 }
1658 
1659 
1660 template<class T1, class T2>
1661 inline
1662 T1* Teuchos::get_optional_extra_data( ArrayRCP<T2>& p, const std::string& name )
1663 {
1664  p.assert_not_null();
1665  any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
1666  TypeNameTraits<T1>::name(), name);
1667  if( extra_data ) return &any_cast<T1>(*extra_data);
1668  return NULL;
1669 }
1670 
1671 
1672 template<class T1, class T2>
1673 inline
1674 const T1* Teuchos::get_optional_extra_data( const ArrayRCP<T2>& p, const std::string& name )
1675 {
1676  p.assert_not_null();
1677  any *extra_data = p.access_private_node().get_optional_extra_data(
1678  TypeNameTraits<T1>::name(), name);
1679  if( extra_data ) return &any_cast<T1>(*extra_data);
1680  return NULL;
1681 }
1682 
1683 
1684 template<class Dealloc_T, class T>
1685 inline
1686 const Dealloc_T&
1687 Teuchos::get_dealloc( const ArrayRCP<T>& p )
1688 {
1689  return get_nonconst_dealloc<Dealloc_T>(p);
1690 }
1691 
1692 
1693 template<class Dealloc_T, class T>
1694 inline
1695 Dealloc_T&
1696 Teuchos::get_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p )
1697 {
1698  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
1699  p.assert_not_null();
1700  RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
1701  *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
1702  p.access_private_node().node_ptr());
1704  dnode==NULL, NullReferenceError
1705  ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
1706  << "," << TypeNameTraits<T>::name() << ">(p): "
1707  << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
1708  << "\' does not match actual type of the node \'"
1709  << typeName(*p.access_private_node().node_ptr()) << "!"
1710  );
1711  return dnode->get_nonconst_dealloc();
1712 }
1713 
1714 
1715 template<class Dealloc_T, class T>
1716 inline
1717 const Dealloc_T*
1718 Teuchos::get_optional_dealloc( const ArrayRCP<T>& p )
1719 {
1720  return get_optional_dealloc<Dealloc_T>(p);
1721 }
1722 
1723 
1724 template<class Dealloc_T, class T>
1725 inline
1726 Dealloc_T*
1727 Teuchos::get_optional_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p )
1728 {
1729  p.assert_not_null();
1730  typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
1731  RCPNT;
1732  RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
1733  if (dnode)
1734  return &dnode->get_nonconst_dealloc();
1735  return 0;
1736 }
1737 
1738 
1739 template<class TOrig, class Embedded, class T>
1740 const Embedded& Teuchos::getEmbeddedObj( const ArrayRCP<T>& p )
1741 {
1742  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t;
1743  return get_dealloc<Dealloc_t>(p).getObj();
1744 }
1745 
1746 
1747 template<class TOrig, class Embedded, class T>
1748 Embedded& Teuchos::getNonconstEmbeddedObj( const ArrayRCP<T>& p )
1749 {
1750  typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t;
1751  return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
1752 }
1753 
1754 
1755 template<class T>
1756 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayRCP<T>& p )
1757 {
1758  // mfh 15 Sep 2015: Make sure that NULL pointers print consistently.
1759  // Clang 3.5 likes to print an empty string in that case, while GCC
1760  // prints 0. Thus, we test if the pointer is NULL and print 0 in
1761  // that case. This is important for MueLu tests, which compare
1762  // string print-outs.
1763  out
1764  << TypeNameTraits<ArrayRCP<T> >::name() << "{"
1765  << "ptr=";
1766  if (p.access_private_ptr () == NULL) {
1767  out << "0";
1768  } else {
1769  out << (const void*) (p.access_private_ptr ());
1770  }
1771  out
1772  <<",lowerOffset="<<p.lowerOffset()
1773  <<",upperOffset="<<p.upperOffset()
1774  <<",size="<<p.size()
1775  <<",node=" << p.access_private_node ()
1776  <<",strong_count="<<p.strong_count()
1777  <<",weak_count="<<p.weak_count()
1778  <<"}";
1779  return out;
1780  // NOTES:
1781  // * I can't find any alternative to this C cast (problems with char data)
1782  // * Don't range check the pointer since this code does not dereference it.
1783  // This is needed to allow printing the end() or past end() for debugging.
1784 }
1785 
1786 
1787 #endif // TEUCHOS_ARRAY_RCP_HPP
size_type lowerOffset_
Lower offset to the data; 0 if this array is null.
TEUCHOS_DEPRECATED int count() const
Returns strong_count() [deprecated].
int weak_count() const
The weak count for this RCPNode, or 0 if the node is NULL.
ERCPStrength
Used to specify if the pointer is weak or strong.
ArrayRCP< T > create_weak() const
Create a new weak reference from another (strong) reference.
ArcpReinterpretCastEmbeddedObj & operator=(const ArcpReinterpretCastEmbeddedObj &arceo)
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...
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
BigUInt< n > operator-(BigUInt< n > const &a, BigUInt< n > const &b)
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.
RCPNode * ArrayRCP_createNewDeallocRCPNodeRawPtr(T *p, Dealloc_T dealloc, bool has_ownership_in)
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.
ERCPNodeLookup
Used to determine if RCPNode lookup is performed or not.
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!
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.
void debug_assert_valid_ptr() const
RCPNodeHandle node_
Reference-counting machinery.
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.
bool operator!=(const Allocator< T > &a_t, const Allocator< U > &a_u)
Return ! (a_t == a_u) (see above).
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...
Deallocator class that uses delete [] to delete memory allocated uisng new []
Templated implementation class of RCPNode that has the responsibility for deleting the reference-coun...
bool operator>(BigUInt< n > const &a, BigUInt< n > const &b)
std::string concreteTypeName(const T &t)
Template function for returning the type name of the actual concrete name of a passed-in object...
bool operator>=(BigUInt< n > const &a, BigUInt< n > const &b)
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()).
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
Incompatiable iterators error exception class.
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.
T * ptr_
Raw pointer to the array; NULL if this array is null.
Nonowning array view.
void set_has_ownership()
Give this and other ArrayRCP&lt;&gt; objects ownership of the underlying referenced array to delete it...
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
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)
void debug_assert_in_range(size_type lowerOffset_in, size_type size_in) const
ArrayView< T > operator()() const
Return a nonpersisting view of *this.
int total_count() const
The sum of the weak and string counts.
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.
void assert_shares_resource(const ArrayRCP< T1 > &p1, const ArrayRCP< T2 > &p2)
ArcpReinterpretCastEmbeddedObj(const ArrayRCP< T1 > &arcp_pod)
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.
RCPNode * ArrayRCP_createNewRCPNodeRawPtr(T *p, bool has_ownership_in)
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 ...
size_type upperOffset_
Upper offset to the data; -1 if this array is null.
RCPNodeHandle create_weak() const
Return a weak handle.
bool operator==(BigUInt< n > const &a, BigUInt< n > const &b)
int count() const
The strong count; retained for backwards compatibility.
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...
void assign(size_type n, const T &val)
Resize and assign n elements of val.
ArrayView< T > view(size_type lowerOffset, size_type size) const
Return a nonpersisting view of a contiguous range of elements.