IODA Bundle
StridedData.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2019- ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 
12 /// @author Simon Smart
13 /// @date January 2019
14 
15 #ifndef odc_api_StridedData_H
16 #define odc_api_StridedData_H
17 
18 #include <cstddef>
19 #include <string.h>
20 #include <algorithm>
21 
22 #include "eckit/exception/Exceptions.h"
23 
24 
25 namespace odc {
26 namespace api {
27 
28 //----------------------------------------------------------------------------------------------------------------------
29 
30 template <typename value_type>
31 class StridedDataT {
32 
33 public: // types
34 
36 
39 
40 private: // types
41 
42  using void_arg_t = typename std::conditional<std::is_const<value_type>::value, const void*, void*>::type;
43 
44 public: // methods
45 
46  // Construction and copy
47 
48  StridedDataT(void_arg_t data, size_t nelem, size_t dataSize, size_t stride) :
49  data_(reinterpret_cast<value_type*>(data)), nelem_(nelem), dataSize_(dataSize), stride_(stride) {
50  }
51  StridedDataT() : StridedDataT(0, 0, 0, 0) {}
52 
54 
55  StridedDataT(const StridedDataT<value_type>& rhs) = default;
57 
58  // Slice the StridedData to get a sub-strided-data
59 
60  StridedDataT<value_type> slice(size_t rowOffset, size_t nrows) {
61  ASSERT(rowOffset + nrows <= nelem_);
62  return StridedDataT<value_type>(get(rowOffset), nrows, dataSize_, stride_);
63  }
64 
65  StridedDataT<value_type> slice(size_t rowOffset, size_t nrows) const {
66  ASSERT(rowOffset + nrows <= nelem_);
67  return StridedDataT<const_value_type>(get(rowOffset), nrows, dataSize_, stride_);
68  }
69 
70  // Accessing the data
71 
72  size_t nelem() const { return nelem_; }
73  size_t dataSize() const { return dataSize_; }
74  size_t stride() const { return stride_; }
75 
76  value_type* get(int i) {
77  return &data_[i*stride_];
78  }
79  const_value_type* get(int i) const {
80  return &data_[i*stride_];
81  }
82 
83  value_type* operator[](int i) { return get(i); }
84  const_value_type* operator[](int i) const { return get(i); }
85 
86  value_type* operator*() { return data_; }
87  const_value_type* operator*() const { return data_; }
88 
89  void fill(int sourceRow, int finalRow);
90 
91  bool isNewValue(size_t row) const {
92  if (row == 0) return true;
93  return ::memcmp(get(row), get(row-1), dataSize_) != 0;
94  }
95 
96  // Iteration functionality
97 
98  iterator begin() { return *this; }
100 
103 
105  data_ += stride_;
106  --nelem_;
107  return *this;
108  }
109 
111  auto ret = *this;
112  ++(*this);
113  return ret;
114  }
115 
116  bool operator==(const StridedDataT<value_type>& rhs) const {
117  return (data_ == rhs.data_ &&
118  nelem_ == rhs.nelem_ &&
119  dataSize_ == rhs.dataSize_ &&
120  stride_ == rhs.stride_);
121  }
122  bool operator!=(const StridedDataT<value_type>& rhs) const {
123  return !(*this == rhs);
124  }
125 
126 private: // methods
127 
128  friend std::ostream& operator<<(std::ostream& o, const StridedDataT<value_type>& s) {
129  o << "StridedData(0x" << (void*)s.data_ << "-" << s.dataSize_ << ":" << s.stride_ << "x" << s.nelem_ << ")";
130  return o;
131  }
132 
133 private: // members
134 
135  value_type* data_;
136 
137  size_t nelem_;
138  size_t dataSize_;
139  size_t stride_;
140 };
141 
142 //----------------------------------------------------------------------------------------------------------------------
143 
144 template <typename value_type>
145 inline void StridedDataT<value_type>::fill(int sourceRow, int finalRow) {
146 
147  ASSERT(sourceRow < finalRow);
148 
149  // Specialisations for speed
150 
151  if (dataSize_ == 8) {
152  if (stride_ == 8) {
153  std::fill(reinterpret_cast<uint64_t*>(get(sourceRow+1)),
154  reinterpret_cast<uint64_t*>(get(finalRow+1)),
155  *reinterpret_cast<uint64_t*>(get(sourceRow)));
156  } else {
157  uint64_t src = *reinterpret_cast<uint64_t*>(get(sourceRow));
158  uint64_t* end = reinterpret_cast<uint64_t*>(get(finalRow));
159  for (uint64_t* p = reinterpret_cast<uint64_t*>(get(sourceRow+1));
160  p <= end;
161  p = reinterpret_cast<uint64_t*>(reinterpret_cast<char*>(p) + stride_)) {
162  *p = src;
163  }
164  }
165  } else {
166  char* src = get(sourceRow);
167  for (int row = sourceRow + 1; row <= finalRow; ++row) {
168  ::memcpy(get(row), src, dataSize_);
169  }
170  }
171 }
172 
175 
176 //----------------------------------------------------------------------------------------------------------------------
177 
178 } // namespace api
179 } // namespace odc
180 
181 #endif // odc_api_StridedData_H
value_type * get(int i)
Definition: StridedData.h:76
value_type * operator[](int i)
Definition: StridedData.h:83
void fill(int sourceRow, int finalRow)
Definition: StridedData.h:145
size_t nelem() const
Definition: StridedData.h:72
value_type * operator*()
Definition: StridedData.h:86
friend std::ostream & operator<<(std::ostream &o, const StridedDataT< value_type > &s)
Definition: StridedData.h:128
StridedDataT< value_type > & operator=(const StridedDataT< value_type > &rhs)=default
bool isNewValue(size_t row) const
Definition: StridedData.h:91
StridedDataT(const StridedDataT< value_type > &rhs)=default
typename std::conditional< std::is_const< value_type >::value, const void *, void * >::type void_arg_t
Definition: StridedData.h:42
size_t stride() const
Definition: StridedData.h:74
StridedDataT< value_type > & operator++()
Definition: StridedData.h:104
const_iterator begin() const
Definition: StridedData.h:101
const_iterator end() const
Definition: StridedData.h:102
const_value_type * get(int i) const
Definition: StridedData.h:79
StridedDataT< value_type > slice(size_t rowOffset, size_t nrows) const
Definition: StridedData.h:65
StridedDataT< value_type > slice(size_t rowOffset, size_t nrows)
Definition: StridedData.h:60
StridedDataT< value_type > operator++(int)
Definition: StridedData.h:110
bool operator!=(const StridedDataT< value_type > &rhs) const
Definition: StridedData.h:122
size_t dataSize() const
Definition: StridedData.h:73
bool operator==(const StridedDataT< value_type > &rhs) const
Definition: StridedData.h:116
StridedDataT(void_arg_t data, size_t nelem, size_t dataSize, size_t stride)
Definition: StridedData.h:48
typename std::add_const< value_type >::type const_value_type
Definition: StridedData.h:35
const_value_type * operator*() const
Definition: StridedData.h:87
const_value_type * operator[](int i) const
Definition: StridedData.h:84
Definition: ColumnInfo.h:23