-
STL iterators
Suppose I want to have itertors for my own class.
In particular, I have a class with the purpose of resolving wildcarded filenames for me (searches the filesystem for any files that match, stores them internally).
Is there a way I can make the class expose an output iterator even if I don't have an STL container internally? So I can do:
vector<string> vs;
CFileGetter fg(file, bRecursive);
copy(fg.begin(), fg.end(), back_inserter(vs));
Thx in advance.
-
Thats the whole point of the STL. You can provide your own iterators for your own container classes, and you can still use them compatibly. In fact, it is recommended that you do.
Z.
-
-
Well, what is your internal structure? Say a raw pointer...
Code:
template<class t>
class F_Iterator
{
public:
F_Iterator& operator ++(){m_pos_ptr++;return *this;}
F_Iterator& operator --(){m_pos_ptr--;return *this;}
t& operator *(){return *m_pos_ptr;}
t& operator *() const{return *m_pos_ptr;}
private:
t* m_pos_ptr;
};
Should work. Make that an inner class of your container class... then...
Code:
F_Iterator<t> YourClass<t>::begin()
{
F_Iterator<t> i;
i.m_pos_ptr = myStuff;
return i;
}
F_Iterator<t> YourClass<t>::end()
{
F_Iterator<t> i;
i.m_pos_ptr = myStuff + mySize;
return i;
}
Should work...
Z.
-
In what way is that compatible to the other STL iterators?
-
Compatible by concept.
That is, it can be substituted in a template, therefore it must supply certain features, things like * to dereference, ++/-- to navigate, things like that.
They don't need *all* of those, but you'll find which ones you need when you try and use them.
If it looks like an STL iterator when reading the code, you're on a good track.
-
The above code needs a couple of boolean operators as well (specifically, != would be a needed one).
Z.
-
Can I pass such an iterator to the algorithms?
-
As long as you provide the operators that the algorithm function requires. Remember, since all of the algorithms are templated functions, the code is provided with the compiler. The templates are compiled along with your own code, and as long as the template algorithm functions try to call functions and operators that you have provided, you are fine.
Z.
-
Hmmmmm....
Thanks.
Thing is, I'm writing classes that encapsulate POSIX file system handling, and I need iterators to enumerate the directory entries.
It's just a quick hack currently, but I want to upgrade it to full STL requirements compliance later.
-
See the Filesystem library at www.boost.org :)
I think so far it's only in the sandbox CVS, but it should appear in the 1.29 release...
-
thx parksie, will take a look tomorrow - actually today (damn I'm tired)
Ok, found some info (mainly by browsing the list and iterator headers).
Whatever class you use as iterator (I use a class because of the very special ++ operation I need to perform), it must contain a few typedefs in order to get iterator_traits working:
typedef some_tag iterator_category;
where some_tag may be any of
input_iterator_tag
output_iterator_tag
forward_iterator_tag
bidirectional_iterator_tag
random_access_iterator_tag
pointers are classified as random access iterators
typedef foo value_type;
where foo is is the type of (*iterator)
typedef value_type *pointer;
typedef value_type &reference;
unless you use some special kind of pointer
typedef bar difference_type;
where bar is a type capable of expressing the difference between two iterators. For pointers this defaults to ptrdiff_t
There was another one, but I forgot...
-
There is no filesystem library in the list at boost.org...
-
You need the sandbox, it's not going in until 1.29.
-
you mean January 1st?
Can't wait that long, needs to be finished in at most two weeks
-
You can download it from their CVS repository.
No wait, you're on Windows ;)
-
It's for UNIX, so I can. But I don't know how. Maybe you can help?
-
They have the login and download instructions on their site. You need to build their build tool as well though :-/
It's a bit complex because you have to merge the two together.
Ah well. Don't bother and have a play when it gets released ;)
-
Well, here is a nifty little tidbit I discovered =). Raw pointers seem to be perfectly valid "iterators" to be passed to the various <algorithm> functions =).
Z.
-
Yep. I think that was one of the original goals of them :)
It took me a while to find that as well, but when I did, my life got easier :D
-
Im sure =). I was playing around with the allocator class, and it just sort of popped into my head... so i tried it =).
Z.
-
There is a specialization of the iterator_traits struct for any pointer, this is why it works. They are always classified as random access, with ptrdiff_t being the difference type.
Most STL vector implementations use raw pointers as iterators.
-
Been playing with allocators too. Load of fun =).
Z.
-
Haven't looked into allocators yet, what can you use them for?
But I found an interesting article about creating a string class with case-independent comparison as a specialisation of basic_string. Can't remember where though...
-
Well, the default allocator will simply use new, and give you a chunk of memory, but you can overlaod that behavior. For instance, last night, I overloaded the allocate and deallocate functions so that the memory returned was a part of a static memory block (ie, all objects are created in the same block of memory. Since all of the STL objects can take allocator parameters, you could use this so that your vector, map, list, etc, etc, all took memory where you specify.
Lots of fun =).
Z.
-
Very cool. STL rocks, and as Bjarne Strousrup says, we all have yet to learn the STL.
-