Loki: StrongPtr Ownership policies

# StrongPtr Ownership policies
[Smart pointers]

Collaboration diagram for StrongPtr Ownership policies:

## Classes
class | Loki::Private::TwoRefCountInfo
class | LockableTwoRefCountInfo
class | Loki::TwoRefCounts
class | LockableTwoRefCounts
class | Loki::TwoRefLinks

## Detailed Description

Terminology
  These terms are used within this file's comments.
  1. StrongPtr : Class used to implement both strong and weak pointers. The second template parameter determines if a StrongPtr is weak or strong.
  2. Strong pointer : A pointer that claims ownership of a shared object. When the last strong copointer dies, the object is destroyed even if there are weak copointers.
  3. Weak pointer : A pointer that does not own the shared object it points to. It only destroys the shared object if there no strong copointers exist when it dies.
  4. Copointers : All the pointers that refer to the same shared object. The copointers must have the same ownership policy, but the other policies may be different.
  5. Pointee : The shared object.

OwnershipPolicy
  The ownership policy has the pointer to the actual object, and it also keeps track of the strong and weak copointers so that it can know if any strong copointers remain. The plain pointer it maintains is stored as a void pointer, which allows the ownership policy classes to be monolithic classes instead of template classes. As monolithic classes, they reduce amount of code-bloat.

Writing Your Own OwnershipPolicy
  If you write your own policy, you must implement these 12 functions:
  1. explicit YourPolicy( bool strong )
  2. YourPolicy( void * p, bool strong )
  3. YourPolicy( const YourPolicy & rhs, bool strong )
  4. bool Release( bool strong )
  5. void Increment( bool strong )
  6. bool Decrement( bool strong )
  7. bool HasStrongPointer( void ) const
  8. void Swap( YourPolicy & rhs )
  9. void SetPointer( void * p )
  10. void ZapPointer( void )
  11. void * GetPointer( void ) const
  12. void * & GetPointerRef( void ) const It is strongly recommended that all 12 of these functions be protected instead of public. These two functions are optional for single-threaded policies, but required for multi-threaded policies:
  13. void Lock( void ) const
  14. void Unlock( void ) const This function is entirely optional:
  15. bool Merge( TwoRefLinks & rhs )

DeletePolicy
  The delete policy provides a mechanism to destroy an object and a default value for an uninitialized pointer. You can override this policy with your own when using the Singleton, NullObject, or Prototype design patterns.

Writing Your Own DeletePolicy
  If you write your own policy, you must implement these 3 functions:
  1. void static Delete( const P * p )
  2. static P * Default( void )
  3. void Swap( YourResetPolicy & )

ResetPolicy
  A reset policy tells the ReleaseAll and ResetAll functions whether they should release or reset the StrongPtr copointers. These functions do not affect just one StrongPtr, but all copointers. That is unlike SmartPtr where the Release and Reset functions only affect 1 SmartPtr, and leave all copointers untouched. A useful trick you can do with the ResetPolicy is to not allow reset when a strong pointer exists, and then use the NoCheck policy for all strong pointers. The reset policy guarantees the strong pointers always have a valid pointee, so checking is not required; but weak pointers may still require checking.

Writing Your Own ResetPolicy
  If you write your own policy, you must implement these 2 functions:
  1. bool OnReleaseAll( bool ) const
  2. bool OnResetAll( bool ) const The bool parameter means that this was called with a strong pointer or one of its copointers is strong. The return value means the pointer can be reset or released.