vendredi 3 février 2017

Implementing views on a std::vector

Goal:

  • Wrap a vector. The wrapper can create view on part of the vector.
  • Support const_view and view.
  • view allows modification of elements while const_view does not.
  • The views are ranges (has begin() and end() methods).

Problem:

  • Code duplication between the const_view and view.

Simplified Code:

#include <vector>
class A_csub;
class A_sub;

typedef std::vector<int> V;
typedef typename V::iterator It;
typedef typename V::const_iterator Cit;

class A {
public:
    A(const int r, const int c);
    A_csub cview(const int n) const;
    A_sub view(const int n);
    It sub_begin(const int n);
    Cit sub_cbegin(const int n) const;
    int _r;
    int _c;
private:
    V _v;
};

class A_csub {
public:
    A_csub(const A& a, const int n);
    Cit begin() const;
    Cit end() const;
    const int size() const;
private:
    const A& _a;
    const int _n;
};

class A_sub {
public:
    A_sub(A& a, const int n);
    It begin();
    It end();
    const int size() const;
private:
    A& _a;
    const int _n;
};

// -- A -- //
A::A(const int r, const int c) : _r(c), _c(c), _v(r*c) {}
A_csub A::cview(const int n) const { return A_csub(*this, n); }
A_sub A::view(const int n) { return A_sub(*this, n); }
It A::sub_begin(const int n) { return _v.begin() + n*_r; }
Cit A::sub_cbegin(const int n) const { return _v.cbegin() + n*_r; }

// -- A_csub -- //
A_csub::A_csub(const A& a, const int n) : _a(a), _n(n) {}
Cit A_csub::begin() const { return _a.sub_cbegin(_n); }
Cit A_csub::end() const { return begin() + _a._r; }
const int A_csub::size() const { return _a._r; }

// -- A_sub -- //
A_sub::A_sub(A& a, const int n) : _a(a), _n(n) {}
It A_sub::begin() { return _a.sub_begin(_n); }
It A_sub::end() { return begin() + _a._r; }
const int A_sub::size() const { return _a._r; }

int main() {
    A a(10,5);
    a.cview(4);
    A_sub b = a.view(4);
    for (auto && e:b) {e=1;}
}

Aucun commentaire:

Enregistrer un commentaire