1.Rationale...........................................................................................................................2 2.Overview..............................................................................................................

.............2 3.Internals.............................................................................................................................4 3.1.Reference count.........................................................................................................4 3.2.Set theory...................................................................................................................4 3.3.Memory segment.......................................................................................................4 4.API....................................................................................................................................5

1. Rationale Smart pointers are in general optimized for a specific resource (memory usage, CPU cycles, user friendliness, ...) depending on what the user need to make the most of. The purpose of this smart pointer is mainly to allocate the reference counter (or owner) and the object itself at the same time so that dynamic memory management is simplified thus accelerated and cheaper on the memory map. Pros: • • • • • • Cons: • • Requires usage of new_sh<T>() Cannot be easily interchanged with boost::shared_ptr<T> or T * Single machine instruction to get the pointee object (get()) One memory allocation for the pointee object Memory usage having a power of 2 (sizeof(void *) * 2) Constant complexity O(1) No need for special classes for array allocations / deallocations All local allocations are guaranteed to be deallocated instantly on exit

2. Overview You need to use new_sh<T>() function call every time you wish to allocate a new object associated with this pointer.
// Allocate object: shifted_ptr<int> p = new_sh<int>(9); // The reference count gets incremented: shifted_ptr<T> q = p;

Beforehand let's start with an example of its usage:
struct A { int i; shifted_ptr<A> p; A(int i = 0) : i(i) { cout << __func__ << ": " << i << endl; }

~A() { } }; int main() { shifted_ptr<A> p = new_sh<A>(7); shifted_ptr<A> q = new_sh<A>(8); shifted_ptr<A> r = new_sh<A>(9); shifted_ptr<A[5]> s = new_sh<A[5]>(); shifted_ptr<void> t = new_sh<A>(10); shifted_ptr<char[9]> u = new_sh<char[9]>(); p->p = p; q = r; u[4] = 'Z'; cout cout cout cout } << << << << "p->i "q->i "r->i "u[4] = = = = " " " " << << << << p->i q->i r->i u[4] << << << << endl; endl; endl; endl; cout << __func__ << ": " << i << endl;

cout << "Done." << endl;

Outputs:
A::A(int): 7 A::A(int): 8 A::A(int): 9 A::A(int): 0 A::A(int): 0 A::A(int): 0 A::A(int): 0 A::A(int): 0 A::A(int): 10 A::~A(): 8 p->i = 7 q->i = 9 r->i = 9 u[4] = Z Done. A::~A(): 10 A::~A(): 10 A::~A(): 0 A::~A(): 0 A::~A(): 0 A::~A(): 0 A::~A(): 0 A::~A(): 9 A::~A(): 7

3. Internals uses different 3 techniques to determine characteristics of an object subject to deletion; all of them depending on each other. The cubic term can subsequently be used to address to these 3 techniques.
shifted_ptr

3.1. Reference count This is the standard reference count that determines how many smart pointers are referring to a discrete element. 3.2. Set theory The set theory is used to assign each object newly allocated to a given set. In practice a set can be viewed as a container. In contrast to the standard reference counted smart pointers, we need to add another pointer to a set object inside the class itself. This way we are now able to find forthwith to which set any shifted_ptr object located on the heap belongs. Moreover if any shifted_ptr object owned by one set points to an object belonging to another set then they are merged together. At that moment the laws of deletion have changed because the pointer responsible for the merge, will become the parent of its subjected set and must be therefore be marked for deletion before its children. Note: Being “marked for deletion” is the opposite of being deleted because of the reverse order destructors are called (child then parent). If the child in turn decides to point back to its parent then we have a cyclic pointer scenario. The order of deletion will still be the same but the objects aren’t going to be deleted until no shifted_ptr from the stack segment are referring to them. This leads to the next characteristic. 3.3. Memory segment This consists of knowing to which memory segment the pointer in question is located at. The possible segments are: stack, heap and data that can be related to the auto, new and finally extern or static keywords respectively in C/C++. We already know that all variables from the stack and data segment are going to be deleted before the application exits. We can thus define all pointers allocated on these segments as roots of all other objects dynamically allocated on the heap. This is

where we define a set we were previously referring to (see section 2.2). A set is hence created every time a shifted_ptr from the stack or data segment is created. These sets residing on the heap will consequently possess a reference counter of its own to determine the number of shifted_ptr from the stack or data segment are referring to them. When its last pointer gets destructed then we delete all elements included in the set, bypassing referencing counting of each element. Set reference counting thereupon overrides all individual reference counts. 4. API Detailed documentation concerning the API can be found here.

Copyright © 2008 Phil Bouchard (phil at fornux dot com) Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)