1 /*
  2  *   Copyright (c) 2007, Michael Lehn
  3  *
  4  *   All rights reserved.
  5  *
  6  *   Redistribution and use in source and binary forms, with or without
  7  *   modification, are permitted provided that the following conditions
  8  *   are met:
  9  *
 10  *   1) Redistributions of source code must retain the above copyright
 11  *      notice, this list of conditions and the following disclaimer.
 12  *   2) Redistributions in binary form must reproduce the above copyright
 13  *      notice, this list of conditions and the following disclaimer in
 14  *      the documentation and/or other materials provided with the
 15  *      distribution.
 16  *   3) Neither the name of the FLENS development group nor the names of
 17  *      its contributors may be used to endorse or promote products derived
 18  *      from this software without specific prior written permission.
 19  *
 20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 31  */
 32 
 33 #ifndef FLENS_STORAGE_ARRAY_CONSTARRAYVIEW_TCC
 34 #define FLENS_STORAGE_ARRAY_CONSTARRAYVIEW_TCC 1
 35 
 36 #include <cassert>
 37 #include <flens/storage/array/array.h>
 38 #include <flens/storage/array/arrayview.h>
 39 
 40 
 41 namespace flens {
 42 
 43 template <typename T, typename I, typename A>
 44 ConstArrayView<T, I, A>::ConstArrayView(IndexType length,
 45                                         const ElementType *data,
 46                                         IndexType stride,
 47                                         IndexType firstIndex,
 48                                         const Allocator &allocator)
 49     : _data(data-firstIndex),
 50       _allocator(allocator),
 51       _length(length),
 52       _stride(stride),
 53       _firstIndex(firstIndex)
 54 {
 55     ASSERT(_length>=0);
 56 }
 57 
 58 template <typename T, typename I, typename A>
 59 ConstArrayView<T, I, A>::ConstArrayView(const ConstArrayView &rhs)
 60     : _data(rhs._data),
 61       _allocator(rhs.allocator()),
 62       _length(rhs._length),
 63       _stride(rhs._stride),
 64       _firstIndex(rhs._firstIndex)
 65 {
 66 }
 67 
 68 template <typename T, typename I, typename A>
 69 template <typename RHS>
 70 ConstArrayView<T, I, A>::ConstArrayView(const RHS &rhs)
 71     : _data(rhs.data()-rhs.firstIndex()),
 72       _allocator(rhs.allocator()),
 73       _length(rhs.length()),
 74       _stride(rhs.stride()),
 75       _firstIndex(rhs.firstIndex())
 76 {
 77 }
 78 
 79 template <typename T, typename I, typename A>
 80 ConstArrayView<T, I, A>::~ConstArrayView()
 81 {
 82 }
 83 
 84 //-- operators -----------------------------------------------------------------
 85 
 86 template <typename T, typename I, typename A>
 87 const typename ConstArrayView<T, I, A>::ElementType &
 88 ConstArrayView<T, I, A>::operator()(IndexType index) const
 89 {
 90     ASSERT(index>=firstIndex());
 91     ASSERT(index<=lastIndex());
 92     return _data[_firstIndex + _stride*(index-_firstIndex)];
 93 }
 94 
 95 //-- methods -------------------------------------------------------------------
 96 
 97 template <typename T, typename I, typename A>
 98 typename ConstArrayView<T, I, A>::IndexType
 99 ConstArrayView<T, I, A>::firstIndex() const
100 {
101     return _firstIndex;
102 }
103 
104 template <typename T, typename I, typename A>
105 typename ConstArrayView<T, I, A>::IndexType
106 ConstArrayView<T, I, A>::lastIndex() const
107 {
108     return _firstIndex+_length-1;
109 }
110 
111 template <typename T, typename I, typename A>
112 typename ConstArrayView<T, I, A>::IndexType
113 ConstArrayView<T, I, A>::length() const
114 {
115     return _length;
116 }
117 
118 template <typename T, typename I, typename A>
119 typename ConstArrayView<T, I, A>::IndexType
120 ConstArrayView<T, I, A>::stride() const
121 {
122     return _stride;
123 }
124 
125 template <typename T, typename I, typename A>
126 const typename ConstArrayView<T, I, A>::ElementType *
127 ConstArrayView<T, I, A>::data() const
128 {
129     return &_data[_firstIndex];
130 }
131 
132 template <typename T, typename I, typename A>
133 const typename ConstArrayView<T, I, A>::Allocator &
134 ConstArrayView<T, I, A>::allocator() const
135 {
136     return _allocator;
137 }
138 
139 template <typename T, typename I, typename A>
140 const ConstArrayView<T, I, A>
141 ConstArrayView<T, I, A>::view(IndexType from, IndexType to,
142                               IndexType stride, IndexType firstViewIndex) const
143 {
144     const IndexType length = (to-from)/stride+1;
145 
146 #   ifndef NDEBUG
147     // prevent an out-of-bound assertion in case a view is empty anyway
148     if (length==0) {
149         return ConstArrayView<T, I, A>(length,              // length
150                                        0,                   // data
151                                        stride*_stride,      // stride
152                                        firstViewIndex,      // firstIndex in view
153                                        allocator());        // allocator
154     }
155 #   endif
156 
157     ASSERT(firstIndex()<=from);
158     ASSERT(lastIndex()>=to);
159     ASSERT(from<=to);
160     ASSERT(stride>=1);
161     return ConstArrayView<T, I, A>(length,              // length
162                                    &operator()(from),   // data
163                                    stride*_stride,      // stride
164                                    firstViewIndex,      // firstIndex in view
165                                    allocator());        // allocator
166 }
167 
168 // namespace flens
169 
170 #endif // FLENS_STORAGE_ARRAY_CONSTARRAYVIEW_TCC