HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
strided_ptr.h
Go to the documentation of this file.
1 // Copyright 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio
4 
5 
6 #pragma once
7 
8 #include <cstddef>
9 
11 #include <OpenImageIO/platform.h>
12 
13 
15 
16 
17 /// strided_ptr<T> looks like a 'T*', but it incorporates a stride, so
18 /// it's not limited to adjacent elements.
19 /// Operators ++, --, [], and so on, take the stride into account when
20 /// computing where each "array element" actually exists.
21 ///
22 /// A strided_ptr<T> is mutable (the values pointed to may be modified),
23 /// whereas an strided_ptr<const T> is not mutable.
24 ///
25 /// Fun trick: strided_ptr<T>(&my_value,0) makes a strided_pointer that
26 /// is addressed like an array, but because the stride is 0, every
27 /// accessed "element" actually will actually refer to the same value.
28 ///
29 /// By default, if StrideUnits == sizeof(T), then the stride refers to
30 /// multiples of the size of T. But every once in a while, you need a
31 /// a byte-addressable stride, and in that case you use a StrideUnits
32 /// of 1, like: strided_ptr<T,1>.
33 template<typename T, int StrideUnits = sizeof(T)> class strided_ptr {
34 public:
35  constexpr strided_ptr(T* ptr = nullptr, ptrdiff_t stride = 1) noexcept
36  : m_ptr(ptr)
37  , m_stride(stride)
38  {
39  }
40  constexpr strided_ptr(const strided_ptr& p) noexcept
41  : strided_ptr(p.data(), p.stride())
42  {
43  }
44 
45  const strided_ptr& operator=(const strided_ptr& p) noexcept
46  {
47  m_ptr = p.m_ptr;
48  m_stride = p.m_stride;
49  return *this;
50  }
51 
52  // Assignment of a pointer sets the pointer and implies a stride of 1.
53  const strided_ptr& operator=(T* p) noexcept
54  {
55  m_ptr = p;
56  m_stride = 1;
57  return *this;
58  }
59 
60  constexpr T& operator*() const { return *m_ptr; }
61  constexpr T& operator[](ptrdiff_t pos) const { return get(pos); }
62  constexpr T* data() const { return m_ptr; }
63  constexpr ptrdiff_t stride() const { return m_stride; }
64 
65  // Careful: == and != only compare the pointer
66  constexpr bool operator==(const T* p) const { return m_ptr == p; }
67  constexpr bool operator!=(const T* p) const { return m_ptr != p; }
68 
69  // Increment and decrement moves the pointer to the next element
70  // one stride length away.
72  { // prefix
73  m_ptr = getptr(1);
74  return *this;
75  }
77  { // postfix
78  strided_ptr r(*this);
79  ++(*this);
80  return r;
81  }
83  { // prefix
84  m_ptr = getptr(-1);
85  return *this;
86  }
88  { // postfix
89  strided_ptr r(*this);
90  --(*this);
91  return r;
92  }
93 
94  // Addition and subtraction returns new strided pointers that are
95  // the given number of strides away.
96  constexpr strided_ptr operator+(ptrdiff_t d) const noexcept
97  {
98  return strided_ptr(getptr(d), m_stride);
99  }
100  constexpr strided_ptr operator-(ptrdiff_t d) const noexcept
101  {
102  return strided_ptr(getptr(-d), m_stride);
103  }
104  const strided_ptr& operator+=(ptrdiff_t d) noexcept
105  {
106  m_ptr = getptr(d);
107  return *this;
108  }
109  const strided_ptr& operator-=(ptrdiff_t d)
110  {
111  m_ptr = getptr(-d);
112  return *this;
113  }
114 
115 private:
116  // The implementation of a strided_ptr is just the pointer and a stride.
117  // Note that when computing addressing, the stride is implicitly
118  // multiplied by the StrideUnits, which defaults to sizeof(T), but when
119  // StrideUnits==1 means that your stride value is measured in bytes.
120  T* m_ptr = nullptr;
121  ptrdiff_t m_stride = 1;
122 
123  // getptr is the real brains of the operation, computing the pointer
124  // for a given element, with strides taken into consideration.
125  constexpr inline T* getptr(ptrdiff_t pos = 0) const noexcept
126  {
127  return (T*)((char*)m_ptr + pos * m_stride * StrideUnits);
128  }
129  constexpr inline T& get(ptrdiff_t pos = 0) const noexcept
130  {
131  return *getptr(pos);
132  }
133 };
134 
135 
136 
constexpr strided_ptr operator-(ptrdiff_t d) const noexcept
Definition: strided_ptr.h:100
constexpr T * data() const
Definition: strided_ptr.h:62
const strided_ptr & operator=(T *p) noexcept
Definition: strided_ptr.h:53
constexpr T & operator*() const
Definition: strided_ptr.h:60
constexpr T & operator[](ptrdiff_t pos) const
Definition: strided_ptr.h:61
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
constexpr bool operator==(const T *p) const
Definition: strided_ptr.h:66
constexpr strided_ptr(T *ptr=nullptr, ptrdiff_t stride=1) noexcept
Definition: strided_ptr.h:35
const strided_ptr & operator--()
Definition: strided_ptr.h:82
const strided_ptr & operator=(const strided_ptr &p) noexcept
Definition: strided_ptr.h:45
const strided_ptr & operator+=(ptrdiff_t d) noexcept
Definition: strided_ptr.h:104
const strided_ptr operator--(int)
Definition: strided_ptr.h:87
const strided_ptr & operator++()
Definition: strided_ptr.h:71
auto ptr(T p) -> const void *
Definition: format.h:2448
constexpr strided_ptr(const strided_ptr &p) noexcept
Definition: strided_ptr.h:40
const strided_ptr & operator-=(ptrdiff_t d)
Definition: strided_ptr.h:109
constexpr bool operator!=(const T *p) const
Definition: strided_ptr.h:67
const strided_ptr operator++(int)
Definition: strided_ptr.h:76
GLboolean r
Definition: glcorearb.h:1222
#define const
Definition: zconf.h:214
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:94
constexpr strided_ptr operator+(ptrdiff_t d) const noexcept
Definition: strided_ptr.h:96
constexpr ptrdiff_t stride() const
Definition: strided_ptr.h:63
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:93