G
Gianni Mariani
I'm looking at templatizing some code that uses pointers and iterators.
There are 3 kinds of values for pointers.
- Null
- Invalid ( the value is ((T*)-1) )
- Valid
Null indicates that the pointer is Null - cool.
Invalid indicates that the pointer is uninitialized - using this value
fails asserts.
Valid points to an object.
Now I want to use iterators and I don't have access to a container.
I was thinking I could use:
typedef map<X>::iterator container_iterator; // any container
union Ptr
{
ptr_diff_t val;
container_iterator ptr;
};
bool IsNull( const Ptr & ptr )
{
assert( ptr.val != -1 );
return ( ptr.val == 0 );
}
container_iterator::value_type & dereference ( Ptr & ptr )
{
assert( ptr.val != -1 );
return * ptr.ptr;
}
Did I break somthing ? I probably did. Firstly, a container_iterator
may occupy more space than a ptr_diff_t and even if it did not, the are
assuptions here that are probably not universally true.
The question is, am I missing somthing regarding iterators ? Is there
a way to initialize an STL iterator to a "null" and also an "invalid"
value without creating a class that is larger than the iterator itself ?
I would find it very useful if you could contain other interesting
values for iterators.
The example for a POD pointer is easy. This code should work on any
conforming C++ compiler.
typedef value_type * pointer_type;
struct Ptr
{
pointer_type ptr;
};
bool IsNull( const Ptr & ptr )
{
assert( ptr.ptr != ( pointer_type * ) -1);
return ( ptr.val == 0 );
}
container_iterator::value_type & dereference ( Ptr & ptr )
{
assert( ptr.ptr != ( pointer_type * ) -1);
return * ptr.ptr;
}
There are 3 kinds of values for pointers.
- Null
- Invalid ( the value is ((T*)-1) )
- Valid
Null indicates that the pointer is Null - cool.
Invalid indicates that the pointer is uninitialized - using this value
fails asserts.
Valid points to an object.
Now I want to use iterators and I don't have access to a container.
I was thinking I could use:
typedef map<X>::iterator container_iterator; // any container
union Ptr
{
ptr_diff_t val;
container_iterator ptr;
};
bool IsNull( const Ptr & ptr )
{
assert( ptr.val != -1 );
return ( ptr.val == 0 );
}
container_iterator::value_type & dereference ( Ptr & ptr )
{
assert( ptr.val != -1 );
return * ptr.ptr;
}
Did I break somthing ? I probably did. Firstly, a container_iterator
may occupy more space than a ptr_diff_t and even if it did not, the are
assuptions here that are probably not universally true.
The question is, am I missing somthing regarding iterators ? Is there
a way to initialize an STL iterator to a "null" and also an "invalid"
value without creating a class that is larger than the iterator itself ?
I would find it very useful if you could contain other interesting
values for iterators.
The example for a POD pointer is easy. This code should work on any
conforming C++ compiler.
typedef value_type * pointer_type;
struct Ptr
{
pointer_type ptr;
};
bool IsNull( const Ptr & ptr )
{
assert( ptr.ptr != ( pointer_type * ) -1);
return ( ptr.val == 0 );
}
container_iterator::value_type & dereference ( Ptr & ptr )
{
assert( ptr.ptr != ( pointer_type * ) -1);
return * ptr.ptr;
}