Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
51namespace Teuchos {
52
53
54// Constructors/Destructors
55
56
57template<class T> inline
59 : ptr_(0), size_(0)
60{
62}
63
64template<class T> inline
66 : ptr_(0), size_(0)
67{
69}
70
71
72
73template<class T> inline
74ArrayView<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
97template<class T> inline
98ArrayView<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
122template<class T> inline
124 :ptr_(array.ptr_), size_(array.size_)
125#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
126 ,arcp_(array.arcp_)
127#endif
128{}
129
130template<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
139template<class T> inline
141 std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
142 )
143 : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
144{
146}
147
148template<class T> inline
150 std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
151 )
152 : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
153{
155}
156
157
158template<class T> inline
160 const std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
161 )
162 : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
163{
165}
166
167template<class T> inline
169 const std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
170 )
171 : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
172{
174}
175
176
177template<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
188template<class T> inline
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
200template<class T> inline
202{}
204template<class T> inline
207
208
209// General query functions
210
211
212template<class T>
213inline
216 return ptr_ == 0;
217}
218
219template<class T>
220inline
223 return ptr_ == 0;
224}
226
227template<class T> inline
229{
230 debug_assert_valid_ptr();
231 return size_;
232}
233
234template<class T> inline
236{
237 debug_assert_valid_ptr();
238 return size_;
239}
241
242template<typename T>
243std::string ArrayView<T>::toString() const
244{
245 using Teuchos::as;
246 std::ostringstream ss;
247
248 debug_assert_valid_ptr();
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
262template<typename T>
263std::string ArrayView<const T>::toString() const
264{
265 using Teuchos::as;
266 std::ostringstream ss;
267
268 debug_assert_valid_ptr();
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 ();
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.
285template<>
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.
291template<>
294
295// Specialization for double. We use sufficient precision that no
296// digits are lost after writing to string and reading back in again.
297template<>
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.
303template<>
306
307
308// Element Access Functions
309
310
311template<class T> inline
313{
314 debug_assert_valid_ptr();
315 return ptr_;
316}
317
318template<class T> inline
320{
321 debug_assert_valid_ptr();
322 return ptr_;
323}
324
325template<class T> inline
326const T* ArrayView<const T>::getRawPtr() const
327{
328 debug_assert_valid_ptr();
329 return ptr_;
330}
331
332template<class T> inline
333const T* ArrayView<const T>::data() const
334{
335 debug_assert_valid_ptr();
336 return ptr_;
338
339template<class T> inline
341{
342 debug_assert_valid_ptr();
343 debug_assert_in_range(i,1);
344 return ptr_[i];
345}
346
347template<class T> inline
348const T& ArrayView<const T>::operator[](size_type i) const
349{
350 debug_assert_valid_ptr();
351 debug_assert_in_range(i,1);
352 return ptr_[i];
353}
354
355
356template<class T> inline
358{
359 debug_assert_not_null();
360 debug_assert_valid_ptr();
361 return *ptr_;
362}
363
364template<class T> inline
365const T& ArrayView<const T>::front() const
367 debug_assert_not_null();
368 debug_assert_valid_ptr();
369 return *ptr_;
370}
371
372template<class T> inline
374{
375 debug_assert_not_null();
376 debug_assert_valid_ptr();
377 return *(ptr_+size_-1);
378}
379
380template<class T> inline
381const T& ArrayView<const T>::back() const
382{
383 debug_assert_not_null();
384 debug_assert_valid_ptr();
385 return *(ptr_+size_-1);
386}
387
388
389// Views
390
391
392template<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
408template<class T> inline
409ArrayView<const T> ArrayView<const T>::view(size_type offset, size_type size_in) const
410{
411 if (size_in == 0) { return null; }
412 debug_assert_valid_ptr();
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
425template<class T> inline
427{
428 return view(offset, size_in);
429}
430
431template<class T> inline
432ArrayView<const T> ArrayView<const T>::operator()(size_type offset, size_type size_in) const
433{
434 return view(offset, size_in);
435}
436
437
438template<class T> inline
440{
441 debug_assert_valid_ptr();
442 return *this;
443}
444
445template<class T> inline
447{
448 debug_assert_valid_ptr();
449 return *this;
450}
451
452
453template<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
464template<class T> inline
466 return *this;
467}
468
469
470template<class T> inline
472{
473 return getConst();
474}
475
476
477// Assignment
478
479
480template<class T>
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
497template<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
508template<class T>
510{
511 debug_assert_valid_ptr();
512#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
513 return arcp_.create_weak();
514#else
515 return ptr_;
516#endif
517}
518
519
520template<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
531template<class T>
533{
534 debug_assert_valid_ptr();
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
546template<class T>
548{
549 if(!ptr_)
550 throw_null_ptr_error(typeName(*this));
551 return *this;
552}
553
554template<class T>
556{
557 if(!ptr_)
558 throw_null_ptr_error(typeName(*this));
559 return *this;
560}
561
562
563template<class T>
564const 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 ),
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
584template<class T>
586ArrayView<const T>::assert_in_range(size_type offset, size_type size_in) const
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 ),
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
608template<class T>
609ArrayView<T>::ArrayView( const ArrayRCP<T> &arcp )
610 : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
611{}
612
613template<class T>
614ArrayView<const T>::ArrayView( const ArrayRCP<const T> &arcp )
615 : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
616{}
617
618
619template<class T>
620ArrayView<T>::ArrayView(T* p, size_type size_in, const ArrayRCP<T> &arcp)
621 : ptr_(p), size_(size_in), arcp_(arcp)
622{}
623
624template<class T>
625ArrayView<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
636template<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
648template<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
669template<class T> inline
671Teuchos::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
679template<class T> inline
680Teuchos::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
688template<class T> inline
689Teuchos::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
699template<class T> inline
700std::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
709template<class T> inline
710std::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
717template<class T> inline
718bool Teuchos::is_null( const ArrayView<T> &av )
719{
720 return av.is_null();
721}
722
723
724template<class T> inline
725bool Teuchos::nonnull( const ArrayView<T> &av )
726{
727 return !av.is_null();
728}
729
730
731template<class T>
732std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayView<T>& p )
733{
734 return out << p.toString();
735}
736
737
738template<class T2, class T1>
741Teuchos::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
749template<class T2, class T1>
752Teuchos::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
#define TEUCHOSCORE_LIB_DLL_EXPORT
#define REFCOUNTPTR_INLINE
Definition of Teuchos::as, for conversions between types.
Reference-counted smart pointer for managing arrays.
Nonowning array view.
void setUpIterators(const ERCPNodeLookup rcpNodeLookup=RCP_ENABLE_NODE_LOOKUP)
bool is_null() const
Returns true if the underlying pointer is null.
iterator end() const
Return an iterator to past the end of the array of data.
const ArrayView< T > & assert_in_range(size_type offset, size_type size) const
Throws NullReferenceError if this->get()==NULL orthis->get()!=NULL, throws RangeError if (offset < 0 ...
iterator begin() const
Return an iterator to beginning of the array of data.
ArrayView(ENull null_arg=null)
Constructor that initializes to NULL (implicitly or explicitly).
T & front() const
Get the first element.
ArrayView< T > & operator=(const ArrayView< T > &array)
Shallow copy assignment operator.
const ArrayView< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
ArrayView< T > view(size_type offset, size_type size) const
Return a view of a contiguous range of elements.
T * data() const
Return a raw pointer to beginning of array.
ArrayView< const T > getConst() const
Return a const view of a possibly nonconst view.
const ArrayView< T > & operator()() const
Return *this (just for compatibility with Array and ArrayPtr).
pointer iterator
Type of a nonconst iterator.
size_type size() const
The total number of items in the managed array.
T & back() const
Get the last element.
void assign(const ArrayView< const T > &array) const
Copy the data from one array view object to this array view object.
std::string toString() const
Convert an ArrayView<T> to an std::string
T * getRawPtr() const
Return a raw pointer to beginning of array or NULL if unsized.
T & operator[](size_type i) const
Random object access.
Ordinal size_type
Type representing the number of elements in an ArrayRCP or view thereof.
Range error exception class.
#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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
std::ostream & operator<<(std::ostream &os, BigUInt< n > a)
ERCPNodeLookup
Used to determine if RCPNode lookup is performed or not.
RawPointerConversionTraits< Container >::Ptr_t getRawPtr(const Container &c)
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.