473,395 Members | 1,474 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Comparing an iterator to a NULL value

Hello,

I have a problem with iterators in a fairly complex polygonal mesh data
structure which is implemented using lists of geometric entities.
However, the problem in itself is fairly simple:

I need to define special iterator values. In particular, I want a null
iterator. This is different from end() which means the end of this
list. I want an iterator value that is known to just not correspond to
any element. It must be possible to compare using == and != and, of
course, this special value must be invariant to changes to the data
structure.

Say the type is

list<int>

and my special iterator is NULL_INT_LIST_ITERATOR

I want to compare like this

a == NULL_INT_LIST_ITERATOR

and this comparison should return true only if a has previously been
assigned my null value. Previously, I did this using

----------------------------------------------
typedef list<int>::iterator IntIter;
IntIter NULL_INT_LIST_ITER(0);
----------------------------------------------

This just defines an iterator with an internal null pointer. That works
fine in g++ but it is not documented that it should work. Arguably it
is ugly. A different solution is this

----------------------------------------------
inline IntIter get_null_int_iter()
{
static list<int> l;
return l.end();
}
#define NULL_INT_LIST_ITER get_null_int_iter()
-----------------------------------------------

However, this solution does not work in recent version of Microsoft
visual studio. The reason *appears* to be that when I compare this
iterator value to a different iterator value it is detected that
NULL_INT_LIST_ITER belongs to a different list.

It seems you can make it work by defining HAS_ITERATOR_DEBUGGING=0.
However, the program still does not work - but possibly for different
reasons.

If you have a better solution, I'd be grateful to hear about it.

Thanks

Andreas

Dec 13 '05 #1
7 5157
andreas wrote:
Hello,

I have a problem with iterators in a fairly complex polygonal mesh data
structure which is implemented using lists of geometric entities.
However, the problem in itself is fairly simple:

I need to define special iterator values. In particular, I want a null
iterator. This is different from end() which means the end of this
list. I want an iterator value that is known to just not correspond to
any element. It must be possible to compare using == and != and, of
course, this special value must be invariant to changes to the data
structure.

Say the type is

list<int>

and my special iterator is NULL_INT_LIST_ITERATOR

I want to compare like this

a == NULL_INT_LIST_ITERATOR


Why would one want to do BS like that?

Compare your iterator to yourlist.end() and nothing else. PERIOD.
/S
--
Stefan Naewe
naewe.s_AT_atlas_DOT_de
Dec 13 '05 #2
andreas wrote:
I need to define special iterator values. In particular, I want a null
iterator. This is different from end() which means the end of this
list. I want an iterator value that is known to just not correspond to
any element. It must be possible to compare using == and != and, of
course, this special value must be invariant to changes to the data
structure.
[...]


Could you try to justify why you need that thing?

An iterator serves a particular purpose: to iterate. So, as such, it
should always be initialised (to the beginning of the sequence), used
(by increment, usually), and then discarded when the sequence is exhausted
(and that's determined by comparing the iterator to 'end()'). If you just
need to identify something in a collection, you're allowed to keep any
pointers, references, sometimes indices. Those can become invalid, but so
can iterators. IOW, I am unclear what you're going to accomplish by
letting iterators to become "NULL". Perhaps if you explain what problem
you're trying to solve, we could suggest a better solution...

V
Dec 13 '05 #3
andreas wrote:
Hello,

I have a problem with iterators in a fairly complex polygonal mesh data
structure which is implemented using lists of geometric entities.
However, the problem in itself is fairly simple:

I need to define special iterator values. In particular, I want a null
iterator. This is different from end() which means the end of this
list. I want an iterator value that is known to just not correspond to
any element. It must be possible to compare using == and != and, of
course, this special value must be invariant to changes to the data
structure.

Say the type is

list<int>

and my special iterator is NULL_INT_LIST_ITERATOR

I want to compare like this

a == NULL_INT_LIST_ITERATOR

and this comparison should return true only if a has previously been
assigned my null value. Previously, I did this using

----------------------------------------------
typedef list<int>::iterator IntIter;
IntIter NULL_INT_LIST_ITER(0);
----------------------------------------------

This just defines an iterator with an internal null pointer. That works
fine in g++ but it is not documented that it should work. Arguably it
is ugly.
yes, and definitely not portable. the standard does not guarantee any
iterator constructors besides default and copy initializers. for
non-trivial iterators, positions are only meant to be assigned
internally by the corresponding container class functions.
A different solution is this

----------------------------------------------
inline IntIter get_null_int_iter()
{
static list<int> l;
return l.end();
}
#define NULL_INT_LIST_ITER get_null_int_iter()
-----------------------------------------------

However, this solution does not work in recent version of Microsoft
visual studio. The reason *appears* to be that when I compare this
iterator value to a different iterator value it is detected that
NULL_INT_LIST_ITER belongs to a different list.

It seems you can make it work by defining HAS_ITERATOR_DEBUGGING=0.
However, the program still does not work - but possibly for different
reasons.
i would not rely on the result of comparing iterators from different
container instances. the standard is unclear in that regard. besides,
HAS_ITERATOR_DEBUGGING is your friend :)

If you have a better solution, I'd be grateful to hear about it.


wrap the standard iterators in your own iterator class with support for
the additional state if you want to implement this at iterator level.
the required interface is pretty simple.

i would recommend to use boost::iterator, which provides helpers to
create fully standard compliant iterators in very short time.

see http://boost.org/libs/iterator/doc/index.html

-- peter

Dec 13 '05 #4
Hello,
wrap the standard iterators in your own iterator class with support for
the additional state if you want to implement this at iterator level.
the required interface is pretty simple.

i would recommend to use boost::iterator, which provides helpers to
create fully standard compliant iterators in very short time.

see http://boost.org/libs/iterator/doc/index.html


That might be a good solution. The only thing that detracts is the fact
that added state will make the custom iterators larger, but that might
be a necessary evil.

Meanwhile, it seems that some of you find my use of the STL slightly
frivolous :-), so I'll explain why I need this unusual construct.

I have three types (Face, HalfEdge, Vertex) and corresponding lists of
objects belonging to these classes.

A HalfEdge needs iterators to elements in the Vertex and Face and even
HalfEdge lists (the last also required an unusual but quite portable
template construct). It must be iterators, because I need to be able to
remove, say, a Face list element indicated by an iterator in an element
of the halfedge list.

(Digression: That is also why I do not use vectors instead of lists. It
would simplify a number of things, and I could use index values of -1
to indicate a NULL element. However, you know the problems with random
deletion and vectors.)

Now, the face iterator stored in a halfedge does not always correspond
to a valid face. The data structure is for polygonal meshes, and it is
quite possible to have holes which are indicated by an iterator in the
halfedge being set to NULL_FACE_ITER.

Ok. So arguably I might be caught up in thinking in terms of pointers,
and I could of course simply add state to the halfedge class to
indicate that it is a boundary halfedge whose face is not defined.
It would however add some code here and there and make the data
structure fatter.

Solution number 2 would be to add this state to custom iterators. That
solution might indeed be prettier. However, if all iterators grow one
byte plus alignment, the data structure will really become a bit large
- after all the mesh can easily contain hundreds of thousands of faces,
edges and vertices.

At any rate, you all seem to suggest that I should solve the problem by
adding state, so that might well be what I end up doing.

Thanks so far :-)

Andreas

Dec 13 '05 #5
Hello,
wrap the standard iterators in your own iterator class with support for
the additional state if you want to implement this at iterator level.
the required interface is pretty simple.

i would recommend to use boost::iterator, which provides helpers to
create fully standard compliant iterators in very short time.

see http://boost.org/libs/iterator/doc/index.html


That might be a good solution. The only thing that detracts is the fact
that added state will make the custom iterators larger, but that might
be a necessary evil.

Meanwhile, it seems that some of you find my use of the STL slightly
frivolous :-), so I'll explain why I need this unusual construct.

I have three types (Face, HalfEdge, Vertex) and corresponding lists of
objects belonging to these classes.

A HalfEdge needs iterators to elements in the Vertex and Face and even
HalfEdge lists (the last also required an unusual but quite portable
template construct). It must be iterators, because I need to be able to
remove, say, a Face list element indicated by an iterator in an element
of the halfedge list.

(Digression: That is also why I do not use vectors instead of lists. It
would simplify a number of things, and I could use index values of -1
to indicate a NULL element. However, you know the problems with random
deletion and vectors.)

Now, the face iterator stored in a halfedge does not always correspond
to a valid face. The data structure is for polygonal meshes, and it is
quite possible to have holes which are indicated by an iterator in the
halfedge being set to NULL_FACE_ITER.

Ok. So arguably I might be caught up in thinking in terms of pointers,
and I could of course simply add state to the halfedge class to
indicate that it is a boundary halfedge whose face is not defined.
It would however add some code here and there and make the data
structure fatter.

Solution number 2 would be to add this state to custom iterators. That
solution might indeed be prettier. However, if all iterators grow one
byte plus alignment, the data structure will really become a bit large
- after all the mesh can easily contain hundreds of thousands of faces,
edges and vertices.

At any rate, you all seem to suggest that I should solve the problem by
adding state, so that might well be what I end up doing.

Thanks so far :-)

Andreas

Dec 13 '05 #6
andreas wrote:
[...]
I have three types (Face, HalfEdge, Vertex) and corresponding lists of
objects belonging to these classes.

A HalfEdge needs iterators to elements in the Vertex and Face and even
HalfEdge lists (the last also required an unusual but quite portable
template construct). It must be iterators, because I need to be able to
remove, say, a Face list element indicated by an iterator in an element
of the halfedge list.
[..]
Now, the face iterator stored in a halfedge does not always correspond
to a valid face. The data structure is for polygonal meshes, and it is
quite possible to have holes which are indicated by an iterator in the
halfedge being set to NULL_FACE_ITER.
IIRC, the usual way is to actually have a valid face, and to designate it
as a _hole_. It makes for more consistent data structure and algorithms
become more straight-forward. This is OT, of course. You need to consult
with 'comp.graphics.algorithms' for more recommendations on how to manage
your topology better.
[..]


V
Dec 13 '05 #7

andreas wrote:
Hello,

I have a problem with iterators in a fairly complex polygonal mesh data
structure which is implemented using lists of geometric entities.
However, the problem in itself is fairly simple:

I need to define special iterator values. In particular, I want a null
iterator. Previously, I did this using

----------------------------------------------
typedef list<int>::iterator IntIter;
IntIter NULL_INT_LIST_ITER(0);
----------------------------------------------


Try

typedef boost::optional<list<int>::iterator> IntIter;

HTH,
Michiel Salters

Dec 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: david | last post by:
Hello, Is the code below correct ? I always get an seg fault on execution and the debugger points to c_str() ? Basically i want to convert the value std::string to char * within the iterator...
5
by: Curtis Gilchrist | last post by:
I am required to read in records from a file and store them in descending order by an customer number, which is a c-style string of length 5. I am storing these records in a linked list. My...
3
by: uclamathguy | last post by:
I am working on connected component analysis, but that is irrelevant. I have a mapping containing ints as the keys and sets of ints as the "values." Given an integer, I need to iterate through...
15
by: sandwich_eater | last post by:
I want to know how to set an std::list iterator variable to make it null or nil. If this is not possible what is the value of an uninitialised std::list iterator and is it ok to assign this value...
14
by: shawnk | last post by:
I searched the net to see if other developers have been looking for a writable iterator in C#. I found much discussion and thus this post. Currently (C# 2) you can not pass ref and out arguments...
3
by: 2b|!2b==? | last post by:
If an iterator is a pointer, then why can't I assign an 'int' (NULL) to it? This works fine in debug, but fils to compile with Release configuration ..: bool myParser::spellCheck(TokenList...
25
by: J Caesar | last post by:
In C you can compare two pointers, p<q, as long as they come from the same array or the same malloc()ated block. Otherwise you can't. What I'd like to do is write a function int comparable(void...
2
by: =?Utf-8?B?QWxoYW1icmEgRWlkb3MgS2lxdWVuZXQ=?= | last post by:
Hi mister, I have an object with two properties, of type DateTime? (Nullable). Which is the best way for comparing ? The value of datetime can be null, and another value cannot be null, or two...
4
by: thinktwice | last post by:
std::vector<CStringvec; vec::iterator iter; i can initiaze the iterator in vc6 like this $B!'(B iter = NULL, but it compile failed in vc2005, it tells me there is no acceptable conversion.
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.