-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConstBlobPtr.h
162 lines (148 loc) · 4.49 KB
/
ConstBlobPtr.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#ifndef CONSTBLOBPTR_H
#define CONSTBLOBPTR_H
#include <vector>
#include <string>
#include <memory>
#include <cstddef>
#include <stdexcept>
template <typename T> class Blob;
template <typename T> class ConstBlobPtr;
template <typename T> bool operator==(const ConstBlobPtr<T> &, const ConstBlobPtr<T> &);
template <typename T> bool operator<(const ConstBlobPtr<T> &, const ConstBlobPtr<T> &);
template <typename T> std::ptrdiff_t operator-(const ConstBlobPtr<T> &, const ConstBlobPtr<T> &);
template <typename T>
class ConstBlobPtr {
friend bool operator==<T>(const ConstBlobPtr<T> &, const ConstBlobPtr<T> &);
friend bool operator< <T>(const ConstBlobPtr<T> &, const ConstBlobPtr<T> &);
friend std::ptrdiff_t operator-<T>(const ConstBlobPtr<T> &, const ConstBlobPtr<T> &);
public:
ConstBlobPtr();
ConstBlobPtr(const Blob<T> &, std::size_t = 0);
const T &operator*() const;
ConstBlobPtr &operator+=(std::size_t);
ConstBlobPtr &operator-=(std::size_t);
ConstBlobPtr &operator++(); // prefix
ConstBlobPtr &operator--();
ConstBlobPtr operator++(int); // postfix
ConstBlobPtr operator--(int);
private:
std::shared_ptr<std::vector<T>> check(std::size_t, const std::string &) const;
std::weak_ptr<std::vector<T>> wptr;
std::size_t curr;
};
template <typename T>
ConstBlobPtr<T>::ConstBlobPtr() : curr(0) {}
template <typename T>
ConstBlobPtr<T>::ConstBlobPtr(const Blob<T> &a, std::size_t sz) : wptr(a.data), curr(sz) {}
// Dereference
template <typename T>
const T &ConstBlobPtr<T>::operator*() const {
std::shared_ptr<std::vector<T>> p = check(curr, "dereference past end");
return (*p)[curr];
}
// Compound addition assignment
template <typename T>
ConstBlobPtr<T> &ConstBlobPtr<T>::operator+=(std::size_t n) {
curr += n;
check(curr - 1, "increment past end of ConstBlobPtr");
return *this;
}
// Compound subtraction assignment
template <typename T>
ConstBlobPtr<T> &ConstBlobPtr<T>::operator-=(std::size_t n) {
curr -= n;
check(curr, "decrement past beginning of ConstBlobPtr");
return *this;
}
// Prefix increment
template <typename T>
ConstBlobPtr<T> &ConstBlobPtr<T>::operator++() {
check(curr, "increment past end of ConstBlobPtr");
++curr;
return *this;
}
// Prefix decrement
template <typename T>
ConstBlobPtr<T> &ConstBlobPtr<T>::operator--() {
check(--curr, "decrement past beginning of ConstBlobPtr");
return *this;
}
// Postfix increment
template <typename T>
ConstBlobPtr<T> ConstBlobPtr<T>::operator++(int) {
ConstBlobPtr old = *this;
++*this;
return old;
}
// Postfix decrement
template <typename T>
ConstBlobPtr<T> ConstBlobPtr<T>::operator--(int) {
ConstBlobPtr old = *this;
--*this;
return old;
}
template <typename T>
std::shared_ptr<std::vector<T>>
ConstBlobPtr<T>::check(std::size_t i, const std::string &msg) const {
std::shared_ptr<std::vector<T>> ret = wptr.lock();
if (!ret)
throw std::runtime_error("unbound ConstBlobPtr");
if (i >= ret->size())
throw std::out_of_range(msg);
return ret;
}
// Equality
template <typename T>
bool operator==(const ConstBlobPtr<T> &lhs, const ConstBlobPtr<T> &rhs) {
return (lhs.wptr.lock() == rhs.wptr.lock())
&& (lhs.curr == rhs.curr);
}
// Inequality
template <typename T>
bool operator!=(const ConstBlobPtr<T> &lhs, const ConstBlobPtr<T> &rhs) {
return !(lhs == rhs);
}
// Less-than
template <typename T>
bool operator<(const ConstBlobPtr<T> &lhs, const ConstBlobPtr<T> &rhs) {
if (lhs.wptr.lock() != rhs.wptr.lock())
throw std::runtime_error("comparing two ConstBlobPtrs that don't point to the same object");
return lhs.curr < rhs.curr;
}
// Greater-than
template <typename T>
bool operator>(const ConstBlobPtr<T> &lhs, const ConstBlobPtr<T> &rhs) {
return rhs < lhs;
}
// Less-than or equal
template <typename T>
bool operator<=(const ConstBlobPtr<T> &lhs, const ConstBlobPtr<T> &rhs) {
return !(lhs > rhs);
}
// Greater-than or equal
template <typename T>
bool operator>=(const ConstBlobPtr<T> &lhs, const ConstBlobPtr<T> &rhs) {
return !(lhs < rhs);
}
// Addition
template <typename T>
ConstBlobPtr<T> operator+(const ConstBlobPtr<T> &p, const std::size_t n) {
ConstBlobPtr<T> ret = p;
ret += n;
return ret;
}
// Subtraction
template <typename T>
ConstBlobPtr<T> operator-(const ConstBlobPtr<T> &p, const std::size_t n) {
ConstBlobPtr<T> ret = p;
ret -= n;
return ret;
}
// Subtraction
template <typename T>
std::ptrdiff_t operator-(const ConstBlobPtr<T> &lhs, const ConstBlobPtr<T> &rhs) {
if (lhs.wptr.lock() != rhs.wptr.lock())
throw std::runtime_error("the two ConstBlobPtrs don't point to the same object");
return lhs.curr - rhs.curr;
}
#endif