-
Notifications
You must be signed in to change notification settings - Fork 1
/
Ch14_CheckedPtr.cpp
130 lines (113 loc) · 3.24 KB
/
Ch14_CheckedPtr.cpp
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
// C++ Primer 4th Edition Chapter 14 Section 14.7
#include "Ch14_CheckedPtr.h"
#include <iostream>
using std::cerr;
#include <stdexcept>
using std::out_of_range;
using std::logic_error;
// dereference operator
int& CheckedPtr::operator*()
{
if (curr == end)
throw out_of_range("dereference past the end");
return *curr;
}
const int& CheckedPtr::operator*() const
{
if (curr == end)
throw out_of_range("dereference past the end");
return *curr;
}
// subscript operator
int& CheckedPtr::operator[]( const size_t index )
{
if( (index+beg)<beg || (index+beg)>=end ){
throw out_of_range("subscript wrong range");
}
return *(beg+index);
}
const int& CheckedPtr::operator[]( const size_t index ) const
{
if( (index+beg)<beg || (index+beg)>=end ){
throw out_of_range("subscript wrong range");
}
return *(beg+index);
}
// postfix: increment/decrement object but return unchanged value
CheckedPtr CheckedPtr::operator++(int)
{
// no check needed here, the call to prefix increment will do the check
CheckedPtr ret(*this); // save current value
++*this; // advance one element, checking the increment
return ret; // return saved state
}
CheckedPtr CheckedPtr::operator--(int)
{
// no check needed here, the call to prefix decrement will do the check
CheckedPtr ret(*this); // save current value
--*this; // move backward one element and check
return ret; // return saved state
}
// prefix: return reference to incremented/decremented object
CheckedPtr& CheckedPtr::operator++()
{
if (curr == end)
throw out_of_range
("increment past the end of CheckedPtr");
++curr; // advance current state
return *this;
}
CheckedPtr& CheckedPtr::operator--()
{
if (curr == beg)
throw out_of_range
("decrement past the beginning of CheckedPtr");
--curr; // move current state back one element
return *this;
}
//
inline bool operator==( const CheckedPtr& lhs, const CheckedPtr& rhs )
{
return lhs.beg==rhs.beg && lhs.end==rhs.end && lhs.curr==rhs.curr;
}
inline bool operator!=( const CheckedPtr& lhs, const CheckedPtr& rhs )
{
return !( lhs==rhs );
}
inline bool operator>( const CheckedPtr& lhs, const CheckedPtr& rhs )
{
return lhs.beg==rhs.beg && lhs.end==rhs.end && lhs.curr>rhs.curr;
}
inline bool operator<( const CheckedPtr& lhs, const CheckedPtr& rhs )
{
return rhs>lhs;
}
inline bool operator>=( const CheckedPtr& lhs, const CheckedPtr& rhs )
{
return !( lhs<rhs );
}
inline bool operator<=( const CheckedPtr& lhs, const CheckedPtr& rhs )
{
return !( lhs>rhs );
}
//
CheckedPtr operator+( const CheckedPtr& lhs, const ptrdiff_t index )
{
if( lhs.curr+index >= lhs.end || lhs.curr+index < lhs.beg ){
throw out_of_range("pointer out of range!");
}
CheckedPtr ret(lhs);
ret.curr += index;
return ret;
}
CheckedPtr operator-( const CheckedPtr& lhs, const ptrdiff_t index )
{
return lhs+(-index);
}
ptrdiff_t operator-( const CheckedPtr& lhs, const CheckedPtr& rhs )
{
if( lhs.beg!=rhs.beg || lhs.end!= rhs.end ){
throw logic_error("Different pointers!");
}
return lhs.curr - rhs.curr;
}