forked from huangmingchuan/Cpp_Primer_Answers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblobptr.h
114 lines (89 loc) · 2.06 KB
/
blobptr.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
#ifndef BLOBPTR_H
#define BLOBPTR_H
#include "Blob.h"
#include <memory>
#include <vector>
template <typename> class BlobPtr;
template <typename T>
bool operator ==(const BlobPtr<T>& lhs, const BlobPtr<T>& rhs);
template <typename T>
bool operator < (const BlobPtr<T>& lhs, const BlobPtr<T>& rhs);
template<typename T> class BlobPtr
{
friend bool operator ==<T>
(const BlobPtr<T>& lhs, const BlobPtr<T>& rhs);
friend bool operator < <T>
(const BlobPtr<T>& lhs, const BlobPtr<T>& rhs);
public:
BlobPtr() : curr(0) {}
BlobPtr(Blob<T>& a, std::size_t sz = 0) :
wptr(a.data), curr(sz)
{}
T& operator*() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
// prefix
BlobPtr& operator++();
BlobPtr& operator--();
// postfix
BlobPtr operator ++(int);
BlobPtr operator --(int);
private:
// returns a shared_ptr to the vector if the check succeeds
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;
};
// prefix ++
template<typename T>
BlobPtr<T>& BlobPtr<T>::operator ++()
{
// if curr already points past the end of the container, can't increment it
check(curr, "increment past end of StrBlob");
++curr;
return *this;
}
// prefix --
template<typename T>
BlobPtr<T>& BlobPtr<T>::operator --()
{
--curr;
check(curr, "decrement past begin of BlobPtr");
return *this;
}
// postfix ++
template<typename T>
BlobPtr<T> BlobPtr<T>::operator ++(int)
{
BlobPtr ret = *this;
++*this;
return ret;
}
// postfix --
template<typename T>
BlobPtr<T> BlobPtr<T>::operator --(int)
{
BlobPtr ret = *this;
--*this;
return ret;
}
template<typename T> bool operator==(const BlobPtr<T> &lhs, const BlobPtr<T> &rhs)
{
if (lhs.wptr.lock() != rhs.wptr.lock())
{
throw runtime_error("ptrs to different Blobs!");
}
return lhs.i == rhs.i;
}
template<typename T> bool operator< (const BlobPtr<T> &lhs, const BlobPtr<T> &rhs)
{
if (lhs.wptr.lock() != rhs.wptr.lock())
{
throw runtime_error("ptrs to different Blobs!");
}
return lhs.i < rhs.i;
}
#endif // BLOBPTR_H