Boost logo

Boost :

From: Neal D. Becker (nbecker_at_[hidden])
Date: 2003-08-06 14:06:46


On Wednesday 06 August 2003 02:38 pm, Thomas Witt wrote:
> gpgkeys: WARNING: this is an *experimental* HKP interface!
> gpgkeys: key D1DB3F812DD7B01A not found on keyserver
>
> Rozental, Gennadiy wrote:
> | What is the problem adapting pair of iterators to scalar vectors to
>
> produce
>
> | an iterator with complex value type?
>
> The problem is you can hardly adapt a pair. So using iterator_adaptor
> (the new class template) does not provide any benefit.
>
> | I am sure both old and new iterator adaptor easily allows it.
>
> As I said before iterator_facade (new) would be the right tool AFAICS.
>
>
> Thomas

This seems to work, but it's klugey. I guess it is an existance proof that
it's possible to do with old iterator adaptors?

1) Since only 1 object can be passed to the iterator adaptor constructor, I
had to pass a pair.

2) Distance uses only one of the base iterators.

3) iterator_category uses only 1 of the iterators.

Can anyone suggest ways to improve this?

The first 2 policies pick off real or imag parts of complex. They are no
problem.

The last 1 combines real and imag into complex. That's where the problems
lie.

#include<boost/iterator_adaptors.hpp>
#include <complex>
#include <utility> // pair
// #include<algorithm>

namespace boost {

  namespace detail{

    template<typename BaseIterator>
    class complex_real_iterator_policy : public default_iterator_policies {

    public:
      // Constructors
      complex_real_iterator_policy (BaseIterator const& _base) :
        base (_base) {}

      template <class IteratorAdaptor>
      typename IteratorAdaptor::reference dereference (IteratorAdaptor& x)
const {
        return real (*x.base());
      }
      
      
    private:

      const BaseIterator& base;
    };

    template<typename BaseIterator>
    class complex_imag_iterator_policy : public default_iterator_policies {

    public:
      // Constructors
      complex_imag_iterator_policy (BaseIterator const& _base) :
        base (_base) {}

      template <class IteratorAdaptor>
      typename IteratorAdaptor::reference dereference (IteratorAdaptor& x)
const {
        return imag (*x.base());
      }
      
      
    private:

      const BaseIterator& base;
    };

    template<typename BaseIterator1, typename BaseIterator2>
    class real_imag_complex_iterator_policy : public default_iterator_policies
{

    public:
      typedef typename std::pair<BaseIterator1, BaseIterator2> base_type;

      // Constructors
      real_imag_complex_iterator_policy (base_type const& _base) :
        base (_base) {}

      template <class IteratorAdaptor>
      typename IteratorAdaptor::reference dereference (IteratorAdaptor& x)
const {
        return typename IteratorAdaptor::value_type (*x.base().first,
*x.base().second);
      }

      template <class IteratorAdaptor>
      void increment(IteratorAdaptor& x)
      { ++x.base().first; ++x.base().second; }
      
      template <class IteratorAdaptor>
      void decrement(IteratorAdaptor& x)
      { --x.base().first; --x.base().second; }

      template <class IteratorAdaptor1, class IteratorAdaptor2>
      typename IteratorAdaptor1::difference_type
      distance(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
      { return y.base().first - x.base().first; }

    private:

      const base_type base;
    };
  } // namespace detail

  template<typename BaseIterator>
  struct complex_real_iterator_generator {
    typedef typename boost::detail::iterator_traits<BaseIterator>::value_type
complex_value_type;
    typedef typename complex_value_type::value_type scalar_value_type;
    typedef
boost::iterator_adaptor<BaseIterator,detail::complex_real_iterator_policy<BaseIterator>,
reference_is<scalar_value_type> > type;
  };

  template<typename BaseIterator>
  typename complex_real_iterator_generator<BaseIterator>::type
  make_complex_real_iterator(BaseIterator const& begin) {
    typedef typename complex_real_iterator_generator<BaseIterator>::type
ret_type;

    return ret_type (begin, detail::complex_real_iterator_policy<BaseIterator>
(begin));
  }

  template<typename BaseIterator>
  struct complex_imag_iterator_generator {
    typedef typename boost::detail::iterator_traits<BaseIterator>::value_type
complex_value_type;
    typedef typename complex_value_type::value_type scalar_value_type;
    typedef
boost::iterator_adaptor<BaseIterator,detail::complex_imag_iterator_policy<BaseIterator>,
reference_is<scalar_value_type> > type;
  };

  template<typename BaseIterator>
  typename complex_imag_iterator_generator<BaseIterator>::type
  make_complex_imag_iterator(BaseIterator const& begin) {
    typedef typename complex_imag_iterator_generator<BaseIterator>::type
ret_type;

    return ret_type (begin, detail::complex_imag_iterator_policy<BaseIterator>
(begin));
  }

  template<typename BaseIterator1, typename BaseIterator2>
  struct real_imag_complex_iterator_generator {
    typedef typename boost::detail::iterator_traits<BaseIterator1>::value_type
scalar_value_type;
    typedef typename std::complex<scalar_value_type> complex_value_type;
    typedef typename std::pair<BaseIterator1, BaseIterator2> pair_type;
    typedef boost::iterator_adaptor<pair_type,
detail::real_imag_complex_iterator_policy<BaseIterator1, BaseIterator2>,
complex_value_type, complex_value_type, complex_value_type*, typename
std::iterator_traits<BaseIterator1>::iterator_category, typename
std::iterator_traits<BaseIterator1>::difference_type > type;
  };

  template<typename BaseIterator1, typename BaseIterator2>
  typename real_imag_complex_iterator_generator<BaseIterator1,
BaseIterator2>::type
  make_real_imag_complex_iterator(BaseIterator1 const& begin1, BaseIterator2
const& begin2) {
    typedef typename real_imag_complex_iterator_generator<BaseIterator1,
BaseIterator2>::type ret_type;
    typedef typename std::pair<BaseIterator1, BaseIterator2> pair_type;

    return ret_type (pair_type (begin1, begin2),
detail::real_imag_complex_iterator_policy<BaseIterator1, BaseIterator2>
(pair_type (begin1, begin2)));
  }
    

} // namespace boost




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk