-
Notifications
You must be signed in to change notification settings - Fork 0
/
ObjRefCount.cpp
142 lines (103 loc) · 3.35 KB
/
ObjRefCount.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
131
132
133
134
135
136
#include <iostream>
#include <assert.h>
#ifndef nullptr
#define nullptr 0
#endif
#include "ObjRefCount.h"
////////////////////////////////////////////////////////////////////////////////
ObjRefCount::Data::Data( )
: m_count(1)
{
}
////////////////////////////////////////////////////////////////////////////////
ObjRefCount::Data::Data(const Data& d)
: m_count(1)
{
}
////////////////////////////////////////////////////////////////////////////////
bool ObjRefCount::Data::operator==(const ObjRefCount::Data& other)const
{
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool ObjRefCount::Data::operator<(const ObjRefCount::Data& other)const
{
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool ObjRefCount::Data::operator>(const ObjRefCount::Data& other)const
{
return true;
}
////////////////////////////////////////////////////////////////////////////////
ObjRefCount::ObjRefCount( )
: m_data(defaultData())
{
}
////////////////////////////////////////////////////////////////////////////////
ObjRefCount::ObjRefCount(const ObjRefCount& other)
: m_data(other.m_data)
{
++m_data->m_count;
}
////////////////////////////////////////////////////////////////////////////////
ObjRefCount::~ObjRefCount( )
{
if (--m_data->m_count == 0) delete m_data;
}
////////////////////////////////////////////////////////////////////////////////
ObjRefCount::Data* ObjRefCount::defaultData( )
{
static ObjRefCount::Data* p = nullptr;
if (p == nullptr)
{
p = new Data( );
++p->m_count; // Make sure it never goes to zero
}
return p;
}
////////////////////////////////////////////////////////////////////////////////
void ObjRefCount::createNewDataIfNeeded( )
{
// This method might need to change things in *m_data
// Thus it first checks if this is the only pointer to *m_data
if (m_data->m_count > 1)
{
Data* d = new Data(*m_data); // Invoke Fred::Data's copy ctor
--m_data->m_count;
m_data = d;
}
assert(m_data->m_count == 1);
}
////////////////////////////////////////////////////////////////////////////////
ObjRefCount& ObjRefCount::operator=(const ObjRefCount& f)
{
// DO NOT CHANGE THE ORDER OF THESE STATEMENTS!
// (This order properly handles self-assignment)
// (This order also properly handles recursion, e.g., if a
// Fred::Data contains Freds)
Data* const old(m_data);
m_data = f.m_data;
++m_data->m_count;
if (--old->m_count == 0)
{
delete old;
}
return *this;
}
////////////////////////////////////////////////////////////////////////////////
bool ObjRefCount::operator==(const ObjRefCount& other)const
{
return m_data&&other.m_data ? m_data->operator==(*other.m_data) : false;
}
////////////////////////////////////////////////////////////////////////////////
bool ObjRefCount::operator>(const ObjRefCount& other)const
{
return m_data&&other.m_data ? m_data->operator>(*other.m_data) : false;
}
////////////////////////////////////////////////////////////////////////////////
bool ObjRefCount::operator<(const ObjRefCount& other)const
{
return m_data&&other.m_data ? m_data->operator<(*other.m_data) : false;
}
////////////////////////////////////////////////////////////////////////////////