Boost logo

Boost :

From: nbecker_at_[hidden]
Date: 2001-03-27 13:50:26


In the field of signal processing it is often necessary to interface
between algorithms that expect complex vs. scalar vectors as
arguments. To prevent unnecessary copying it is nice to use iterator
adaptors to interface between them.

Here is my own primitive attempt. Perhaps someone can improve on it:

ComplexAdapt.H

#ifndef ComplexAdapt_H
#define ComplexAdapt_H

#include <complex>
#include <cstddef>
#include <stdexcept>

template<class T, class ComplexIterator>
class ComplexToRealAdapt {
private:
  ComplexIterator I;
public:
  typedef T value_type;
  typedef ComplexToRealAdapt self;
  typedef ptrdiff_t difference_type;
  typedef size_t size_type;
  typedef iterator_traits<ComplexIterator>::iterator_category iterator_category;
  typedef T* pointer;
  typedef T& reference;

  //! STL wants this
  ComplexToRealAdapt () {}

  ComplexToRealAdapt (ComplexIterator C) :
    I (C)
  {}

  value_type operator*() const {
    return real (*I);
  }

  self& operator++ () {
    I++;
    return *this;
  }

  self operator++ (int) {
    self tmp = *this;
    ++*this;
    return tmp;
  }

  self& operator-- () {
    I--;
    return *this;
  }

  self operator-- (int) {
    self tmp = *this;
    --*this;
    return tmp;
  }

  self& operator+=(difference_type n) {
    I += n;
    return *this;
  }

  self& operator-=(difference_type n) { return *this += -n; }

  self operator+(difference_type n) const {
    self tmp = *this;
    return tmp += n;
  }

  value_type operator[](difference_type n) const { return *(*this + n); }

  bool operator==(const self& x) const { return I == x.I; }

  bool operator!=(const self& x) const { return !(*this == x); }

  difference_type operator- (const self& x) const {
      return I - x.I;
  }

};

template<class T, class ComplexIterator>
class ComplexToImagAdapt {
private:
  ComplexIterator I;
public:
  typedef T value_type;
  typedef ComplexToImagAdapt self;
  typedef ptrdiff_t difference_type;
  typedef size_t size_type;
  typedef iterator_traits<ComplexIterator>::iterator_category iterator_category;
  typedef T* pointer;
  typedef T& reference;

  ComplexToImagAdapt (ComplexIterator C) :
    I (C)
  {}

  value_type operator*() const {
    return imag (*I);
  }

  self& operator++ () {
    I++;
    return *this;
  }

  self operator++ (int) {
    self tmp = *this;
    ++*this;
    return tmp;
  }

  self& operator-- () {
    I--;
    return *this;
  }

  self operator-- (int) {
    self tmp = *this;
    --*this;
    return tmp;
  }

  self& operator+=(difference_type n) {
    I += n;
    return *this;
  }

  self& operator-=(difference_type n) { return *this += -n; }

  self operator+(difference_type n) const {
    self tmp = *this;
    return tmp += n;
  }

  value_type operator[](difference_type n) const { return *(*this + n); }

  bool operator==(const self& x) const { return I == x.I; }

  bool operator!=(const self& x) const { return !(*this == x); }

  difference_type operator- (const self& x) const {
      return I - x.I;
  }

};

template<class T, class RealIterator, class ImagIterator>
class RealToComplexAdapt {
private:
  RealIterator rI;
  ImagIterator iI;
public:
  typedef complex<T> value_type;
  typedef RealToComplexAdapt self;
  typedef ptrdiff_t difference_type;
  typedef size_t size_type;
  // I guess we just have to pick one
  typedef iterator_traits<RealIterator>::iterator_category iterator_category;
  typedef const complex<T>* pointer;
  typedef const complex<T>& reference;

  RealToComplexAdapt (RealIterator _rI, ImagIterator _iI) :
    rI (_rI),
    iI (_iI)
  {}

  value_type operator*() const {
    return complex<T> (*rI, *iI);
  }

  self& operator++() {
    rI++;
    iI++;
    return *this;
  }

  self operator++ (int) {
    self tmp = *this;
    ++*this;
    return tmp;
  }

  self& operator-- () {
    rI--;
    iI--;
    return *this;
  }

  self operator-- (int) {
    self tmp = *this;
    --*this;
    return tmp;
  }

  self& operator+=(difference_type n) {
    rI += n;
    iI += n;
    return *this;
  }

  self& operator-=(difference_type n) { return *this += -n; }

  self operator+(difference_type n) const {
    self tmp = *this;
    return tmp += n;
  }

  value_type operator[](difference_type n) const { return *(*this + n); }

  bool operator==(const self& x) const { return rI == x.rI && iI == x.iI; }

  bool operator!=(const self& x) const { return !(*this == x); }

  difference_type operator- (const self& x) const {
    if (iI - x.iI != rI - x.rI)
      throw invalid_argument ("RealToComplexAdapt");
    return iI - x.iI;
  }

};

#endif


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