[ptr_container] ptr_map predicates

How would I accomplish the following using ptr_map instead of std::map? typedef std::map< std::string, int* > stlmap; bool predicate( stlmap::value_type& mapitem ) { // return true if key value has at least 4 characters return( mapitem.first.size() > 3 ); } void sample( stlmap& themap ) { std::find_if( themap.begin(), themap.end(), predicate ); } The predicate for std::find_if requires *iterator for the parameter. However, with ptr_map *iterator returns a reference to the element value instead of the key/value pair. Normally this is fine (in general code I like this feature), but in this case I need access to the key in the predicate. How do I get at it? ptr_map version of above: typedef boost::ptr_map< std::string, int > bpmap; bool predicate( ??? ) { ??? } void sample( bpmap& themap ) { std::find_if( ??? ); }

Bill Buklis wrote:
How would I accomplish the following using ptr_map instead of std::map?
typedef std::map< std::string, int* > stlmap;
bool predicate( stlmap::value_type& mapitem ) { // return true if key value has at least 4 characters return( mapitem.first.size() > 3 ); }
void sample( stlmap& themap ) { std::find_if( themap.begin(), themap.end(), predicate ); }
The predicate for std::find_if requires *iterator for the parameter. However, with ptr_map *iterator returns a reference to the element value instead of the key/value pair. Normally this is fine (in general code I like this feature), but in this case I need access to the key in the predicate. How do I get at it?
this is an interesting use-case that I haven't thought of.
ptr_map version of above:
typedef boost::ptr_map< std::string, int > bpmap;
bool predicate( ??? ) { ??? }
bool predicate( const std::pair
void sample( bpmap& themap ) { std::find_if( ??? ); }
void sample( bpmap& m ) { std::find_if( m.begin().base(), m.end().base(), predicate() ); } iterator.base() should return an iterator to the underlying void-ptr-map. I hope it works -Thorsten

How would I accomplish the following using ptr_map instead of std::map?
typedef std::map< std::string, int* > stlmap;
bool predicate( stlmap::value_type& mapitem ) { // return true if key value has at least 4 characters return( mapitem.first.size() > 3 ); }
void sample( stlmap& themap ) { std::find_if( themap.begin(), themap.end(), predicate ); }
The predicate for std::find_if requires *iterator for the parameter. However, with ptr_map *iterator returns a reference to the element value instead of the key/value pair. Normally this is fine (in general code I
m.begin.base() seems like it might work, but I'm having a little trouble figuring out the right parameters for the predicate. bpmap::value_type doesn't match. What's the correct type/typedef to use for the base void-ptr-map? Thanks, -- Bill -- -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Thorsten Ottosen Sent: Thursday, February 09, 2006 4:09 AM To: boost-users@lists.boost.org Subject: Re: [Boost-users] [ptr_container] ptr_map predicates Bill Buklis wrote: like
this feature), but in this case I need access to the key in the predicate. How do I get at it?
this is an interesting use-case that I haven't thought of.
ptr_map version of above:
typedef boost::ptr_map< std::string, int > bpmap;
bool predicate( ??? ) { ??? }
bool predicate( const std::pair
void sample( bpmap& themap ) { std::find_if( ??? ); }
void sample( bpmap& m ) { std::find_if( m.begin().base(), m.end().base(), predicate() ); } iterator.base() should return an iterator to the underlying void-ptr-map. I hope it works -Thorsten _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

How would I accomplish the following using ptr_map instead of std::map?
typedef std::map< std::string, int* > stlmap;
bool predicate( stlmap::value_type& mapitem ) { // return true if key value has at least 4 characters return( mapitem.first.size() > 3 ); }
void sample( stlmap& themap ) { std::find_if( themap.begin(), themap.end(), predicate ); }
The predicate for std::find_if requires *iterator for the parameter. However, with ptr_map *iterator returns a reference to the element value instead of the key/value pair. Normally this is fine (in general code I
Nevermind. I see you did put the predicate in your message. Thanks. Somehow
I missed it when reading it.
bool predicate( const std::pair
this feature), but in this case I need access to the key in the predicate. How do I get at it?
this is an interesting use-case that I haven't thought of.
ptr_map version of above:
typedef boost::ptr_map< std::string, int > bpmap;
bool predicate( ??? ) { ??? }
bool predicate( const std::pair
void sample( bpmap& themap ) { std::find_if( ??? ); }
void sample( bpmap& m ) { std::find_if( m.begin().base(), m.end().base(), predicate() ); } iterator.base() should return an iterator to the underlying void-ptr-map. I hope it works -Thorsten _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Bill Buklis wrote:
Nevermind. I see you did put the predicate in your message. Thanks. Somehow I missed it when reading it.
bool predicate( const std::pair
& p ) { return p.first.size() > 3; } This does work correctly. Thanks.
HTH
Out of curiosity, if nothing else, is there a corresponding typedef that would match this? std::map would use value_type. What would be the equivalent for the ptr_map/void-ptr-map? Of course, depending on the length and indirection, it may be better anyway to explicitly list it out as the std::pair.
The current docs are a bit weak in this matter. But
ptr_map

From a user's perspective all you care about is that it is relatively easy to use, that you can get it do what you want, and it's not too difficult to
The design of the normal iterator is beautiful. I much prefer it this way,
i.e. using it as if it were a pointer to the object. The downside, of
course, was just when you do need a key/value iterator. Since it can be done
using the pair
From an aesthetics standpoint, it would be nice to have the two types of iterators depending on what you need. The code would be more readable. It would also shut those up who complain about the iterators not acting like std::map. "Look, use map_iterator if you want that!" Also in those cases where you do need both the key and the value, you wouldn't have to cast the void* back to the correct object type.
Unless I'm mistaken this whole argument only pertains to ptr_map and ptr_multimap. The other classes only have a single value, so the iterators already act like the standard versions. What do you think? Anyone else have any thoughts on this?
I could thus add another pair of typedefs for this case. How does
void_ptr_map_reference void_ptr_map_const_reference
sound? Is it worth the effort?
As for the typedef, I'm honestly not sure if it's worth it or not. My goal
for typedefs (and I'm sure it is similar with most people) is that:
A: it makes the code more readable
B: it's shorter (a.k.a. less typing)
Using "void_ptr_map_reference", etc. falls in line with exposing details
more. Maybe it's worthwhile. Maybe it's not. I'm not sure. Personally it's
not a big deal for me typing std::pair
-----Original Message-----
Out of curiosity, if nothing else, is there a corresponding typedef that would match this? std::map would use value_type. What would be the equivalent for the ptr_map/void-ptr-map? Of course, depending on the length and indirection, it may be better anyway to explicitly list it out as the std::pair.
The current docs are a bit weak in this matter. But
ptr_map
::value_type is T* ptr_vector<T>::value_type is T*
The fact that you cannot use the normal iterator to access the key in an algorithm is of course bad when you need it, but I still feel that the design in general is OK given the domain.
There is no nested typedef right now that would give you the value-type of the void-ptr-map used internally, though you are guaranteed that it is std::map
. I could thus add another pair of typedefs for this case. How does
void_ptr_map_reference void_ptr_map_const_reference
sound? Is it worth the effort?
-Thorsten
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Bill Buklis wrote:
The design of the normal iterator is beautiful. I much prefer it this way, i.e. using it as if it were a pointer to the object. The downside, of course, was just when you do need a key/value iterator. Since it can be done using the pair
and base() iterator, perhaps that is sufficient and no changes need to be made. However, from a purely design perspective (as opposed to usage), the only problem I see with that is that it exposes the internal workings of the class a little (I try to keep my classes as "black box" as possible. It's not always feasible, but at least that's the initial goal). The only way around that I can see at the moment is to have two types of iterators offered by the class - the normal iterator (same as it is now) and a "map_iterator" which acts the same as a std::map iterator would.
you mean iterating over pair
I'm not sure how feasible that would be to implement. I haven't studied the inner workings of the ptr_map class that much (although I'm quickly learning more and more about it).
it's certainly doable, probably with a little overhead to create a proxy.
From a user's perspective all you care about is that it is relatively easy to use, that you can get it do what you want, and it's not too difficult to maintain.
right.
From an aesthetics standpoint, it would be nice to have the two types of iterators depending on what you need. The code would be more readable. It would also shut those up who complain about the iterators not acting like std::map. "Look, use map_iterator if you want that!" Also in those cases where you do need both the key and the value, you wouldn't have to cast the void* back to the correct object type.
yeah, that is bad.
Unless I'm mistaken this whole argument only pertains to ptr_map and ptr_multimap. The other classes only have a single value, so the iterators already act like the standard versions.
true.
What do you think?
I'm leaning towards a new iterator type that iterators over pair

"Bill Buklis"
From an aesthetics standpoint, it would be nice to have the two types of iterators depending on what you need. The code would be more readable. It would also shut those up who complain about the iterators not acting like std::map. "Look, use map_iterator if you want that!" Also in those cases where you do need both the key and the value, you wouldn't have to cast the void* back to the correct object type.
From an aesthetics standpoint, you should re-use transform_iterator with the appropriate function object to project a tuple of references into either the first or second element, rather than fattening the interface of this particular container. That transform_iterator idiom could then be re-used with std::map.
-- Dave Abrahams Boost Consulting www.boost-consulting.com

"Bill Buklis"
The predicate for std::find_if requires *iterator for the parameter. However, with ptr_map *iterator returns a reference to the element value instead of the key/value pair. Normally this is fine (in general code I like this feature)
Yikes, this sounds like a gratuitous inconsistency with the standard map semantics, and not one that's "obviously better" than the standard one. Why be inventive here? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Bill Buklis"
writes: The predicate for std::find_if requires *iterator for the parameter. However, with ptr_map *iterator returns a reference to the element value instead of the key/value pair. Normally this is fine (in general code I like this feature)
Yikes, this sounds like a gratuitous inconsistency with the standard map semantics, and not one that's "obviously better" than the standard one. Why be inventive here?
well, the general idea of the library is to hide direct access to the pointers. its shows up most in ptr_map. the alternative would be to return a "pair-proxy" from operator*(). -Thorsten

Thorsten Ottosen
David Abrahams wrote:
"Bill Buklis"
writes: The predicate for std::find_if requires *iterator for the parameter. However, with ptr_map *iterator returns a reference to the element value instead of the key/value pair. Normally this is fine (in general code I like this feature)
Yikes, this sounds like a gratuitous inconsistency with the standard map semantics, and not one that's "obviously better" than the standard one. Why be inventive here?
well, the general idea of the library is to hide direct access to the pointers. its shows up most in ptr_map.
the alternative would be to return a "pair-proxy" from operator*().
a tuple of references would work nicely, neh? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Thorsten Ottosen
writes: David Abrahams wrote:
"Bill Buklis"
writes: The predicate for std::find_if requires *iterator for the parameter. However, with ptr_map *iterator returns a reference to the element value instead of the key/value pair. Normally this is fine (in general code I like this feature)
Yikes, this sounds like a gratuitous inconsistency with the standard map semantics, and not one that's "obviously better" than the standard one. Why be inventive here?
well, the general idea of the library is to hide direct access to the pointers. its shows up most in ptr_map.
the alternative would be to return a "pair-proxy" from operator*().
a tuple of references would work nicely, neh?
I guess it would. Do we want to break code to introduce this? -Thorsten

Thorsten Ottosen
David Abrahams wrote:
a tuple of references would work nicely, neh?
I guess it would.
Do we want to break code to introduce this?
If by "we" you mean me, then yes. Better to break it now, after only one full release of the library, than to live with a mis-design forevermore. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (3)
-
Bill Buklis
-
David Abrahams
-
Thorsten Ottosen