Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_ArrayView.hpp
1// @HEADER
2// *****************************************************************************
3// Teuchos: Common Tools Package
4//
5// Copyright 2004 NTESS and the Teuchos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef TEUCHOS_ARRAY_VIEW_HPP
11#define TEUCHOS_ARRAY_VIEW_HPP
12
13
14#include "Teuchos_ArrayViewDecl.hpp"
15#include "Teuchos_ArrayRCP.hpp"
16#include "Teuchos_as.hpp"
17
18
19namespace Teuchos {
20
21
22// Constructors/Destructors
23
24
25template<class T> inline
27 : ptr_(0), size_(0)
28{
29 setUpIterators();
30}
31
32template<class T> inline
34 : ptr_(0), size_(0)
35{
36 setUpIterators();
37}
38
39
40
41template<class T> inline
43 :ptr_(size_in == 0 ? nullptr : p), size_(size_in)
44{
45#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
46 // We comment out the one check below, as part of the fix for #4234:
47 //
48 // https://github.com/trilinos/Trilinos/issues/4234
49 //
50 // This permits conversion from std::vector or Kokkos::View, using
51 // ArrayView(x.data(), x.size(), RCP_DISABLE_NODE_LOOKUP). The
52 // other part of the fix is that we make sure ptr_ is null if
53 // size_in is zero.
54 //
55 //TEUCHOS_TEST_FOR_EXCEPT( p != 0 && size_in <= 0 );
56
57 TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 );
58 // This only does something if HAVE_TEUCHOS_ARRAY_BOUNDSCHECK is defined.
59 setUpIterators(rcpNodeLookup);
60#else
61 (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
62#endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
63}
64
65template<class T> inline
67 : ptr_(size_in == 0 ? nullptr : p), size_(size_in)
68{
69#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
70 // We comment out the one check below, as part of the fix for #4234:
71 //
72 // https://github.com/trilinos/Trilinos/issues/4234
73 //
74 // This permits conversion from std::vector or Kokkos::View, using
75 // ArrayView(x.data(), x.size(), RCP_DISABLE_NODE_LOOKUP). The
76 // other part of the fix is that we make sure ptr_ is null if
77 // size_in is zero.
78 //
79 //TEUCHOS_TEST_FOR_EXCEPT( p != 0 && size_in <= 0 );
80
81 TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 );
82 // This only does something if HAVE_TEUCHOS_ARRAY_BOUNDSCHECK is defined.
83 setUpIterators(rcpNodeLookup);
84#else
85 (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
86#endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
87}
88
89
90template<class T> inline
97
98template<class T> inline
100 :ptr_(array.ptr_), size_(array.size_)
103#endif
104{}
105
106
107template<class T> inline
109 std::vector<typename std::remove_const_t<T>>& vec
110 )
111 : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
112{
113 setUpIterators();
114}
115
116template<class T> inline
118 std::vector<typename std::remove_const_t<T>>& vec
119 )
120 : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
121{
122 setUpIterators();
123}
124
125
126template<class T> inline
128 const std::vector<typename std::remove_const_t<T>>& vec
129 )
130 : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
131{
132 setUpIterators();
133}
134
135template<class T> inline
137 const std::vector<typename std::remove_const_t<T>>& vec
138 )
139 : ptr_( vec.empty() ? 0 : vec.data() ), size_(vec.size())
141 setUpIterators();
142}
143
144
145template<class T> inline
147{
148 ptr_ = array.ptr_;
149 size_ = array.size_;
150#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
151 arcp_ = array.arcp_;
152#endif
153 return *this;
154}
155
156template<class T> inline
158{
159 ptr_ = array.ptr_;
160 size_ = array.size_;
161#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
162 arcp_ = array.arcp_;
163#endif
164 return *this;
165}
166
167
168template<class T> inline
171
172template<class T> inline
174{}
175
177// General query functions
178
180template<class T>
181inline
183{
184 return ptr_ == 0;
185}
186
187template<class T>
188inline
190{
191 return ptr_ == 0;
193
194
195template<class T> inline
197{
199 return size_;
200}
201
202template<class T> inline
204{
206 return size_;
208
209
210template<typename T>
211std::string ArrayView<T>::toString() const
212{
213 using Teuchos::as;
214 std::ostringstream ss;
215
217
218 ss << "{";
219 for (size_type i = 0; i < size (); ++i) {
220 // NOTE: This depends on std::ostream::operator<<(const T&).
221 ss << operator[] (i);
222 if (i + 1 < size ()) {
223 ss << ", ";
224 }
225 }
226 ss << "}";
227 return ss.str ();
228}
229
230template<typename T>
231std::string ArrayView<const T>::toString() const
232{
233 using Teuchos::as;
234 std::ostringstream ss;
235
237
238 ss << "{";
239 for (size_type i = 0; i < size (); ++i) {
240 // NOTE: This depends on std::ostream::operator<<(const T&).
241 ss << operator[] (i);
242 if (i + 1 < size ()) {
243 ss << ", ";
244 }
245 }
246 ss << "}";
247 return ss.str ();
248}
249
251// Specialization for float. We use sufficient precision that no
252// digits are lost after writing to string and reading back in again.
253template<>
254TEUCHOSCORE_LIB_DLL_EXPORT std::string
256
257// Specialization for (const) float. We use sufficient precision that no
258// digits are lost after writing to string and reading back in again.
259template<>
260TEUCHOSCORE_LIB_DLL_EXPORT std::string
263// Specialization for double. We use sufficient precision that no
264// digits are lost after writing to string and reading back in again.
265template<>
266TEUCHOSCORE_LIB_DLL_EXPORT std::string
268
269// Specialization for (const) double. We use sufficient precision that no
270// digits are lost after writing to string and reading back in again.
271template<>
272TEUCHOSCORE_LIB_DLL_EXPORT std::string
274
275
276// Element Access Functions
277
278
279template<class T> inline
281{
283 return ptr_;
284}
285
286template<class T> inline
288{
290 return ptr_;
291}
292
293template<class T> inline
294const T* ArrayView<const T>::getRawPtr() const
295{
297 return ptr_;
298}
299
300template<class T> inline
301const T* ArrayView<const T>::data() const
302{
304 return ptr_;
305}
306
307template<class T> inline
309{
311 debug_assert_in_range(i,1);
312 return ptr_[i];
313}
314
315template<class T> inline
316const T& ArrayView<const T>::operator[](size_type i) const
317{
319 debug_assert_in_range(i,1);
320 return ptr_[i];
321}
322
323
324template<class T> inline
326{
329 return *ptr_;
330}
331
332template<class T> inline
334{
337 return *ptr_;
338}
339
340template<class T> inline
342{
345 return *(ptr_+size_-1);
346}
347
348template<class T> inline
349const T& ArrayView<const T>::back() const
350{
353 return *(ptr_+size_-1);
354}
355
356
357// Views
358
359
360template<class T> inline
362{
363 if (size_in == 0) { return null; }
365 debug_assert_in_range(offset, size_in);
366 return ArrayView<T>(
367 ptr_+offset, size_in
369 ,arcp_.persistingView(offset, size_in)
370#endif
371 );
372 // WARNING: The above code had better be correct since we are using raw
373 // pointer arithmetic!
374}
375
376template<class T> inline
378{
379 if (size_in == 0) { return null; }
381 debug_assert_in_range(offset, size_in);
382 return ArrayView<const T>(
383 ptr_+offset, size_in
384#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
385 ,arcp_.persistingView(offset, size_in)
386#endif
387 );
388 // WARNING: The above code had better be correct since we are using raw
389 // pointer arithmetic!
390}
391
392
393template<class T> inline
398
399template<class T> inline
401{
402 return view(offset, size_in);
403}
404
405
406template<class T> inline
408{
410 return *this;
411}
412
413template<class T> inline
415{
417 return *this;
418}
419
420
421template<class T> inline
423{
425#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
427#else
428 return ArrayView<const T>(ptr_, size_);
429#endif
430}
431
432template<class T> inline
434 return *this;
435}
436
437
438template<class T> inline
440{
441 return getConst();
442}
443
444
445// Assignment
446
447
448template<class T>
450{
453 if (this->getRawPtr()==array.getRawPtr() && this->size()==array.size())
454 return; // Assignment to self
455 debug_assert_in_range(0,array.size());
456 std::copy( array.begin(), array.end(), this->begin() );
457 // Note: Above, in debug mode, the iterators are range checked! In
458 // optimized mode, these are raw pointers which should run very fast!
459}
460
461
462// Standard Container-Like Functions
463
464
465template<class T>
467{
469#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
470 return arcp_.create_weak();
471#else
472 return ptr_;
473#endif
474}
475
476template<class T>
478{
480#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
481 return arcp_.create_weak();
482#else
483 return ptr_;
484#endif
485}
486
487
488template<class T>
490{
492#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
493 return arcp_.create_weak() + size_;
494#else
495 return ptr_ + size_;
496#endif
497}
498
499template<class T>
501{
503#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
504 return arcp_.create_weak() + size_;
505#else
506 return ptr_ + size_;
507#endif
508}
509
510
511// Assertion Functions.
512
513
514template<class T>
516{
517 if(!ptr_)
518 throw_null_ptr_error(typeName(*this));
519 return *this;
520}
521
522template<class T>
524{
525 if(!ptr_)
526 throw_null_ptr_error(typeName(*this));
527 return *this;
528}
529
530
531template<class T>
532const ArrayView<T>&
534{
537 "Error, size=0 is not allowed!" );
539 !(
540 ( 0 <= offset && offset+size_in <= this->size() )
541 &&
542 size_in >= 0
543 ),
545 typeName(*this)<<"::assert_in_range():"
546 " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")"
547 " does not lie in the range [0,"<<this->size()<<")!"
548 );
549 return*this;
550}
551
552template<class T>
554ArrayView<const T>::assert_in_range(size_type offset, size_type size_in) const
555{
558 "Error, size=0 is not allowed!" );
560 !(
561 ( 0 <= offset && offset+size_in <= this->size() )
562 &&
563 size_in >= 0
564 ),
566 typeName(*this)<<"::assert_in_range():"
567 " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")"
568 " does not lie in the range [0,"<<this->size()<<")!"
569 );
570 return*this;
571}
572
573
574#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
575
576template<class T>
577ArrayView<T>::ArrayView( const ArrayRCP<T> &arcp )
578 : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
579{}
580
581template<class T>
582ArrayView<const T>::ArrayView( const ArrayRCP<const T> &arcp )
583 : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
584{}
585
586
587template<class T>
588ArrayView<T>::ArrayView(T* p, size_type size_in, const ArrayRCP<T> &arcp)
589 : ptr_(p), size_(size_in), arcp_(arcp)
590{}
591
592template<class T>
593ArrayView<const T>::ArrayView(const T* p, size_type size_in, const ArrayRCP<const T> &arcp)
594 : ptr_(p), size_(size_in), arcp_(arcp)
595{}
596
597
598#endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
599
600
601// private
602
603
604template<class T>
605void ArrayView<T>::setUpIterators(const ERCPNodeLookup rcpNodeLookup)
606{
607#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
608 if (ptr_ && arcp_.is_null()) {
609 arcp_ = ArrayRCP<T>(ptr_, 0, size_, false, rcpNodeLookup);
610 }
611#else
612 (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
613#endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
614}
615
616template<class T>
617void ArrayView<const T>::setUpIterators(const ERCPNodeLookup rcpNodeLookup)
618{
619#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
620 if (ptr_ && arcp_.is_null()) {
621 arcp_ = ArrayRCP<const T>(ptr_, 0, size_, false, rcpNodeLookup);
622 }
623#else
624 (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
625#endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
626}
627
628
629} // namespace Teuchos
630
631
632//
633// Nonmember helper functions
634//
635
636
637template<class T> inline
639Teuchos::arrayView( T* p, typename ArrayView<T>::size_type size )
640{
641 if (size == 0)
642 return null;
643 return ArrayView<T>(p, size);
644}
645
646
647template<class T> inline
648Teuchos::ArrayView<T> Teuchos::arrayViewFromVector( std::vector<T>& vec )
649{
650 if (vec.size() == 0)
651 return null;
652 return ArrayView<T>(vec);
653}
654
655
656template<class T> inline
657Teuchos::ArrayView<const T> Teuchos::arrayViewFromVector( const std::vector<T>& vec )
658{
659 if (vec.size() == 0)
660 return null;
661 return ArrayView<const T>(vec);
662}
663
664
665#ifndef __sun
666
667template<class T> inline
668std::vector<T> Teuchos::createVector( const ArrayView<T> &av )
669{
670 std::vector<T> v(av.begin(), av.end());
671 return v;
672}
673
674#endif // __sun
675
676
677template<class T> inline
678std::vector<T> Teuchos::createVector( const ArrayView<const T> &av )
679{
680 std::vector<T> v(av.begin(), av.end());
681 return v;
682}
683
684
685template<class T> inline
686bool Teuchos::is_null( const ArrayView<T> &av )
687{
688 return av.is_null();
689}
690
691
692template<class T> inline
693bool Teuchos::nonnull( const ArrayView<T> &av )
694{
695 return !av.is_null();
696}
697
698
699template<class T>
700std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayView<T>& p )
701{
702 return out << p.toString();
703}
704
705
706template<class T2, class T1>
707REFCOUNTPTR_INLINE
709Teuchos::av_const_cast(const ArrayView<T1>& p1)
710{
711 T2 *ptr2 = const_cast<T2*>(p1.getRawPtr());
712 return ArrayView<T2>(ptr2, p1.size());
713 // Note: Above is just fine even if p1.get()==NULL!
714}
715
716
717template<class T2, class T1>
718REFCOUNTPTR_INLINE
720Teuchos::av_reinterpret_cast(const ArrayView<T1>& p1)
721{
722 typedef typename ArrayView<T1>::size_type size_type;
723 const int sizeOfT1 = sizeof(T1);
724 const int sizeOfT2 = sizeof(T2);
725 size_type size2 = (p1.size()*sizeOfT1) / sizeOfT2;
726 T2 *ptr2 = reinterpret_cast<T2*>(p1.getRawPtr());
727 return ArrayView<T2>(
728 ptr2, size2
729#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
730 ,arcp_reinterpret_cast<T2>(p1.access_private_arcp())
731#endif
732 );
733 // Note: Above is just fine even if p1.get()==NULL!
734}
735
736
737#endif // TEUCHOS_ARRAY_VIEW_HPP
Definition of Teuchos::as, for conversions between types.
Nonowning array view.
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.
Smart reference counting pointer class for automatic garbage collection.
RCP< const T > getConst() const
Return an RCP<const T> version of *this.
RCP< T > create_weak() const
Create a new weak RCP object from another (strong) RCP object.
bool is_null() const
Returns true if the underlying pointer is null.
T * getRawPtr() const
Get the raw C++ pointer to the underlying object.
const RCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
const RCP< T > & debug_assert_valid_ptr() const
Calls assert_valid_ptr() in a debug build.
const RCP< T > & debug_assert_not_null() const
Calls assert_not_null() in a debug build.
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.
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
ERCPNodeLookup
Used to determine if RCPNode lookup is performed or not.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...