Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_ArrayRCP.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_ARRAY_RCP_HPP
43 #define TEUCHOS_ARRAY_RCP_HPP
44 
45 
46 #include "Teuchos_ArrayRCPDecl.hpp"
47 #include "Teuchos_ArrayView.hpp"
48 #include "Teuchos_Assert.hpp"
49 #include "Teuchos_dyn_cast.hpp"
50 #include "Teuchos_as.hpp"
51 
52 
53 namespace Teuchos {
54 
55 
56 // Helper code (not for general clients)
57 
58 
59 template<class T> inline
60 RCPNode* ArrayRCP_createNewRCPNodeRawPtr( T* p, bool has_ownership_in )
61 {
62  return new RCPNodeTmpl<T,DeallocArrayDelete<T> >(
63  p, DeallocArrayDelete<T>(), has_ownership_in
64  );
65 }
66 
67 
68 template<class T, class Dealloc_T>
69 inline
70 RCPNode* ArrayRCP_createNewDeallocRCPNodeRawPtr(
71  T* p, Dealloc_T dealloc, bool has_ownership_in
72  )
73 {
74  return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in);
75 }
76 
77 
78 template<class T2, class T1>
79 class ArcpReinterpretCastEmbeddedObj
80 {
81 public:
82  typedef T2 ptr_t;
83  ArcpReinterpretCastEmbeddedObj()
84  : arcp_pod_(null)
85  {}
86  ArcpReinterpretCastEmbeddedObj(const ArrayRCP<T1> &arcp_pod)
87  : arcp_pod_(arcpCloneNode(arcp_pod)) // Unique reference count!
88  {}
89  // NOTE: The default copy constructor is allowed and does the right thing
90  ~ArcpReinterpretCastEmbeddedObj()
91  { freeMemory(); }
92  ArcpReinterpretCastEmbeddedObj&
93  operator=(const ArcpReinterpretCastEmbeddedObj& arceo)
94  {
95  assert(is_null(arceo.arcp_pod_)); // Can only be a catestrophic programming error!
96  freeMemory();
97  return *this;
98  }
99 private:
100  ArrayRCP<T1> arcp_pod_;
101  void freeMemory()
102  {
103  typedef typename ArrayRCP<T2>::iterator itr_t;
104  if (arcp_pod_.strong_count() == 1) {
105  ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(arcp_pod_);
106  for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) {
107  itr->~T2();
108  }
109  arcp_pod_ = null;
110  }
111  }
112 };
113 
114 
115 // Constructors/Destructors/Initializers
116 
117 template<class T> inline
119  : ptr_(NULL), lowerOffset_(0), upperOffset_(-1)
120 {}
121 
122 template<class T> inline
124  : ptr_(NULL), lowerOffset_(0), upperOffset_(-1)
125 {}
126 
127 
128 template<class T> inline
130  : ptr_(0), lowerOffset_(0), upperOffset_(-1)
131 {
132  *this = arcp<T>(n);
133  std::fill_n(begin(), n, val);
134 }
135 
136 template<class T> inline
137 ArrayRCP<const T>::ArrayRCP (size_type n, const T& val)
138  : ptr_(0), lowerOffset_(0), upperOffset_(-1)
139 {
140  // We can't call std::fill_n on a const T*, so we have to create a
141  // nonconst array first, fill it, and then convert to const.
142  ArrayRCP<T> nonconstArray (n, val);
143  *this = arcp_const_cast<const T> (nonconstArray);
144 }
145 
146 
147 template<class T> inline
149  T* p, size_type lowerOffset_in, size_type size_in,
150  bool has_ownership_in, const ERCPNodeLookup rcpNodeLookup
151  )
152  : ptr_(p),
153 #ifndef TEUCHOS_DEBUG
154  node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)),
155 #endif // TEUCHOS_DEBUG
156  lowerOffset_(lowerOffset_in),
157  upperOffset_(size_in + lowerOffset_in - 1)
158 {
159 #ifdef TEUCHOS_DEBUG
160  if (p) {
161  RCPNode* existing_RCPNode = 0;
162  if (!has_ownership_in && rcpNodeLookup==RCP_ENABLE_NODE_LOOKUP) {
163  existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p);
164  }
165  if (existing_RCPNode) {
166  // Will not call add_new_RCPNode(...)
167  node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
168  }
169  else {
170  // Will call add_new_RCPNode(...)
171  RCPNodeThrowDeleter nodeDeleter(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in));
172  node_ = RCPNodeHandle(
173  nodeDeleter.get(),
174  p, typeName(*p), concreteTypeName(*p),
175  has_ownership_in
176  );
177  nodeDeleter.release();
178  }
179  }
180 #else // NOT TEUCHOS_DEBUG
181  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
182 #endif // TEUCHOS_DEBUG
183 }
184 
185 template<class T> inline
187 ArrayRCP (const T* p, size_type lowerOffset_in, size_type size_in,
188  bool has_ownership_in, const ERCPNodeLookup rcpNodeLookup)
189  : ptr_(p),
190 #ifndef TEUCHOS_DEBUG
191  node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)),
192 #endif // TEUCHOS_DEBUG
193  lowerOffset_(lowerOffset_in),
194  upperOffset_(size_in + lowerOffset_in - 1)
195 {
196 #ifdef TEUCHOS_DEBUG
197  if (p) {
198  RCPNode* existing_RCPNode = 0;
199  if (! has_ownership_in && rcpNodeLookup == RCP_ENABLE_NODE_LOOKUP) {
200  existing_RCPNode = RCPNodeTracer::getExistingRCPNode (p);
201  }
202  if (existing_RCPNode) {
203  // Will not call add_new_RCPNode(...)
204  node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
205  }
206  else {
207  // Will call add_new_RCPNode(...)
208  RCPNodeThrowDeleter nodeDeleter (ArrayRCP_createNewRCPNodeRawPtr (p, has_ownership_in));
209  node_ = RCPNodeHandle(
210  nodeDeleter.get (),
211  p, typeName (*p), concreteTypeName (*p),
212  has_ownership_in
213  );
214  nodeDeleter.release ();
215  }
216  }
217 #else // NOT TEUCHOS_DEBUG
218  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
219 #endif // TEUCHOS_DEBUG
220 }
221 
222 
223 template<class T>
224 template<class Dealloc_T>
225 inline
227  T* p, size_type lowerOffset_in, size_type size_in,
228  Dealloc_T dealloc, bool has_ownership_in
229  )
230  : ptr_(p),
231 #ifndef TEUCHOS_DEBUG
232  node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)),
233 #endif // TEUCHOS_DEBUG
234  lowerOffset_(lowerOffset_in),
235  upperOffset_(size_in + lowerOffset_in - 1)
236 {
237 #ifdef TEUCHOS_DEBUG
238  if (p) {
239  node_ = RCPNodeHandle(
240  ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in),
241  p, typeName(*p), concreteTypeName(*p),
242  has_ownership_in
243  //, RCP_STRONG, false
244  );
245  }
246 #endif // TEUCHOS_DEBUG
247 }
248 
249 template<class T>
250 template<class Dealloc_T>
251 inline
253  const T* p, size_type lowerOffset_in, size_type size_in,
254  Dealloc_T dealloc, bool has_ownership_in
255  )
256  : ptr_(p),
257 #ifndef TEUCHOS_DEBUG
258  node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)),
259 #endif // TEUCHOS_DEBUG
260  lowerOffset_(lowerOffset_in),
261  upperOffset_(size_in + lowerOffset_in - 1)
262 {
263 #ifdef TEUCHOS_DEBUG
264  if (p) {
265  node_ = RCPNodeHandle(
266  ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in),
267  p, typeName(*p), concreteTypeName(*p),
268  has_ownership_in
269  //, RCP_STRONG, false
270  );
271  }
272 #endif // TEUCHOS_DEBUG
273 }
274 
275 
276 template<class T> inline
278  :ptr_(r_ptr.ptr_),
279  node_(r_ptr.node_),
280  lowerOffset_(r_ptr.lowerOffset_),
281  upperOffset_(r_ptr.upperOffset_)
282 {}
283 
284 template<class T> inline
286  :ptr_(r_ptr.ptr_),
287  node_(r_ptr.node_),
288  lowerOffset_(r_ptr.lowerOffset_),
289  upperOffset_(r_ptr.upperOffset_)
290 {}
291 
292 
293 template<class T> inline
295 
296 template<class T> inline
298 
299 
300 template<class T> inline
302 {
303  if( this == &r_ptr )
304  return *this; // Assignment to self
305  node_ = r_ptr.access_private_node(); // May throw in debug mode!
306  ptr_ = r_ptr.ptr_;
307  lowerOffset_ = r_ptr.lowerOffset_;
308  upperOffset_ = r_ptr.upperOffset_;
309  return *this;
310  // NOTE: It is critical that the assignment of ptr_ come *after* the
311  // assignment of node_ since node_ might throw an exception!
312 }
313 
314 template<class T> inline
317 {
318  if (this == &r_ptr) {
319  return *this; // Assignment to self
320  }
321  node_ = r_ptr.access_private_node (); // May throw in debug mode!
322  ptr_ = r_ptr.ptr_;
323  lowerOffset_ = r_ptr.lowerOffset_;
324  upperOffset_ = r_ptr.upperOffset_;
325  return *this;
326  // NOTE: The assignment of ptr_ MUST come after the assignment of
327  // node_, since that line of code might throw an exception!
328 }
329 
330 
331 // Object/Pointer Access Functions
332 
333 
334 template<class T> inline
335 bool ArrayRCP<T>::is_null() const {
336  return ptr_ == 0;
337 }
338 
339 template<class T> inline
340 bool ArrayRCP<const T>::is_null() const {
341  return ptr_ == 0;
342 }
343 
344 
345 template<class T> inline
347 {
348  debug_assert_valid_ptr();
349  debug_assert_in_range(0,1);
350  return ptr_;
351 }
352 
353 template<class T> inline
354 const T* ArrayRCP<const T>::operator->() const
355 {
356  debug_assert_valid_ptr();
357  debug_assert_in_range(0,1);
358  return ptr_;
359 }
360 
361 
362 template<class T> inline
364 {
365  debug_assert_valid_ptr();
366  debug_assert_in_range(0,1);
367  return *ptr_;
368 }
369 
370 template<class T> inline
371 const T& ArrayRCP<const T>::operator*() const
372 {
373  debug_assert_valid_ptr();
374  debug_assert_in_range(0,1);
375  return *ptr_;
376 }
377 
378 
379 template<class T> inline
381 {
382  if (ptr_) {
383  debug_assert_valid_ptr();
384  debug_assert_in_range(0,1);
385  }
386  return ptr_;
387 }
388 
389 template<class T> inline
390 const T* ArrayRCP<const T>::get() const
391 {
392  if (ptr_) {
393  debug_assert_valid_ptr();
394  debug_assert_in_range(0,1);
395  }
396  return ptr_;
397 }
398 
399 
400 template<class T> inline
402  return this->get();
403 }
404 
405 template<class T> inline
406 const T* ArrayRCP<const T>::getRawPtr() const {
407  return this->get();
408 }
409 
410 
411 template<class T> inline
413 {
414  debug_assert_valid_ptr();
415  debug_assert_in_range(offset,1);
416  return ptr_[offset];
417 }
418 
419 template<class T> inline
420 const T& ArrayRCP<const T>::operator[] (size_type offset) const
421 {
422  debug_assert_valid_ptr();
423  debug_assert_in_range(offset,1);
424  return ptr_[offset];
425 }
426 
427 
428 // Pointer Arithmetic Functions
429 
430 
431 template<class T> inline
433 {
434  debug_assert_valid_ptr();
435  ++ptr_;
436  --lowerOffset_;
437  --upperOffset_;
438  return *this;
439 }
440 
441 template<class T> inline
443 {
444  debug_assert_valid_ptr();
445  ++ptr_;
446  --lowerOffset_;
447  --upperOffset_;
448  return *this;
449 }
450 
451 
452 template<class T> inline
454 {
455  debug_assert_valid_ptr();
456  ArrayRCP<T> r_ptr = *this;
457  ++(*this);
458  return r_ptr;
459 }
460 
461 template<class T> inline
463 {
464  debug_assert_valid_ptr();
465  ArrayRCP<const T> r_ptr = *this;
466  ++(*this);
467  return r_ptr;
468 }
469 
470 
471 template<class T> inline
473 {
474  debug_assert_valid_ptr();
475  --ptr_;
476  ++lowerOffset_;
477  ++upperOffset_;
478  return *this;
479 }
480 
481 template<class T> inline
483 {
484  debug_assert_valid_ptr();
485  --ptr_;
486  ++lowerOffset_;
487  ++upperOffset_;
488  return *this;
489 }
490 
491 
492 template<class T> inline
494 {
495  debug_assert_valid_ptr();
496  ArrayRCP<T> r_ptr = *this;
497  --(*this);
498  return r_ptr;
499 }
500 
501 template<class T> inline
503 {
504  debug_assert_valid_ptr();
505  ArrayRCP<const T> r_ptr = *this;
506  --(*this);
507  return r_ptr;
508 }
509 
510 
511 template<class T> inline
513 {
514  debug_assert_valid_ptr();
515  ptr_ += offset;
516  lowerOffset_ -= offset;
517  upperOffset_ -= offset;
518  return *this;
519 }
520 
521 template<class T> inline
523 {
524  debug_assert_valid_ptr();
525  ptr_ += offset;
526  lowerOffset_ -= offset;
527  upperOffset_ -= offset;
528  return *this;
529 }
530 
531 
532 template<class T> inline
534 {
535  debug_assert_valid_ptr();
536  ptr_ -= offset;
537  lowerOffset_ += offset;
538  upperOffset_ += offset;
539  return *this;
540 }
541 
542 template<class T> inline
544 {
545  debug_assert_valid_ptr();
546  ptr_ -= offset;
547  lowerOffset_ += offset;
548  upperOffset_ += offset;
549  return *this;
550 }
551 
552 
553 template<class T> inline
555 {
556  ArrayRCP<T> r_ptr = *this;
557  r_ptr+=(offset);
558  return r_ptr;
559 }
560 
561 template<class T> inline
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
884  TEUCHOS_ASSERT_EQUALITY(lowerOffset(), 0);
885 #endif
886  if (n == 0) {
887  clear ();
888  return;
889  }
890  const size_type orig_n = size ();
891  if (n != orig_n) {
892  ArrayRCP<const T> tmp = *this;
893  // It's not allowed to assign to the result of operator[] for a
894  // const right-hand side, so we have to assign to a temporary
895  // nonconst ArrayRCP (nonconstThis) first.
896  ArrayRCP<T> nonconstThis = arcp<T> (n);
897  const size_type small_n = std::min (n, orig_n);
898  for (size_type i = 0; i < small_n; ++i) {
899  nonconstThis[i] = tmp[i];
900  }
901  for (size_type i = orig_n; i < n; ++i) {
902  nonconstThis[i] = val;
903  }
904  *this = arcp_const_cast<const T> (nonconstThis);
905  upperOffset_ = n-1;
906  }
907 }
908 
909 
910 template<class T> inline
912  *this = null;
913 }
914 
915 template<class T> inline
917  *this = null;
918 }
919 
920 
921 // Misc functions
922 
923 
924 template<class T> inline
926 {
927  if (av.size() == 0) {
928  *this = null;
929  return;
930  }
931  assign(av.begin(), av.end());
932 }
933 
934 
935 // Reference counting
936 
937 
938 template<class T> inline
940  return node_.strength();
941 }
942 
943 template<class T> inline
945  return node_.strength();
946 }
947 
948 
949 template<class T> inline
951 {
952  if (ptr_)
953  return node_.is_valid_ptr();
954  return true;
955 }
956 
957 template<class T> inline
959 {
960  if (ptr_)
961  return node_.is_valid_ptr();
962  return true;
963 }
964 
965 
966 template<class T> inline
968 {
969  return node_.strong_count();
970 }
971 
972 template<class T> inline
974 {
975  return node_.strong_count();
976 }
977 
978 
979 template<class T> inline
981 {
982  return node_.weak_count();
983 }
984 
985 template<class T> inline
987 {
988  return node_.weak_count();
989 }
990 
991 
992 template<class T> inline
994 {
995  return node_.total_count();
996 }
997 
998 template<class T> inline
1000 {
1001  return node_.total_count();
1002 }
1003 
1004 
1005 template<class T> inline
1007 {
1008  node_.has_ownership(true);
1009 }
1010 
1011 template<class T> inline
1013 {
1014  node_.has_ownership(true);
1015 }
1016 
1017 
1018 template<class T> inline
1020 {
1021  return node_.has_ownership();
1022 }
1023 
1024 template<class T> inline
1026 {
1027  return node_.has_ownership();
1028 }
1029 
1030 
1031 template<class T> inline
1033 {
1034  debug_assert_valid_ptr();
1035  node_.has_ownership(false);
1036  return ptr_;
1037 }
1038 
1039 template<class T> inline
1040 const T* ArrayRCP<const T>::release()
1041 {
1042  debug_assert_valid_ptr();
1043  node_.has_ownership(false);
1044  return ptr_;
1045 }
1046 
1047 
1048 template<class T> inline
1050  debug_assert_valid_ptr ();
1051  return ArrayRCP<T> (ptr_, lowerOffset_, size (), node_.create_weak ());
1052 }
1053 
1054 template<class T> inline
1056  debug_assert_valid_ptr ();
1057  return ArrayRCP<const T> (ptr_, lowerOffset_, size (), node_.create_weak ());
1058 }
1059 
1060 
1061 template<class T> inline
1063  debug_assert_valid_ptr ();
1064  return ArrayRCP<T> (ptr_, lowerOffset_, size (), node_.create_strong ());
1065 }
1066 
1067 template<class T> inline
1069  debug_assert_valid_ptr ();
1070  return ArrayRCP<const T> (ptr_, lowerOffset_, size (), node_.create_strong ());
1071 }
1072 
1073 
1074 template<class T>
1075 template <class T2>
1076 inline
1078 {
1079  return node_.same_node (r_ptr.access_private_node ());
1080  // Note: above, r_ptr is *not* the same class type as *this so we can not
1081  // access its node_ member directly! This is an interesting detail to the
1082  // C++ protected/private protection mechanism!
1083 }
1084 
1085 template<class T>
1086 template <class T2>
1087 inline
1088 bool ArrayRCP<const T>::shares_resource (const ArrayRCP<T2>& r_ptr) const
1089 {
1090  return node_.same_node (r_ptr.access_private_node ());
1091  // Note: above, r_ptr is *not* the same class type as *this so we can not
1092  // access its node_ member directly! This is an interesting detail to the
1093  // C++ protected/private protection mechanism!
1094 }
1095 
1096 
1097 // Assertion Functions
1098 
1099 
1100 template<class T> inline
1101 const ArrayRCP<T>&
1103 {
1104  if(!ptr_)
1106  return *this;
1107 }
1108 
1109 template<class T> inline
1110 const ArrayRCP<const T>&
1112 {
1113  if (! ptr_) {
1114  throw_null_ptr_error (typeName (*this));
1115  }
1116  return *this;
1117 }
1118 
1119 
1120 template<class T> inline
1122 {
1123  if (ptr_) {
1124  node_.assert_valid_ptr (*this);
1125  }
1126  return *this;
1127 }
1128 
1129 template<class T> inline
1131 {
1132  if (ptr_) {
1133  node_.assert_valid_ptr (*this);
1134  }
1135  return *this;
1136 }
1137 
1138 
1139 template<class T> inline
1140 const ArrayRCP<T>&
1141 ArrayRCP<T>::assert_in_range( size_type lowerOffset_in, size_type size_in ) const
1142 {
1143  assert_not_null();
1145  !(
1146  (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_)
1147  &&
1148  size_in >= 0
1149  ),
1151  typeName(*this)<<"::assert_in_range:"
1152  " Error, [lowerOffset,lowerOffset+size-1] = ["
1153  <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the"
1154  " range ["<<lowerOffset_<<","<<upperOffset_<<"]!"
1155  );
1156  return *this;
1157 }
1158 
1159 template<class T> inline
1160 const ArrayRCP<const T>&
1162 assert_in_range (size_type lowerOffset_in, size_type size_in) const
1163 {
1164  assert_not_null ();
1166  !(
1167  (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_)
1168  &&
1169  size_in >= 0
1170  ),
1172  typeName (*this) << "::assert_in_range:"
1173  " Error, [lowerOffset,lowerOffset+size-1] = ["
1174  <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the"
1175  " range ["<<lowerOffset_<<","<<upperOffset_<<"]!"
1176  );
1177  return *this;
1178 }
1179 
1180 
1181 // 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
1190 int ArrayRCP<const T>::count() const {
1191  return node_.count();
1192 }
1193 
1194 
1195 // very bad public functions
1196 
1197 
1198 template<class T> inline
1199 ArrayRCP<T>::ArrayRCP(
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
1210 ArrayRCP<const T>::ArrayRCP(
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
1222 T* ArrayRCP<T>::access_private_ptr() const
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>
1285 inline void assert_shares_resource(
1286  const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2
1287  )
1288 {
1289 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
1291  !p1.shares_resource(p2), IncompatibleIteratorsError,
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 {
1522  Utilities::assert_shares_resource(p1,p2);
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 {
1531  Utilities::assert_shares_resource(p1,p2);
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 {
1540  Utilities::assert_shares_resource(p1,p2);
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 {
1549  Utilities::assert_shares_resource(p1,p2);
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
T * get() const
Get the raw C++ pointer to the underlying object.
ArrayView< T > arrayView(T *p, typename ArrayView< T >::size_type size)
Construct a const or non-const view to const or non-const data.
bool is_null(const boost::shared_ptr< T > &p)
Returns true if p.get()==NULL.
ArrayRCP(ENull null_arg=null)
Default constructor; initialize to an empty array.
Partial specialization of ArrayRCP for const T.
Ordinal difference_type
Type representing the difference between two size_type values.
size_type size() const
The total number of entries in the array.
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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
const ArrayRCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
ArrayRCP< T > arcp(const RCP< Array< T > > &v)
Wrap an RCP<Array<T> > object as an ArrayRCP<T> object.
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...
TEUCHOS_DEPRECATED int count() const
Returns strong_count() [deprecated].
Ordinal size_type
Type representing the number of elements in an ArrayRCP or view thereof.
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
ArrayRCP< T2 > arcp_reinterpret_cast(const ArrayRCP< T1 > &p1)
Reinterpret cast of underlying ArrayRCP type from T1* to T2*.
const ArrayRCP< T > & assert_valid_ptr() const
If the object pointer is non-null, assert that it is still valid.
Node class to keep track of address and the reference count for a reference-counted utility class and...
bool has_ownership() const
Returns true if this has ownership of object pointed to by this->get() in order to deallocate it...
int total_count() const
Total count (strong_count() + weak_count()).
bool is_valid_ptr() const
Return whether the underlying object pointer is still valid.
ERCPStrength
Used to specify if the pointer is weak or strong.
size_type upperOffset() const
Return the upper offset to valid data.
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
Ptr< T > ptr(T *p)
Create a pointer to an object from a raw pointer.
int weak_count() const
Return the number of active RCP<> objects that have a "weak" reference to the underlying reference-co...
ERCPStrength strength() const
Strength of the pointer.
Nonowning array view.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
Handle class that manages the RCPNode&#39;s reference counting.
ERCPNodeLookup
Used to determine if RCPNode lookup is performed or not.
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
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*.
TEUCHOSCORE_LIB_DLL_EXPORT void throw_null_ptr_error(const std::string &type_name)
Throw that a pointer passed into an RCP object is null.
Smart reference counting pointer class for automatic garbage collection.
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.
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 ...
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
size_type lowerOffset() const
Return the lower offset to valid data.
Definition of Teuchos::as, for conversions between types.
#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...
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
Reference-counted smart pointer for managing arrays.