Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_ArrayView.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_ARRAY_VIEW_HPP
43 #define TEUCHOS_ARRAY_VIEW_HPP
44 
45 
47 #include "Teuchos_ArrayRCP.hpp"
48 #include "Teuchos_as.hpp"
49 
50 
51 namespace Teuchos {
52 
53 
54 // Constructors/Destructors
55 
56 
57 template<class T> inline
59  : ptr_(0), size_(0)
60 {
62 }
63 
64 template<class T> inline
66  : ptr_(0), size_(0)
67 {
69 }
70 
71 
72 
73 template<class T> inline
74 ArrayView<T>::ArrayView( T* p, size_type size_in, const ERCPNodeLookup rcpNodeLookup )
75  :ptr_(size_in == 0 ? nullptr : p), size_(size_in)
76 {
77 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
78  // We comment out the one check below, as part of the fix for #4234:
79  //
80  // https://github.com/trilinos/Trilinos/issues/4234
81  //
82  // This permits conversion from std::vector or Kokkos::View, using
83  // ArrayView(x.data(), x.size(), RCP_DISABLE_NODE_LOOKUP). The
84  // other part of the fix is that we make sure ptr_ is null if
85  // size_in is zero.
86  //
87  //TEUCHOS_TEST_FOR_EXCEPT( p != 0 && size_in <= 0 );
88 
89  TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 );
90  // This only does something if HAVE_TEUCHOS_ARRAY_BOUNDSCHECK is defined.
91  setUpIterators(rcpNodeLookup);
92 #else
93  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
94 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
95 }
96 
97 template<class T> inline
98 ArrayView<const T>::ArrayView(const T* p, size_type size_in, const ERCPNodeLookup rcpNodeLookup )
99  : ptr_(size_in == 0 ? nullptr : p), size_(size_in)
100 {
101 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
102  // We comment out the one check below, as part of the fix for #4234:
103  //
104  // https://github.com/trilinos/Trilinos/issues/4234
105  //
106  // This permits conversion from std::vector or Kokkos::View, using
107  // ArrayView(x.data(), x.size(), RCP_DISABLE_NODE_LOOKUP). The
108  // other part of the fix is that we make sure ptr_ is null if
109  // size_in is zero.
110  //
111  //TEUCHOS_TEST_FOR_EXCEPT( p != 0 && size_in <= 0 );
112 
113  TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 );
114  // This only does something if HAVE_TEUCHOS_ARRAY_BOUNDSCHECK is defined.
115  setUpIterators(rcpNodeLookup);
116 #else
117  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
118 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
119 }
120 
121 
122 template<class T> inline
124  :ptr_(array.ptr_), size_(array.size_)
125 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
126  ,arcp_(array.arcp_)
127 #endif
128 {}
129 
130 template<class T> inline
132  :ptr_(array.ptr_), size_(array.size_)
133 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
134  ,arcp_(array.arcp_)
135 #endif
136 {}
137 
138 
139 template<class T> inline
141  std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
142  )
143  : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
144 {
145  setUpIterators();
146 }
147 
148 template<class T> inline
150  std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
151  )
152  : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
153 {
154  setUpIterators();
155 }
156 
157 
158 template<class T> inline
160  const std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
161  )
162  : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
163 {
164  setUpIterators();
165 }
166 
167 template<class T> inline
169  const std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
170  )
171  : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
172 {
173  setUpIterators();
174 }
175 
176 
177 template<class T> inline
179 {
180  ptr_ = array.ptr_;
181  size_ = array.size_;
182 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
183  arcp_ = array.arcp_;
184 #endif
185  return *this;
186 }
187 
188 template<class T> inline
190 {
191  ptr_ = array.ptr_;
192  size_ = array.size_;
193 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
194  arcp_ = array.arcp_;
195 #endif
196  return *this;
197 }
198 
199 
200 template<class T> inline
202 {}
203 
204 template<class T> inline
206 {}
207 
208 
209 // General query functions
210 
211 
212 template<class T>
213 inline
215 {
216  return ptr_ == 0;
217 }
218 
219 template<class T>
220 inline
222 {
223  return ptr_ == 0;
224 }
225 
226 
227 template<class T> inline
229 {
230  debug_assert_valid_ptr();
231  return size_;
232 }
233 
234 template<class T> inline
236 {
238  return size_;
239 }
240 
241 
242 template<typename T>
243 std::string ArrayView<T>::toString() const
244 {
245  using Teuchos::as;
246  std::ostringstream ss;
247 
248  debug_assert_valid_ptr();
249 
250  ss << "{";
251  for (size_type i = 0; i < size (); ++i) {
252  // NOTE: This depends on std::ostream::operator<<(const T&).
253  ss << operator[] (i);
254  if (i + 1 < size ()) {
255  ss << ", ";
256  }
257  }
258  ss << "}";
259  return ss.str ();
260 }
261 
262 template<typename T>
263 std::string ArrayView<const T>::toString() const
264 {
265  using Teuchos::as;
266  std::ostringstream ss;
267 
269 
270  ss << "{";
271  for (size_type i = 0; i < size (); ++i) {
272  // NOTE: This depends on std::ostream::operator<<(const T&).
273  ss << operator[] (i);
274  if (i + 1 < size ()) {
275  ss << ", ";
276  }
277  }
278  ss << "}";
279  return ss.str ();
280 }
281 
282 
283 // Specialization for float. We use sufficient precision that no
284 // digits are lost after writing to string and reading back in again.
285 template<>
286 TEUCHOSCORE_LIB_DLL_EXPORT std::string
288 
289 // Specialization for (const) float. We use sufficient precision that no
290 // digits are lost after writing to string and reading back in again.
291 template<>
292 TEUCHOSCORE_LIB_DLL_EXPORT std::string
294 
295 // Specialization for double. We use sufficient precision that no
296 // digits are lost after writing to string and reading back in again.
297 template<>
298 TEUCHOSCORE_LIB_DLL_EXPORT std::string
300 
301 // Specialization for (const) double. We use sufficient precision that no
302 // digits are lost after writing to string and reading back in again.
303 template<>
304 TEUCHOSCORE_LIB_DLL_EXPORT std::string
306 
307 
308 // Element Access Functions
309 
310 
311 template<class T> inline
313 {
314  debug_assert_valid_ptr();
315  return ptr_;
316 }
317 
318 template<class T> inline
320 {
321  debug_assert_valid_ptr();
322  return ptr_;
323 }
324 
325 template<class T> inline
327 {
329  return ptr_;
330 }
331 
332 template<class T> inline
333 const T* ArrayView<const T>::data() const
334 {
336  return ptr_;
337 }
338 
339 template<class T> inline
341 {
342  debug_assert_valid_ptr();
343  debug_assert_in_range(i,1);
344  return ptr_[i];
345 }
346 
347 template<class T> inline
349 {
352  return ptr_[i];
353 }
354 
355 
356 template<class T> inline
358 {
359  debug_assert_not_null();
360  debug_assert_valid_ptr();
361  return *ptr_;
362 }
363 
364 template<class T> inline
366 {
369  return *ptr_;
370 }
371 
372 template<class T> inline
374 {
375  debug_assert_not_null();
376  debug_assert_valid_ptr();
377  return *(ptr_+size_-1);
378 }
379 
380 template<class T> inline
381 const T& ArrayView<const T>::back() const
382 {
385  return *(ptr_+size_-1);
386 }
387 
388 
389 // Views
390 
391 
392 template<class T> inline
394 {
395  if (size_in == 0) { return null; }
396  debug_assert_valid_ptr();
397  debug_assert_in_range(offset, size_in);
398  return ArrayView<T>(
399  ptr_+offset, size_in
400 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
401  ,arcp_.persistingView(offset, size_in)
402 #endif
403  );
404  // WARNING: The above code had better be correct since we are using raw
405  // pointer arithmetic!
406 }
407 
408 template<class T> inline
410 {
411  if (size_in == 0) { return null; }
413  debug_assert_in_range(offset, size_in);
414  return ArrayView<const T>(
415  ptr_+offset, size_in
416 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
417  ,arcp_.persistingView(offset, size_in)
418 #endif
419  );
420  // WARNING: The above code had better be correct since we are using raw
421  // pointer arithmetic!
422 }
423 
424 
425 template<class T> inline
427 {
428  return view(offset, size_in);
429 }
430 
431 template<class T> inline
433 {
434  return view(offset, size_in);
435 }
436 
437 
438 template<class T> inline
440 {
441  debug_assert_valid_ptr();
442  return *this;
443 }
444 
445 template<class T> inline
447 {
449  return *this;
450 }
451 
452 
453 template<class T> inline
455 {
456  debug_assert_valid_ptr();
457 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
458  return ArrayView<const T>(arcp_.getConst());
459 #else
460  return ArrayView<const T>(ptr_, size_);
461 #endif
462 }
463 
464 template<class T> inline
466  return *this;
467 }
468 
469 
470 template<class T> inline
472 {
473  return getConst();
474 }
475 
476 
477 // Assignment
478 
479 
480 template<class T>
481 void ArrayView<T>::assign(const ArrayView<const T>& array) const
482 {
483  debug_assert_valid_ptr();
484  debug_assert_not_null();
485  if (this->getRawPtr()==array.getRawPtr() && this->size()==array.size())
486  return; // Assignment to self
487  debug_assert_in_range(0,array.size());
488  std::copy( array.begin(), array.end(), this->begin() );
489  // Note: Above, in debug mode, the iterators are range checked! In
490  // optimized mode, these are raw pointers which should run very fast!
491 }
492 
493 
494 // Standard Container-Like Functions
495 
496 
497 template<class T>
499 {
500  debug_assert_valid_ptr();
501 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
502  return arcp_.create_weak();
503 #else
504  return ptr_;
505 #endif
506 }
507 
508 template<class T>
510 {
512 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
513  return arcp_.create_weak();
514 #else
515  return ptr_;
516 #endif
517 }
518 
519 
520 template<class T>
522 {
523  debug_assert_valid_ptr();
524 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
525  return arcp_.create_weak() + size_;
526 #else
527  return ptr_ + size_;
528 #endif
529 }
530 
531 template<class T>
533 {
535 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
536  return arcp_.create_weak() + size_;
537 #else
538  return ptr_ + size_;
539 #endif
540 }
541 
542 
543 // Assertion Functions.
544 
545 
546 template<class T>
548 {
549  if(!ptr_)
550  throw_null_ptr_error(typeName(*this));
551  return *this;
552 }
553 
554 template<class T>
556 {
557  if(!ptr_)
558  throw_null_ptr_error(typeName(*this));
559  return *this;
560 }
561 
562 
563 template<class T>
564 const ArrayView<T>&
566 {
567  assert_not_null();
568  TEUCHOS_TEST_FOR_EXCEPTION( size_in == as<size_type>(0), RangeError,
569  "Error, size=0 is not allowed!" );
571  !(
572  ( 0 <= offset && offset+size_in <= this->size() )
573  &&
574  size_in >= 0
575  ),
576  RangeError,
577  typeName(*this)<<"::assert_in_range():"
578  " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")"
579  " does not lie in the range [0,"<<this->size()<<")!"
580  );
581  return*this;
582 }
583 
584 template<class T>
585 const ArrayView<const T>&
587 {
588  assert_not_null();
589  TEUCHOS_TEST_FOR_EXCEPTION( size_in == as<size_type>(0), RangeError,
590  "Error, size=0 is not allowed!" );
592  !(
593  ( 0 <= offset && offset+size_in <= this->size() )
594  &&
595  size_in >= 0
596  ),
597  RangeError,
598  typeName(*this)<<"::assert_in_range():"
599  " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")"
600  " does not lie in the range [0,"<<this->size()<<")!"
601  );
602  return*this;
603 }
604 
605 
606 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
607 
608 template<class T>
610  : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
611 {}
612 
613 template<class T>
614 ArrayView<const T>::ArrayView( const ArrayRCP<const T> &arcp )
615  : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
616 {}
617 
618 
619 template<class T>
620 ArrayView<T>::ArrayView(T* p, size_type size_in, const ArrayRCP<T> &arcp)
621  : ptr_(p), size_(size_in), arcp_(arcp)
622 {}
623 
624 template<class T>
625 ArrayView<const T>::ArrayView(const T* p, size_type size_in, const ArrayRCP<const T> &arcp)
626  : ptr_(p), size_(size_in), arcp_(arcp)
627 {}
628 
629 
630 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
631 
632 
633 // private
634 
635 
636 template<class T>
638 {
639 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
640  if (ptr_ && arcp_.is_null()) {
641  arcp_ = ArrayRCP<T>(ptr_, 0, size_, false, rcpNodeLookup);
642  }
643 #else
644  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
645 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
646 }
647 
648 template<class T>
650 {
651 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
652  if (ptr_ && arcp_.is_null()) {
653  arcp_ = ArrayRCP<const T>(ptr_, 0, size_, false, rcpNodeLookup);
654  }
655 #else
656  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
657 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
658 }
659 
660 
661 } // namespace Teuchos
662 
663 
664 //
665 // Nonmember helper functions
666 //
667 
668 
669 template<class T> inline
671 Teuchos::arrayView( T* p, typename ArrayView<T>::size_type size )
672 {
673  if (size == 0)
674  return null;
675  return ArrayView<T>(p, size);
676 }
677 
678 
679 template<class T> inline
680 Teuchos::ArrayView<T> Teuchos::arrayViewFromVector( std::vector<T>& vec )
681 {
682  if (vec.size() == 0)
683  return null;
684  return ArrayView<T>(vec);
685 }
686 
687 
688 template<class T> inline
689 Teuchos::ArrayView<const T> Teuchos::arrayViewFromVector( const std::vector<T>& vec )
690 {
691  if (vec.size() == 0)
692  return null;
693  return ArrayView<const T>(vec);
694 }
695 
696 
697 #ifndef __sun
698 
699 template<class T> inline
700 std::vector<T> Teuchos::createVector( const ArrayView<T> &av )
701 {
702  std::vector<T> v(av.begin(), av.end());
703  return v;
704 }
705 
706 #endif // __sun
707 
708 
709 template<class T> inline
710 std::vector<T> Teuchos::createVector( const ArrayView<const T> &av )
711 {
712  std::vector<T> v(av.begin(), av.end());
713  return v;
714 }
715 
716 
717 template<class T> inline
718 bool Teuchos::is_null( const ArrayView<T> &av )
719 {
720  return av.is_null();
721 }
722 
723 
724 template<class T> inline
725 bool Teuchos::nonnull( const ArrayView<T> &av )
726 {
727  return !av.is_null();
728 }
729 
730 
731 template<class T>
732 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayView<T>& p )
733 {
734  return out << p.toString();
735 }
736 
737 
738 template<class T2, class T1>
741 Teuchos::av_const_cast(const ArrayView<T1>& p1)
742 {
743  T2 *ptr2 = const_cast<T2*>(p1.getRawPtr());
744  return ArrayView<T2>(ptr2, p1.size());
745  // Note: Above is just fine even if p1.get()==NULL!
746 }
747 
748 
749 template<class T2, class T1>
752 Teuchos::av_reinterpret_cast(const ArrayView<T1>& p1)
753 {
754  typedef typename ArrayView<T1>::size_type size_type;
755  const int sizeOfT1 = sizeof(T1);
756  const int sizeOfT2 = sizeof(T2);
757  size_type size2 = (p1.size()*sizeOfT1) / sizeOfT2;
758  T2 *ptr2 = reinterpret_cast<T2*>(p1.getRawPtr());
759  return ArrayView<T2>(
760  ptr2, size2
761 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
762  ,arcp_reinterpret_cast<T2>(p1.access_private_arcp())
763 #endif
764  );
765  // Note: Above is just fine even if p1.get()==NULL!
766 }
767 
768 
769 #endif // TEUCHOS_ARRAY_VIEW_HPP
std::string toString() const
Convert an ArrayView&lt;T&gt; to an std::string
void setUpIterators(const ERCPNodeLookup rcpNodeLookup=RCP_ENABLE_NODE_LOOKUP)
T & front() const
Get the first element.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
pointer iterator
Type of a nonconst iterator.
bool is_null() const
Returns true if the underlying pointer is null.
const ArrayView< T > & assert_in_range(size_type offset, size_type size) const
Throws NullReferenceError if this-&gt;get()==NULL orthis-&gt;get()!=NULL, throws RangeError if (offset &lt; 0 ...
Partial specialization of ArrayRCP for const T.
iterator begin() const
Return an iterator to beginning of the array of data.
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_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Ordinal size_type
Type representing the number of elements in an ArrayRCP or view thereof.
RawPointerConversionTraits< Container >::Ptr_t getRawPtr(const Container &c)
size_type size() const
The total number of items in the managed array.
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
#define REFCOUNTPTR_INLINE
ERCPNodeLookup
Used to determine if RCPNode lookup is performed or not.
ENull
Used to initialize a RCP object to NULL using an implicit conversion!
T * data() const
Return a raw pointer to beginning of array.
ArrayRCP< T2 > arcp_reinterpret_cast(const ArrayRCP< T1 > &p1)
Reinterpret cast of underlying ArrayRCP type from T1* to T2*.
void assign(const ArrayView< const T > &array) const
Copy the data from one array view object to this array view object.
void debug_assert_in_range(size_type offset, size_type size_in) const
void debug_assert_not_null() const
#define TEUCHOSCORE_LIB_DLL_EXPORT
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
T * getRawPtr() const
Return a raw pointer to beginning of array or NULL if unsized.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
const ArrayView< T > & assert_not_null() const
Throws NullReferenceError if this-&gt;get()==NULL, otherwise returns reference to *this.
void debug_assert_valid_ptr() const
const ArrayView< T > & operator()() const
Return *this (just for compatibility with Array and ArrayPtr).
Nonowning array view.
ArrayView(ENull null_arg=null)
Constructor that initializes to NULL (implicitly or explicitly).
iterator end() const
Return an iterator to past the end of the array of data.
ArrayView< T > view(size_type offset, size_type size) const
Return a view of a contiguous range of elements.
Partial specialization of ArrayView for const T.
Range error exception class.
T & operator[](size_type i) const
Random object access.
ArrayView< T > & operator=(const ArrayView< T > &array)
Shallow copy assignment operator.
Definition of Teuchos::as, for conversions between types.
ArrayView< const T > getConst() const
Return a const view of a possibly nonconst view.
T & back() const
Get the last element.
#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...
Reference-counted smart pointer for managing arrays.