|
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