Boost logo

Boost Users :

Subject: Re: [Boost-users] Implementing python's enumerate with iterator adaptors
From: Jens Auer (jensa_at_[hidden])
Date: 2012-04-17 10:01:26


Thanks for pointing at the bug. Can you give me the bug number so I can check if it is solved in boost version I am using? I used boost 1.48 with g++ and 1.46 with msvc.

And sorry for the html mail, I normally have Outlook configured to not send html but standard txt, I don't why this was active. If anybody is interested, here is the source code as text. I have also corrected the bug in equal().

#include <utility>

#include <boost/iterator/iterator_adaptor.hpp>

namespace Iterator
{
template<typename T, typename X>
struct Enumerated
{
   Enumerated(T i, X x):
      count(i),
      value(x)
   {

   }

   T count;
   X value;
};

template< typename Iterator, typename T = typename Iterator::difference_type>
class Enumerator:
   public boost::iterator_adaptor<Enumerator<Iterator, T>,
                                  Iterator,
                                  Enumerated<T, typename Iterator::value_type>,
                                  boost::use_default,
                                  Enumerated<T, typename Iterator::reference> >
{
public:
   Enumerator():
      mCount(),
      mPos(),
      mStep()
   {

   }

   template<typename It>
   explicit Enumerator(It i, T start=T(), T step=T(1) ):
      mCount(start),
      mPos(i),
      mStep(step)
   {

   }

private:
   friend class boost::iterator_core_access;

   Enumerated<T, typename Iterator::reference > dereference() const
   {
      return Enumerated<T, typename Iterator::reference >(mCount, *mPos);
   }

   Enumerated<T, typename Iterator::reference > dereference()
   {
      return Enumerated<T, typename Iterator::reference >(mCount, mPos);
   }

   bool equal(Enumerator<Iterator, T> const& other) const
   {
      return mPos == other.mPos;
   }

   void increment()
   {
      mCount += mStep;
      mPos += 1;
   }

   void decrement()
   {
      mCount -= mStep;
      mPos -= 1;
   }

   void advance(typename Iterator::difference_type step)
   {
      mCount += step * mStep;
      mPos += step;
   }

   typename Iterator::difference_type distance_to(Enumerator<Iterator, T> const& other) const
   {
      return std::distance(mPos, other.mPos);
   }

   T mCount;
   Iterator mPos;
   typename Iterator::difference_type mStep;
};

template<typename Iterator, typename T>
Enumerator<Iterator, T> enumerate(Iterator i, T start=0, T step=1)
{
   return Enumerator<Iterator, T>(i, start, step);
}

#include <vector>
#include <iostream>
#include <algorithm>

void foo()
{
   std::vector<int> v;

   auto i = Iterator::enumerate(v.begin(), 0, 1);
   auto j = Iterator::enumerate(v.end(), 0, 1);
   
   std::for_each(i, j, [](decltype(*i) const& x)
   {
      std::cout << x.count << ", " << x.value << std::endl;
   } );
   
   auto y = i->count;
   auto z = i->value;
}
-----Ursprüngliche Nachricht-----
Von: boost-users-bounces_at_[hidden] [mailto:boost-users-bounces_at_[hidden]] Im Auftrag von Mateusz Loskot
Gesendet: Dienstag, 17. April 2012 15:21
An: boost-users_at_[hidden]
Betreff: Re: [Boost-users] Implementing python's enumerate with iterator adaptors

On 17 April 2012 13:03, Jens Auer <jensa_at_[hidden]> wrote:
>    bool equal(Enumerator<Iterator, T> const& other) const
>
>    {
>
>       return mPos == mPos;
>
>    }

You likely have a bug above, should read other.mPos.


> My second problem can be reproduced with the following sample program
> on both msvc and g++:
>
>
>
> #include <vector>
>
> #include <iostream>
>
> #include <algorithm>
>
>
>
> void foo()
>
> {
>
>    std::vector<int> v;
>
>
>
>    auto i = Iterator::enumerate(v.begin(), 0, 1);
>
>
>
>    auto y = i->count;
>
>    auto z = i->value;
>
> }
>
> MSVC:
>
> Error      3             error C2664: 'boost::implicit_cast' : cannot
> convert parameter 1 from 'Iterator::Enumerated<T,X> *' to
> 'boost::detail::operator_arrow_proxy<T>'         c:\software
> development\externals\include\boost\iterator\iterator_facade.hpp  326
>
>
>
> G++:
>
> In file included from
> /usr/include/boost/iterator/iterator_adaptor.hpp:15:0,
>
>                  from Enumerate.h:18,
>
>                  from Enumerate.cpp:1:
>
> /usr/include/boost/iterator/iterator_facade.hpp: In static member
> function 'static boost::detail::operator_arrow_result<ValueType,
> Reference,
> Pointer>::type boost::detail::operator_arrow_result<ValueType,
> Pointer>Reference,
> Pointer>::make(Reference) [with ValueType = Iterator::Enumerated<int,
> Pointer>int>,
> Reference = Iterator::Enumerated<int, int&>, Pointer =
> Iterator::Enumerated<int, int>*,
> boost::detail::operator_arrow_result<ValueType, Reference,
> Pointer>::type = boost::detail::operator_arrow_proxy<Iterator::Enumerated<int, int> >]':
>
> /usr/include/boost/iterator/iterator_facade.hpp:648:49:   instantiated
> from 'boost::iterator_facade<I, V, TC, R, D>::pointer
> boost::iterator_facade<I, V, TC, R, D>::operator->() const [with
> Derived = Iterator::Enumerator<__gnu_cxx::__normal_iterator<int*,
> std::vector<int> >,
> int>, Value = Iterator::Enumerated<int, int>, CategoryOrTraversal =
> boost::random_access_traversal_tag, Reference =
> Iterator::Enumerated<int, int&>, Difference = int,
> boost::iterator_facade<I, V, TC, R, D>::pointer = boost::detail::operator_arrow_proxy<Iterator::Enumerated<int, int> >]'
>
> Enumerate.cpp:27:14:   instantiated from here
>
> /usr/include/boost/iterator/iterator_facade.hpp:327:49: error: no
> matching function for call to 'implicit_cast(Iterator::Enumerated<int, int&>*)'

It seems you haven't specified what version of Boost you are using.
I suppose you are hitting bug fixed a few months ago.

Try with Boost trunk and the second program should compile.

I haven't checked the first use case issue though.

(FYI, There is no need to post in HTML to public mailing lists. If it wasn't in HTML, your code above would have been well formatted.)

Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net _______________________________________________
Boost-users mailing list
Boost-users_at_[hidden]
http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net