Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
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 {
61  setUpIterators();
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_(p), size_(size_in)
76 {
77 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
78  TEUCHOS_TEST_FOR_EXCEPT( p != 0 && size_in <= 0 );
79  TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 );
80  // This only does something if HAVE_TEUCHOS_ARRAY_BOUNDSCHECK is defined.
81  setUpIterators(rcpNodeLookup);
82 #else
83  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
84 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
85 }
86 
87 template<class T> inline
88 ArrayView<const T>::ArrayView(const T* p, size_type size_in, const ERCPNodeLookup rcpNodeLookup )
89  : ptr_(p), size_(size_in)
90 {
91 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
92  TEUCHOS_TEST_FOR_EXCEPT( p != 0 && size_in <= 0 );
93  TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 );
94  // This only does something if HAVE_TEUCHOS_ARRAY_BOUNDSCHECK is defined.
95  setUpIterators(rcpNodeLookup);
96 #else
97  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
98 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
99 }
100 
101 
102 template<class T> inline
104  :ptr_(array.ptr_), size_(array.size_)
105 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
106  ,arcp_(array.arcp_)
107 #endif
108 {}
109 
110 template<class T> inline
112  :ptr_(array.ptr_), size_(array.size_)
113 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
114  ,arcp_(array.arcp_)
115 #endif
116 {}
117 
118 
119 template<class T> inline
121  std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
122  )
123  : ptr_( vec.empty() ? 0 : &vec[0] ), size_(vec.size())
124 {
125  setUpIterators();
126 }
127 
128 template<class T> inline
130  std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
131  )
132  : ptr_( vec.empty() ? 0 : &vec[0] ), size_(vec.size())
133 {
134  setUpIterators();
135 }
136 
137 
138 template<class T> inline
140  const std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
141  )
142  : ptr_( vec.empty() ? 0 : &vec[0] ), size_(vec.size())
143 {
144  setUpIterators();
145 }
146 
147 template<class T> inline
149  const std::vector<typename ConstTypeTraits<T>::NonConstType>& vec
150  )
151  : ptr_( vec.empty() ? 0 : &vec[0] ), size_(vec.size())
152 {
153  setUpIterators();
154 }
155 
156 
157 template<class T> inline
159 {
160  ptr_ = array.ptr_;
161  size_ = array.size_;
162 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
163  arcp_ = array.arcp_;
164 #endif
165  return *this;
166 }
167 
168 template<class T> inline
170 {
171  ptr_ = array.ptr_;
172  size_ = array.size_;
173 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
174  arcp_ = array.arcp_;
175 #endif
176  return *this;
177 }
178 
179 
180 template<class T> inline
182 {}
183 
184 template<class T> inline
186 {}
187 
188 
189 // General query functions
190 
191 
192 template<class T>
193 inline
195 {
196  return ptr_ == 0;
197 }
198 
199 template<class T>
200 inline
202 {
203  return ptr_ == 0;
204 }
205 
206 
207 template<class T> inline
209 {
210  debug_assert_valid_ptr();
211  return size_;
212 }
213 
214 template<class T> inline
216 {
218  return size_;
219 }
220 
221 
222 template<typename T>
223 std::string ArrayView<T>::toString() const
224 {
225  using Teuchos::as;
226  std::ostringstream ss;
227 
228  debug_assert_valid_ptr();
229 
230  ss << "{";
231  for (size_type i = 0; i < size (); ++i) {
232  // NOTE: This depends on std::ostream::operator<<(const T&).
233  ss << operator[] (i);
234  if (i + 1 < size ()) {
235  ss << ", ";
236  }
237  }
238  ss << "}";
239  return ss.str ();
240 }
241 
242 template<typename T>
243 std::string ArrayView<const T>::toString() const
244 {
245  using Teuchos::as;
246  std::ostringstream ss;
247 
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 
263 // Specialization for float. We use sufficient precision that no
264 // digits are lost after writing to string and reading back in again.
265 template<>
266 TEUCHOSCORE_LIB_DLL_EXPORT std::string
268 
269 // Specialization for (const) float. We use sufficient precision that no
270 // digits are lost after writing to string and reading back in again.
271 template<>
272 TEUCHOSCORE_LIB_DLL_EXPORT std::string
274 
275 // Specialization for double. We use sufficient precision that no
276 // digits are lost after writing to string and reading back in again.
277 template<>
278 TEUCHOSCORE_LIB_DLL_EXPORT std::string
280 
281 // Specialization for (const) double. We use sufficient precision that no
282 // digits are lost after writing to string and reading back in again.
283 template<>
284 TEUCHOSCORE_LIB_DLL_EXPORT std::string
286 
287 
288 // Element Access Functions
289 
290 
291 template<class T> inline
293 {
294  debug_assert_valid_ptr();
295  return ptr_;
296 }
297 
298 template<class T> inline
300 {
302  return ptr_;
303 }
304 
305 
306 template<class T> inline
308 {
309  debug_assert_valid_ptr();
310  debug_assert_in_range(i,1);
311  return ptr_[i];
312 }
313 
314 template<class T> inline
316 {
319  return ptr_[i];
320 }
321 
322 
323 template<class T> inline
325 {
326  debug_assert_not_null();
327  debug_assert_valid_ptr();
328  return *ptr_;
329 }
330 
331 template<class T> inline
333 {
336  return *ptr_;
337 }
338 
339 template<class T> inline
341 {
342  debug_assert_not_null();
343  debug_assert_valid_ptr();
344  return *(ptr_+size_-1);
345 }
346 
347 template<class T> inline
348 const T& ArrayView<const T>::back() const
349 {
352  return *(ptr_+size_-1);
353 }
354 
355 
356 // Views
357 
358 
359 template<class T> inline
361 {
362  if (size_in == 0) { return null; }
363  debug_assert_valid_ptr();
364  debug_assert_in_range(offset, size_in);
365  return ArrayView<T>(
366  ptr_+offset, size_in
367 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
368  ,arcp_.persistingView(offset, size_in)
369 #endif
370  );
371  // WARNING: The above code had better be correct since we are using raw
372  // pointer arithmetic!
373 }
374 
375 template<class T> inline
377 {
378  if (size_in == 0) { return null; }
380  debug_assert_in_range(offset, size_in);
381  return ArrayView<const T>(
382  ptr_+offset, size_in
383 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
384  ,arcp_.persistingView(offset, size_in)
385 #endif
386  );
387  // WARNING: The above code had better be correct since we are using raw
388  // pointer arithmetic!
389 }
390 
391 
392 template<class T> inline
394 {
395  return view(offset, size_in);
396 }
397 
398 template<class T> inline
400 {
401  return view(offset, size_in);
402 }
403 
404 
405 template<class T> inline
407 {
408  debug_assert_valid_ptr();
409  return *this;
410 }
411 
412 template<class T> inline
414 {
416  return *this;
417 }
418 
419 
420 template<class T> inline
422 {
423  debug_assert_valid_ptr();
424 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
425  return ArrayView<const T>(arcp_.getConst());
426 #else
427  return ArrayView<const T>(ptr_, size_);
428 #endif
429 }
430 
431 template<class T> inline
433  return *this;
434 }
435 
436 
437 template<class T> inline
439 {
440  return getConst();
441 }
442 
443 
444 // Assignment
445 
446 
447 template<class T>
448 void ArrayView<T>::assign(const ArrayView<const T>& array) const
449 {
450  debug_assert_valid_ptr();
451  debug_assert_not_null();
452  if (this->getRawPtr()==array.getRawPtr() && this->size()==array.size())
453  return; // Assignment to self
454  debug_assert_in_range(0,array.size());
455  std::copy( array.begin(), array.end(), this->begin() );
456  // Note: Above, in debug mode, the iterators are range checked! In
457  // optimized mode, these are raw pointers which should run very fast!
458 }
459 
460 
461 // Standard Container-Like Functions
462 
463 
464 template<class T>
466 {
467  debug_assert_valid_ptr();
468 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
469  return arcp_.create_weak();
470 #else
471  return ptr_;
472 #endif
473 }
474 
475 template<class T>
477 {
479 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
480  return arcp_.create_weak();
481 #else
482  return ptr_;
483 #endif
484 }
485 
486 
487 template<class T>
489 {
490  debug_assert_valid_ptr();
491 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
492  return arcp_.create_weak() + size_;
493 #else
494  return ptr_ + size_;
495 #endif
496 }
497 
498 template<class T>
500 {
502 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
503  return arcp_.create_weak() + size_;
504 #else
505  return ptr_ + size_;
506 #endif
507 }
508 
509 
510 // Assertion Functions.
511 
512 
513 template<class T>
515 {
516  if(!ptr_)
517  throw_null_ptr_error(typeName(*this));
518  return *this;
519 }
520 
521 template<class T>
523 {
524  if(!ptr_)
525  throw_null_ptr_error(typeName(*this));
526  return *this;
527 }
528 
529 
530 template<class T>
531 const ArrayView<T>&
533 {
534  assert_not_null();
535  TEUCHOS_TEST_FOR_EXCEPTION( size_in == as<size_type>(0), RangeError,
536  "Error, size=0 is not allowed!" );
538  !(
539  ( 0 <= offset && offset+size_in <= this->size() )
540  &&
541  size_in >= 0
542  ),
543  RangeError,
544  typeName(*this)<<"::assert_in_range():"
545  " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")"
546  " does not lie in the range [0,"<<this->size()<<")!"
547  );
548  return*this;
549 }
550 
551 template<class T>
552 const ArrayView<const T>&
554 {
555  assert_not_null();
556  TEUCHOS_TEST_FOR_EXCEPTION( size_in == as<size_type>(0), RangeError,
557  "Error, size=0 is not allowed!" );
559  !(
560  ( 0 <= offset && offset+size_in <= this->size() )
561  &&
562  size_in >= 0
563  ),
564  RangeError,
565  typeName(*this)<<"::assert_in_range():"
566  " Error, [offset,offset+size) = ["<<offset<<","<<(offset+size_in)<<")"
567  " does not lie in the range [0,"<<this->size()<<")!"
568  );
569  return*this;
570 }
571 
572 
573 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
574 
575 template<class T>
577  : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
578 {}
579 
580 template<class T>
581 ArrayView<const T>::ArrayView( const ArrayRCP<const T> &arcp )
582  : ptr_(arcp.getRawPtr()), size_(arcp.size()), arcp_(arcp)
583 {}
584 
585 
586 template<class T>
587 ArrayView<T>::ArrayView(T* p, size_type size_in, const ArrayRCP<T> &arcp)
588  : ptr_(p), size_(size_in), arcp_(arcp)
589 {}
590 
591 template<class T>
592 ArrayView<const T>::ArrayView(const T* p, size_type size_in, const ArrayRCP<const T> &arcp)
593  : ptr_(p), size_(size_in), arcp_(arcp)
594 {}
595 
596 
597 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
598 
599 
600 // private
601 
602 
603 template<class T>
605 {
606 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
607  if (ptr_ && arcp_.is_null()) {
608  arcp_ = ArrayRCP<T>(ptr_, 0, size_, false, rcpNodeLookup);
609  }
610 #else
611  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
612 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
613 }
614 
615 template<class T>
617 {
618 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
619  if (ptr_ && arcp_.is_null()) {
620  arcp_ = ArrayRCP<const T>(ptr_, 0, size_, false, rcpNodeLookup);
621  }
622 #else
623  (void) rcpNodeLookup; // Silence "unused variable" compiler warning.
624 #endif // HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
625 }
626 
627 
628 } // namespace Teuchos
629 
630 
631 //
632 // Nonmember helper functions
633 //
634 
635 
636 template<class T> inline
638 Teuchos::arrayView( T* p, typename ArrayView<T>::size_type size )
639 {
640  if (size == 0)
641  return null;
642  return ArrayView<T>(p, size);
643 }
644 
645 
646 template<class T> inline
647 Teuchos::ArrayView<T> Teuchos::arrayViewFromVector( std::vector<T>& vec )
648 {
649  if (vec.size() == 0)
650  return null;
651  return ArrayView<T>(vec);
652 }
653 
654 
655 template<class T> inline
656 Teuchos::ArrayView<const T> Teuchos::arrayViewFromVector( const std::vector<T>& vec )
657 {
658  if (vec.size() == 0)
659  return null;
660  return ArrayView<const T>(vec);
661 }
662 
663 
664 #ifndef __sun
665 
666 template<class T> inline
667 std::vector<T> Teuchos::createVector( const ArrayView<T> &av )
668 {
669  std::vector<T> v(av.begin(), av.end());
670  return v;
671 }
672 
673 #endif // __sun
674 
675 
676 template<class T> inline
677 std::vector<T> Teuchos::createVector( const ArrayView<const T> &av )
678 {
679  std::vector<T> v(av.begin(), av.end());
680  return v;
681 }
682 
683 
684 template<class T> inline
685 bool Teuchos::is_null( const ArrayView<T> &av )
686 {
687  return av.is_null();
688 }
689 
690 
691 template<class T> inline
692 bool Teuchos::nonnull( const ArrayView<T> &av )
693 {
694  return !av.is_null();
695 }
696 
697 
698 template<class T>
699 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayView<T>& p )
700 {
701  return out << p.toString();
702 }
703 
704 
705 template<class T2, class T1>
708 Teuchos::av_const_cast(const ArrayView<T1>& p1)
709 {
710  T2 *ptr2 = const_cast<T2*>(p1.getRawPtr());
711  return ArrayView<T2>(ptr2, p1.size());
712  // Note: Above is just fine even if p1.get()==NULL!
713 }
714 
715 
716 template<class T2, class T1>
719 Teuchos::av_reinterpret_cast(const ArrayView<T1>& p1)
720 {
721  typedef typename ArrayView<T1>::size_type size_type;
722  const int sizeOfT1 = sizeof(T1);
723  const int sizeOfT2 = sizeof(T2);
724  size_type size2 = (p1.size()*sizeOfT1) / sizeOfT2;
725  T2 *ptr2 = reinterpret_cast<T2*>(p1.getRawPtr());
726  return ArrayView<T2>(
727  ptr2, size2
728 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
729  ,arcp_reinterpret_cast<T2>(p1.access_private_arcp())
730 #endif
731  );
732  // Note: Above is just fine even if p1.get()==NULL!
733 }
734 
735 
736 #endif // TEUCHOS_ARRAY_VIEW_HPP
void debug_assert_in_range(size_type offset, size_type size_in) const
void assign(const ArrayView< const T > &array) const
Copy the data from one array view object to this array view object.
void setUpIterators(const ERCPNodeLookup rcpNodeLookup=RCP_ENABLE_NODE_LOOKUP)
T & operator[](size_type i) const
Random object access.
const ArrayView< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
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.
Partial specialization of ArrayRCP for const T.
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)
const T & getConst(T &t)
Return a constant reference to an object given a non-const reference.
size_type size() const
The total number of items in the managed array.
#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 & front() const
Get the first element.
T & back() const
Get the last element.
ArrayRCP< T2 > arcp_reinterpret_cast(const ArrayRCP< T1 > &p1)
Reinterpret cast of underlying ArrayRCP type from T1* to T2*.
iterator begin() const
Return an iterator to beginning of the array of data.
ArrayView< const T > getConst() const
Return a const view of a possibly nonconst view.
std::string toString() const
Convert an ArrayView<T> to an std::string
#define TEUCHOSCORE_LIB_DLL_EXPORT
bool is_null() const
Returns true if the underlying pointer is null.
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
Nonowning array view.
T * getRawPtr() const
Return a raw pointer to beginning of array or NULL if unsized.
ArrayView(ENull null_arg=null)
Constructor that initializes to NULL (implicitly or explicitly).
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 ...
Partial specialization of ArrayView for const T.
Range error exception class.
iterator end() const
Return an iterator to past the end of the array of data.
ArrayView< T > & operator=(const ArrayView< T > &array)
Shallow copy assignment operator.
ArrayView< T > view(size_type offset, size_type size) const
Return a view of a contiguous range of elements.
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...
const ArrayView< T > & operator()() const
Return *this (just for compatibility with Array and ArrayPtr).
Reference-counted smart pointer for managing arrays.