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