Archon::Utilities::MutaRef< T > Struct Template Reference

Reference counting with copy-on-write (or lazy copy) semantics. More...

#include <archon/util/muta_ref.H>

Collaboration diagram for Archon::Utilities::MutaRef< T >:

Collaboration graph
[legend]
List of all members.

Public Types

typedef T ObjectType

Public Member Functions

void reset (T *q=0)
 With no argument this method breaks the reference to the previously referenced object and makes this reference a null reference.
void mutate ()
 Prepare for a mutating operation on the referenced object.
void leak ()
 Prepare for a leaking operation on the referenced object.
 MutaRef ()
 Create a nil reference.
 MutaRef (const MutaRef &r)
 ~MutaRef ()
MutaRefoperator= (const MutaRef &r)
Toperator-> () const
 operator bool () const

Detailed Description

template<typename T>
struct Archon::Utilities::MutaRef< T >

Reference counting with copy-on-write (or lazy copy) semantics.

Say you want to build a class of objects with direct and natural copy semantics just like any of the fundamental integral types. You would then face a problem if your objects were in fact pretty big or for other reasons expensive to copy.

One common way to deal with this problem is to employ a copy-on-write scheme. That is, your objects (as they appear to the user) are in fact only references to the real objects. The real objects can then be shared amongst several logical objects as long as they are not modified. While requireing reference counting this provides for a cheap copy operation.

Whenever a modifying operation is invoked on one of the logical objects, we are forced to actually copy or clone the real object.

Together with MutaRefObjectBase this class provides the foundation needed when building classes with copy-on-write semantics.

When you derive a class from MutaRefObjectBase you give up the control of object deletion.

Contrary to the case of the plain Ref you cannot combine this class with other elements of reference counting. That is, if your class derives from this class it may not also derive from another class which is concerned with deletion control. Neither may you derive multiple times from this class.

In most other respects this type of reference counting is identical to that of Ref.

It does not have a special fresh state and thus it does not need a special boot operation to create the first reference to an allocated object. Because the MutaRef almost always will be used inside a single class it does not need such kinds of safty measures.

See also:
MutaRefObjectBase

Ref

Definition at line 76 of file muta_ref.H.


Constructor & Destructor Documentation

template<typename T>
Archon::Utilities::MutaRef< T >::MutaRef const MutaRef< T > &  r  )  [inline]
 

Note:
May throw under the same circumstances as reset.

Definition at line 244 of file muta_ref.H.


Member Function Documentation

template<typename T>
void Archon::Utilities::MutaRef< T >::leak  )  [inline]
 

Prepare for a leaking operation on the referenced object.

A leaking operation is an operation that grants the user direct and unchecked write access to the internals of the referenced object. One would allow such a thing only for performance reasons.

For obvious reasons we are not able to guarantee constancy of an object that has "suffered" a leaking operation. Therefore such an object can never again be shared amongst multiple MutaRef variables.

For this reason we must first take actions to become the only reference to the object. This invloves the equivalent of calling mutate(). Secondly we must make sure that all future copies of this reference leads to a clone operation. This is ensured by putting the object in the leaked state.

For the same reasons as in mutate(), invocation of this function may lead to an unnecessary clone operation.

See also:
mutate()

Definition at line 202 of file muta_ref.H.

Referenced by Archon::Utilities::Image::getPixelBuffer(), and Archon::Utilities::Image::getPixelPtr().

template<typename T>
void Archon::Utilities::MutaRef< T >::mutate  )  [inline]
 

Prepare for a mutating operation on the referenced object.

A mutating (or writing) operation requires that the referenced object is not shared (ie. is not referenced from anywhere else.) If this is not already the case, the referenced object is cloned and this MutaRef variable is made to refer to the newly created clone.

Upon return it is guaranteed that the referenced object is not referenced from anywhere else than this MutaRef variable.

This member function may sometimes go through the cloning procedure even when it was not absolutely necessary. This could happen if two threads (each with a MutaRef to the same object) choose to call this method simultaneously and the object is not otherwise referenced. Both will produce a clone of the original object, and then cut the connection to the original object. Since no one else knows about the original, it will be deleted. Apparently, a more efficient solution in this case would have been to only clone the object once, and then give the clone to one thread and the original to the other thread. However, guaranteeing such an optimal resolution in every case is hard, given the chosen implementation strategy.

Please note that this unnecessary cloning will not impose any safety problems. Further more the author believes that it will occur seldom under normal conditions of use. Thus, the user should not be too worried about it.

Definition at line 147 of file muta_ref.H.

Referenced by Archon::Utilities::Image::setComment(), and Archon::Utilities::Image::setPixel().

template<typename T>
MutaRef& Archon::Utilities::MutaRef< T >::operator= const MutaRef< T > &  r  )  [inline]
 

Note:
May throw under the same circumstances as reset.

Definition at line 254 of file muta_ref.H.

template<typename T>
void Archon::Utilities::MutaRef< T >::reset T q = 0  )  [inline]
 

With no argument this method breaks the reference to the previously referenced object and makes this reference a null reference.

Otherwise it breaks the reference to the previously referenced object and creates a new reference to the object pointed to by the argument.

The calling thread must in some way be able to guarantee that the passed object remains in existence during the call.

Note:
In a mutltihreaded application a plain pointer to a reference counted object poses a danger. The object may get deallocated at any time by another thread. A general rule of thumb is that any thread dealing with a plain pointer to a reference counted object, does this only during a period where a counted reference to the same object is held on the stack of that thread. This will guarantee the validity of the plain pointer.

This member functions will throw no exceptions except those potentially thrown by the clone method of the object pointet to by q. If you know for a fact that this clone method does not throw or is not called then you may safely assume that this member function does not throw any exceptions. You know it will not involve a clone operation if either you are about to create the first reference to a freshly allocate object or if you can otherwise guarantee that the object pointet to by q is not in the leaked state and will not enter the leaked state during the execution of this member function.

Definition at line 111 of file muta_ref.H.

Referenced by Archon::Utilities::Image::Image().


The documentation for this struct was generated from the following file:
Generated on Sun Jul 30 22:57:42 2006 for Archon by  doxygen 1.4.4