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
pgp00000.pgp
Description: signature