[iterator] Proposal to add is_const_iterator trait

Hello, Quite often I find myself writing an is_const_iterator trait which looks like this: //! A helper traits to check if an iterator is const template< typename ItT > struct is_const_iterator : public is_const< typename remove_reference< typename iterator_reference< ItT >::type >::type > { }; Maybe it is worth adding to Boost.Iterators library? Or maybe there already is something like that? -- Best regards, Andrey mailto:andysem@mail.ru

on Tue May 08 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello,
Quite often I find myself writing an is_const_iterator trait which looks like this:
//! A helper traits to check if an iterator is const template< typename ItT > struct is_const_iterator : public is_const< typename remove_reference< typename iterator_reference< ItT >::type >::type > { };
Maybe it is worth adding to Boost.Iterators library? Or maybe there already is something like that?
What's it useful for? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com

Hello David, Wednesday, May 9, 2007, 8:27:53 PM, you wrote:
on Tue May 08 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello,
Quite often I find myself writing an is_const_iterator trait which looks like this:
[snip]
Maybe it is worth adding to Boost.Iterators library? Or maybe there already is something like that?
What's it useful for?
Mostly I used it to implement my iterators for some adopted STL-like containers. It shortens the iterator_facade template parameters list: template< NodeItT > struct MyIterator : public iterator_facade< MyIterator< NodeItT >, typename mpl::if_< is_const_iterator< NodeItT >, const value_type, value_type >::type, typename iterator_category< NodeItT >::type > { }; Here NodeItT is an adopted container iterator (const or not). It iterates over nodes that are not value_type. MyIterator extracts value_types from nodes on dereferencing (this logic may be tricky). Another use case is different iterators translation to each other. It came handy when I had to implement something like multi_index_container iterator projecting: template< int Index, typename SrcItT > typename mpl::if_< is_const_iterator< SrcItT >, typename nth_index< Index >::const_iterator, typename nth_index< Index >::iterator
::type project(SrcItT it);
-- Best regards, Andrey mailto:andysem@mail.ru

on Wed May 09 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello David,
Wednesday, May 9, 2007, 8:27:53 PM, you wrote:
on Tue May 08 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello,
Quite often I find myself writing an is_const_iterator trait which looks like this:
[snip]
Maybe it is worth adding to Boost.Iterators library? Or maybe there already is something like that?
What's it useful for?
Mostly I used it to implement my iterators for some adopted STL-like containers. It shortens the iterator_facade template parameters list:
template< NodeItT > struct MyIterator : public iterator_facade< MyIterator< NodeItT >, typename mpl::if_< is_const_iterator< NodeItT >, const value_type, value_type >::type, typename iterator_category< NodeItT >::type > { };
Is there some good reason you're not using iterator_adaptor here? This looks like a classic use case for it. That would eliminate the need for is_const_iterator in this case.
Another use case is different iterators translation to each other. It came handy when I had to implement something like multi_index_container iterator projecting:
template< int Index, typename SrcItT > typename mpl::if_< is_const_iterator< SrcItT >, typename nth_index< Index >::const_iterator, typename nth_index< Index >::iterator
::type project(SrcItT it);
I see. Well, I'm ambivalent. To me it doesn't look like that particular use case is worth doing much work to extend the library for, but if you can supply the implementation along with doc patches and tests, I guess I would be inclined to accept them. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com

Hello David, Thursday, May 10, 2007, 2:49:56 PM, you wrote:
on Wed May 09 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello David,
Wednesday, May 9, 2007, 8:27:53 PM, you wrote:
on Tue May 08 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello,
Quite often I find myself writing an is_const_iterator trait which looks like this:
[snip]
Maybe it is worth adding to Boost.Iterators library? Or maybe there already is something like that?
What's it useful for?
Mostly I used it to implement my iterators for some adopted STL-like containers. It shortens the iterator_facade template parameters list:
template< NodeItT > struct MyIterator : public iterator_facade< MyIterator< NodeItT >, typename mpl::if_< is_const_iterator< NodeItT >, const value_type, value_type >::type, typename iterator_category< NodeItT >::type > { };
Is there some good reason you're not using iterator_adaptor here? This looks like a classic use case for it. That would eliminate the need for is_const_iterator in this case.
Well... I guess I could use iterator_adaptor in some cases and I can't remember why I didn't in other. Thanks for the pointer.
Another use case is different iterators translation to each other. It came handy when I had to implement something like multi_index_container iterator projecting:
template< int Index, typename SrcItT > typename mpl::if_< is_const_iterator< SrcItT >, typename nth_index< Index >::const_iterator, typename nth_index< Index >::iterator
::type project(SrcItT it);
I see. Well, I'm ambivalent. To me it doesn't look like that particular use case is worth doing much work to extend the library for, but if you can supply the implementation along with doc patches and tests, I guess I would be inclined to accept them.
I agree that the case is rather specific, though I think such template could still be handy here and there. Since I don't have any striking examples of use right now and a little bit short in time, I'll leave it to some day when I have either of them. :) -- Best regards, Andrey mailto:andysem@mail.ru

Hello David, Thursday, May 10, 2007, 2:49:56 PM, you wrote:
on Wed May 09 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello David,
Wednesday, May 9, 2007, 8:27:53 PM, you wrote:
on Tue May 08 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello,
Quite often I find myself writing an is_const_iterator trait which looks like this:
[snip]
Maybe it is worth adding to Boost.Iterators library? Or maybe there already is something like that?
What's it useful for?
Mostly I used it to implement my iterators for some adopted STL-like containers. It shortens the iterator_facade template parameters list:
template< NodeItT > struct MyIterator : public iterator_facade< MyIterator< NodeItT >, typename mpl::if_< is_const_iterator< NodeItT >, const value_type, value_type >::type, typename iterator_category< NodeItT >::type > { };
Is there some good reason you're not using iterator_adaptor here? This looks like a classic use case for it. That would eliminate the need for is_const_iterator in this case.
I apologize for returning to this, but as I'm reading the docs and looking at my use cases I have before me I don't see how would I elide is_const_iterator when using iterator_adaptor. Suppose this: template< typename ValueT > class MyList { public: typedef ValueT value_type; // etc. all other common typedefs except iterators private: struct MyNode { ValueT value; int m_SomeOtherData; }; typedef std::list< MyNode > underlying_container; template< typename > class MyIterator; public: typedef MyIterator< typename underlying_container::iterator > iterator; typedef MyIterator< typename underlying_container::const_iterator > const_iterator; private: template< typename ItT > class MyIterator : public iterator_adaptor< MyIterator< ItT >, ItT, value_type, // I have to substitute value type use_default, // Category fits well ??? // What should I write for reference type? // I've provided value type, so value_type& // is not valid when ItT is const_iterator > { typedef typename iterator_adaptor< ... >::reference reference; reference dereference() { return this->base()->value; } }; }; So, once again I have to detect ItT constness and form up the correct reference type for the iterator_adaptor. Am I missing something? -- Best regards, Andrey mailto:andysem@mail.ru

on Sat May 12 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello David,
<please avoid overquoting>
I apologize for returning to this, but as I'm reading the docs and looking at my use cases I have before me I don't see how would I elide is_const_iterator when using iterator_adaptor. Suppose this:
template< typename ValueT > class MyList { public: typedef ValueT value_type;
// etc. all other common typedefs except iterators
private: struct MyNode { ValueT value; int m_SomeOtherData; }; typedef std::list< MyNode > underlying_container;
template< typename > class MyIterator;
public: typedef MyIterator< typename underlying_container::iterator > iterator;
typedef MyIterator< typename underlying_container::const_iterator > const_iterator;
private: template< typename ItT > class MyIterator : public iterator_adaptor< MyIterator< ItT >, ItT, value_type, // I have to substitute value type
No, just leave it out. The default works.
use_default, // Category fits well ??? // What should I write for reference type? // I've provided value type, so value_type& // is not valid when ItT is const_iterator
Just leave it out. The default works.
> { typedef typename iterator_adaptor< ... >::reference reference;
reference dereference() { return this->base()->value; } }; };
So, once again I have to detect ItT constness and form up the correct reference type for the iterator_adaptor. Am I missing something?
...unless I'm missing something. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com

----- Mensaje original ----- De: David Abrahams <dave@boost-consulting.com> Fecha: Domingo, Mayo 13, 2007 0:16 am Asunto: Re: [boost] [iterator] Proposal to add is_const_iterator trait Para: boost@lists.boost.org
on Sat May 12 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
[...]
I apologize for returning to this, but as I'm reading the docs and looking at my use cases I have before me I don't see how would I elide is_const_iterator when using iterator_adaptor. Suppose this:
template< typename ValueT > class MyList { public: typedef ValueT value_type;
// etc. all other common typedefs except iterators
private: struct MyNode { ValueT value; int m_SomeOtherData; }; typedef std::list< MyNode > underlying_container;
template< typename > class MyIterator;
public: typedef MyIterator< typename underlying_container::iterator > iterator;
typedef MyIterator< typename underlying_container::const_iterator > const_iterator;
private: template< typename ItT > class MyIterator : public iterator_adaptor< MyIterator< ItT >, ItT, value_type, // I have to substitute value type
No, just leave it out. The default works.
I think this is the crux of the matter. value_type is *not* the same type as underlying_container::value_type. I think Andrey has a valid point here. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

on Sat May 12 2007, "JOAQUIN LOPEZ MU?Z" <joaquin-AT-tid.es> wrote:
I think this is the crux of the matter. value_type is *not* the same type as underlying_container::value_type. I think Andrey has a valid point here.
OK, great, then I support the inclusion of this trait. We just need tests and docs :) -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com

Hello David, Sunday, May 13, 2007, 5:21:59 AM, you wrote:
on Sat May 12 2007, "JOAQUIN LOPEZ MU?Z" <joaquin-AT-tid.es> wrote:
I think this is the crux of the matter. value_type is *not* the same type as underlying_container::value_type. I think Andrey has a valid point here.
OK, great, then I support the inclusion of this trait. We just need tests and docs :)
Here it is in the Vault: http://tinyurl.com/2z56r2 I'm not sure I did the right thing with the docs since I never had experience with these rst things. Of course, you are free to do it the right way if I did something wrong. All patches should be applied to HEAD. The test passed for VC8 SP1 and GCC 4.1.2 on Cygwin for me. -- Best regards, Andrey mailto:andysem@mail.ru

Andrey Semashev wrote:
Hello David,
Sunday, May 13, 2007, 5:21:59 AM, you wrote:
on Sat May 12 2007, "JOAQUIN LOPEZ MU?Z" <joaquin-AT-tid.es> wrote:
I think this is the crux of the matter. value_type is *not* the same type as underlying_container::value_type. I think Andrey has a valid point here.
OK, great, then I support the inclusion of this trait. We just need tests and docs :)
Here it is in the Vault:
What does 'is_const' for iterators mean? The New Iterator concept defines Readable and Writable concept, but I don't know the definition of "constant" iterator. Well, I think 'iterator_reference<ItT>::type' can return a const-qualified type even if 'ItT' is Writable. -- Shunsuke Sogame

Hello shunsuke, Monday, May 14, 2007, 3:31:29 AM, you wrote:
Here it is in the Vault:
What does 'is_const' for iterators mean?
As the patched doc says, the trait returns true if the result of iterator dereference is constant reference and false otherwise. is_const_iterator< str::list< int >::const_iterator >::value == true is_const_iterator< str::list< int >::iterator >::value == false
The New Iterator concept defines Readable and Writable concept, but I don't know the definition of "constant" iterator. Well, I think 'iterator_reference<ItT>::type' can return a const-qualified type even if 'ItT' is Writable.
I don't see how would it be possible to write to a const. -- Best regards, Andrey mailto:andysem@mail.ru

Andrey Semashev wrote:
The New Iterator concept defines Readable and Writable concept, but I don't know the definition of "constant" iterator. Well, I think 'iterator_reference<ItT>::type' can return a const-qualified type even if 'ItT' is Writable.
I don't see how would it be possible to write to a const.
Proxy object like vector<bool>? -- Shunsuke Sogame

Hello shunsuke, Monday, May 14, 2007, 1:58:37 PM, you wrote:
Andrey Semashev wrote:
The New Iterator concept defines Readable and Writable concept, but I don't know the definition of "constant" iterator. Well, I think 'iterator_reference<ItT>::type' can return a const-qualified type even if 'ItT' is Writable.
I don't see how would it be possible to write to a const.
Proxy object like vector<bool>?
Dereferencing its iterators yelds rvalues which are not const (at least are not required to be). It is, in fact, possible to create a non-const iterator which has a const reference type, but such cases are, uh, a bit strange to say the least. Currently is_const_iterator will result to true only if the iterator reference type is const value or const reference. I'm not sure how it should behave for iterators with a non-const value reference types and vector< bool >::iterator specifically. I'm leaving this to users to define by specializing is_const_iterator on their iterator types. Maybe there should exist specialization on vector< bool >::const_iterator right out of the box? -- Best regards, Andrey mailto:andysem@mail.ru

Andrey Semashev wrote:
Currently is_const_iterator will result to true only if the iterator reference type is const value or const reference. I'm not sure how it should behave for iterators with a non-const value reference types and vector< bool >::iterator specifically. I'm leaving this to users to define by specializing is_const_iterator on their iterator types. Maybe there should exist specialization on vector< bool >::const_iterator right out of the box?
I'm not sure, but this is an interesting question: Is it feasible to detect the writability of iterator using some language magic? If not, is_const_iterator can be a practical workarond. Well, I looked at the 'MyList' example. 'transform_iterator' could not be used? Regards, -- Shunsuke Sogame

Hello shunsuke, Monday, May 14, 2007, 5:05:46 PM, you wrote:
Andrey Semashev wrote:
Currently is_const_iterator will result to true only if the iterator reference type is const value or const reference. I'm not sure how it should behave for iterators with a non-const value reference types and vector< bool >::iterator specifically. I'm leaving this to users to define by specializing is_const_iterator on their iterator types. Maybe there should exist specialization on vector< bool >::const_iterator right out of the box?
I'm not sure, but this is an interesting question: Is it feasible to detect the writability of iterator using some language magic? If not, is_const_iterator can be a practical workarond.
The more I think of it the more I like the following solution: - Make it fail to compile if dereferencing the iterator yelds a non-reference type - Provide specializations for vector< bool > iterators - Add a note to the library docs about that But I'd like to see what Dave thinks about it, as the library author.
Well, I looked at the 'MyList' example. 'transform_iterator' could not be used?
Theoretically it could. But it seems to me a too heavy solution. The iterator would contain a functor, which: a) I don't need b) either may be of unknown type (in case of bind or lambda expressions) or is an additional class which I find very inconvenient. To my mind, transform_iterator is handy when you want to provide a view of the container to some algorithm from your (user's) code. It is an overkill to use it as a part of a container implementation (library code). -- Best regards, Andrey mailto:andysem@mail.ru

Andrey Semashev wrote:
To my mind, transform_iterator is handy when you want to provide a view of the container to some algorithm from your (user's) code. It is an overkill to use it as a part of a container implementation (library code).
You suggested compressed_transform_iterator using EBO? :-) Regards, -- Shunsuke Sogame

Hello shunsuke, Monday, May 14, 2007, 11:57:12 PM, you wrote:
Andrey Semashev wrote:
To my mind, transform_iterator is handy when you want to provide a view of the container to some algorithm from your (user's) code. It is an overkill to use it as a part of a container implementation (library code).
You suggested compressed_transform_iterator using EBO? :-)
Hm, no, I didn't. Though such improvement of transform_iterator would be great. -- Best regards, Andrey mailto:andysem@mail.ru

on Sun May 13 2007, shunsuke <pstade.mb-AT-gmail.com> wrote:
Andrey Semashev wrote:
Hello David,
Sunday, May 13, 2007, 5:21:59 AM, you wrote:
on Sat May 12 2007, "JOAQUIN LOPEZ MU?Z" <joaquin-AT-tid.es> wrote:
I think this is the crux of the matter. value_type is *not* the same type as underlying_container::value_type. I think Andrey has a valid point here.
OK, great, then I support the inclusion of this trait. We just need tests and docs :)
Here it is in the Vault:
What does 'is_const' for iterators mean?
Well, good question. It should be "is_constant_iterator -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com

Hello David,
Well, good question. It should be "is_constant_iterator
I finally got my hands on it. The updated version is available with the same link: http://tinyurl.com/2z56r2 Changes are: - Renamed to is_constant_iterator - The trait does not compile if applied to an iterator whose reference type is not a reference. - std::vector< bool > iterators are supported, though - Docs and tests update I'm not sure what should I do next. Does this humble addition need some kind of review? -- Best regards, Andrey mailto:andysem@mail.ru

on Sun May 27 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello David,
Well, good question. It should be "is_constant_iterator
I finally got my hands on it. The updated version is available with the same link:
Changes are: - Renamed to is_constant_iterator - The trait does not compile if applied to an iterator whose reference type is not a reference. - std::vector< bool > iterators are supported, though - Docs and tests update
I'm not sure what should I do next. Does this humble addition need some kind of review?
Post the patches to the svn.boost.org. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

Hello David, Thursday, May 31, 2007, 4:06:42 AM, you wrote:
on Sun May 27 2007, Andrey Semashev <andysem-AT-mail.ru> wrote:
Hello David,
Well, good question. It should be "is_constant_iterator
I finally got my hands on it. The updated version is available with the same link:
Changes are: - Renamed to is_constant_iterator - The trait does not compile if applied to an iterator whose reference type is not a reference. - std::vector< bool > iterators are supported, though - Docs and tests update
I'm not sure what should I do next. Does this humble addition need some kind of review?
Post the patches to the svn.boost.org.
Done, ticket #1020. -- Best regards, Andrey mailto:andysem@mail.ru
participants (4)
-
"JOAQUIN LOPEZ MU?Z"
-
Andrey Semashev
-
David Abrahams
-
shunsuke