|
Boost : |
From: Angel Tsankov (fn42551_at_[hidden])
Date: 2008-07-22 15:37:55
Mathias Gaunard wrote:
> Angel Tsankov wrote:
>> Is there any interest in a class template which acts like a pointer
>> and guarantees at compile time and at no CPU or memory cost (except
>> when a call to any of its methods is not inlined) that the pointer
>> is not null?
>
> Preventing empty or invalid cases is always good.
> For example I think it's a shame Boost.Function, Boost.Any and the
> Boost Smart Pointers don't do it.
>
> As for forcing a pointer to not be empty, I suppose you're talking of
> making overloads of constructor and operator= for `int' and make them
> generate errors?
>
No. In C++, an int cannot be converted implicitly to a pointer, unless the
int is the NULL constant, which is not a valid value for unnullable_ptr.
Therefore, one should never need to construct unnullable_ptr from an int or
to assign an int to an unnullable_ptr so there is no need to have overloads
of constructor and operator= for int.
Currently, an unnulalble_ptr is constructed directly from the pointee like
this:
T t;
UnnullablePtr<T> pointer_to_t(t);
Constructors take the pointee by reference, and apart from the implicit copy
assignment there are no other mutable member functions. This is how the
unnullability is guaranteed at compile time.
On a side note, the behaviour of these constructors is inconsistent with the
behaviour of the copy constructor (which creates a copy of the passed
unnullable_ptr rather than a pointer to the passed unnullable_ptr). I'll
probably fix this by making the 'inconsistent' constructors private, adding
a (free) function template that calls the 'incosistent' constructors, and
making that function template a friend.
>
> Do you still provide pointer arithmetic and implicit upcasting?
>
Yes, implicit upcasting as well as the usual casts to void*, and T const*
are supported (I've even written several unit tests especially to check
the conversions). Implicit conversion from array to unnullable_ptr is also
supported.
As for pointer arithmetic, I've not yet needed it to work with
unnullable_ptr's, so I've not considered implementing it. Nevertheless, it
turns out that pointer arithmetic is partially supported (via the convertion
operator from unnullable_ptr to C pointer); this is to say that subtracting
unnullable_ptr's works, but subtracting int's from (or adding int's to)
unnullable_ptr's doesn't yet. In fact, subtracting an int from (as well as
adding an int to) an unnullable_ptr might result in a null pointer so the
result need to be checked. However, the current implementation of
unnullable_ptr is exactly as effective as a built-in C pointer (or at least
allows instances of unnulable_ptr to be that effective) and I would like to
keep it that way. So, subracting and adding int's will probably not be
supported, unless a zero-overhead way is devised to guarantee unnullability
of the result from these operations.
>
> I personally stay away from pointers, which I associate with bad
> programming.
> boost::ref already provides a safe way to do what you want, and better
> IMHO. It is not required to use pointers at all with it. And you *can*
> get the wrapped pointer resource with get or get_pointer.
>
As I mentioned in my first post, boost::ref does not support the natural
syntax for access to the wrapped resource. unnullable_ptr does -- it
overloads 'operator ->' and 'operator T*'. (The latter implicitly provides
dereferencing, i.e. there is no need to overload 'operator *'.)
A known limitation is that unnulalble_ptr cannot be used with member
functions (because there is no such thing as a reference to member function
from which an unnullable_ptr is to be initialized).
In order to be as clear as possible, I could provide all the source code of
unnullable_ptr (157 lines) but I'm afraid that this does not meet the Boost
posting guidelines. So, I think of uploading the code to the Vault.
Angel Tsankov
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk