Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Samer Afach
SharedPtr-cpp03
Commits
147337c5
Commit
147337c5
authored
Apr 06, 2017
by
Samer Afach
Browse files
Add SmartPtr.h
parent
9999f998
Changes
1
Show whitespace changes
Inline
Side-by-side
SmartPtr.h
0 → 100644
View file @
147337c5
#ifndef SMARTPTR_H
#define SMARTPTR_H
#include <map>
#include <string>
#include <stdexcept>
/**
* Simple shared pointer class with NO thread safety (not even the counter is thread-safe)
*/
template
<
typename
T
>
class
SmartPtr
{
//Rule 1: tracker is always NULL when ptr == NULL
//Rule 2: ID is only assigned in constructors
typedef
std
::
map
<
unsigned
long
,
SmartPtr
<
T
>*>
IDMap
;
typedef
std
::
pair
<
unsigned
long
,
SmartPtr
<
T
>*>
IDPair
;
T
*
ptr
;
IDMap
*
tracker
;
//track pointers to same object
unsigned
long
ID
;
static
unsigned
long
__IDCounter
;
public:
typedef
T
element_type
;
SmartPtr
(
const
SmartPtr
&
other
);
SmartPtr
<
T
>&
operator
=
(
const
SmartPtr
&
other
);
SmartPtr
(
T
*
new_ptr
=
NULL
);
T
&
operator
*
();
const
T
&
operator
*
()
const
;
~
SmartPtr
();
unsigned
long
use_count
()
const
;
operator
bool
();
T
*
get
();
const
T
*
const
get
()
const
;
T
*
release
();
void
reset
(
T
*
new_ptr
=
NULL
);
inline
bool
isNull
();
template
<
template
<
typename
_T
,
typename
=
std
::
allocator
<
_T
>
>
class
Container
>
static
Container
<
T
*>
GetRawPtrContainer
(
const
Container
<
SmartPtr
<
T
>
>&
input_container
);
};
template
<
typename
T
>
unsigned
long
SmartPtr
<
T
>::
__IDCounter
=
0
;
template
<
typename
T
>
template
<
template
<
typename
_T
,
typename
=
std
::
allocator
<
_T
>
>
class
Container
>
Container
<
T
*>
SmartPtr
<
T
>::
GetRawPtrContainer
(
const
Container
<
SmartPtr
<
T
>
>&
input_container
)
{
Container
<
T
*>
container
;
for
(
typename
Container
<
SmartPtr
<
T
>
>::
const_iterator
it
=
input_container
.
begin
();
it
!=
input_container
.
end
();
it
++
)
{
container
.
push_back
(
it
->
ptr
);
}
return
container
;
}
template
<
typename
T
>
SmartPtr
<
T
>::
SmartPtr
(
const
SmartPtr
&
other
)
{
this
->
tracker
=
other
.
tracker
;
this
->
ptr
=
other
.
ptr
;
this
->
ID
=
__IDCounter
++
;
if
(
!
isNull
())
tracker
->
insert
(
IDPair
(
ID
,
this
));
}
template
<
typename
T
>
SmartPtr
<
T
>
&
SmartPtr
<
T
>::
operator
=
(
const
SmartPtr
&
other
)
{
this
->
tracker
=
other
.
tracker
;
this
->
ptr
=
other
.
ptr
;
this
->
ID
=
__IDCounter
++
;
if
(
!
isNull
())
tracker
->
insert
(
IDPair
(
ID
,
this
));
return
*
this
;
}
template
<
typename
T
>
SmartPtr
<
T
>::
SmartPtr
(
T
*
new_ptr
)
{
ptr
=
NULL
;
tracker
=
NULL
;
ID
=
__IDCounter
++
;
reset
(
new_ptr
);
}
template
<
typename
T
>
T
&
SmartPtr
<
T
>::
operator
*
()
{
if
(
this
->
get
()
!=
NULL
)
return
*
this
->
get
();
else
throw
std
::
runtime_error
(
"Null pointer exception. Tried to dereference a NULL in SmartPtr"
);
}
template
<
typename
T
>
const
T
&
SmartPtr
<
T
>::
operator
*
()
const
{
if
(
this
->
get
()
!=
NULL
)
return
*
this
->
get
();
else
throw
std
::
runtime_error
(
"Null pointer exception. Tried to dereference a NULL in SmartPtr"
);
}
template
<
typename
T
>
SmartPtr
<
T
>::~
SmartPtr
()
{
reset
();
}
template
<
typename
T
>
unsigned
long
SmartPtr
<
T
>::
use_count
()
const
{
if
(
isNull
())
return
0
;
else
return
tracker
->
size
();
}
template
<
typename
T
>
SmartPtr
<
T
>::
operator
bool
()
{
return
!
isNull
();
}
template
<
typename
T
>
T
*
SmartPtr
<
T
>::
get
()
{
return
ptr
;
}
template
<
typename
T
>
const
T
*
const
SmartPtr
<
T
>::
get
()
const
{
return
ptr
;
}
template
<
typename
T
>
T
*
SmartPtr
<
T
>::
release
()
{
T
*
ret_ptr
=
ptr
;
if
(
!
isNull
())
{
IDMap
*
trackerHolder
=
tracker
;
for
(
typename
IDMap
::
iterator
it
=
trackerHolder
->
begin
();
it
!=
trackerHolder
->
end
();
it
++
)
{
it
->
second
->
ptr
=
NULL
;
it
->
second
->
tracker
=
NULL
;
}
delete
trackerHolder
;
}
return
ret_ptr
;
}
template
<
typename
T
>
void
SmartPtr
<
T
>::
reset
(
T
*
new_ptr
)
{
if
(
!
isNull
())
{
//ptr and tracker are not NULL, guaranteed
if
(
tracker
->
size
()
==
1
)
//this is the last reference
{
delete
ptr
;
ptr
=
NULL
;
delete
tracker
;
tracker
=
NULL
;
}
else
{
tracker
->
erase
(
ID
);
if
(
new_ptr
!=
NULL
)
{
tracker
=
new
IDMap
;
tracker
->
insert
(
IDPair
(
ID
,
this
));
}
else
{
tracker
=
NULL
;
ptr
=
NULL
;
}
}
}
else
//if this is NULL
{
if
(
new_ptr
!=
NULL
)
{
if
(
tracker
==
NULL
)
{
tracker
=
new
IDMap
;
tracker
->
insert
(
IDPair
(
ID
,
this
));
ptr
=
new_ptr
;
}
}
}
}
template
<
typename
T
>
bool
SmartPtr
<
T
>::
isNull
()
{
return
(
ptr
==
NULL
);
}
#endif // SMARTPTR_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment