Re[16]: Являются ли макросы свидетельством недостаточной выр
От: Кодт Россия  
Дата: 02.08.07 09:49
Оценка: 34 (1)
Здравствуйте, VladD2, Вы писали:

FR>>>>На C++ шаблонах такое пишется без проблем, используются ленивые вычиления, то есть выражение собирается в operator= скорость не уступает сишной.

VD>>>Решение конечно на шаблонах с применением Буста?
FR>>На шаблонах без буста. Я такой велосипед писал когда про буст еще не слышал.
VD>Дык, изобрази... посмеемся вместе.

Вот очень грубый эскиз
// исходный контейнер
struct vector
{
    int size() const;
    double operator[](int) const;
    double& at(int);
    
    template<class V> operator=(const V& v)
    {
        for(int i=0, n=size(); i!=n; ++i)
            at(i) = v[i];
    }
};

// ленивая арифметика: кирпичики
template<class V> struct vmul_t
{
    const V& v; double m;
    vmul_t(const V& v, double m) : v(v), m(m) {}
    double operator[](int i) const { return v[i]*m; }
};
template<class V>
    vmul_t<V>
        vmul(const V& v, double m) { return vmul_t<V>(v,m); }

template<class V1, class V2> struct vsum_t
{
    const V1& v1; const V2& v2;
    vsum_t(const V1& v1, const V2& v2) : v1(v1), v2(v2) {}
    double operator[](int i) const { return v1[i]+v2[i]; }
};
template<class V1, class V2>
    vsum_t<V1,V2>
        vsum(const V1& v1, const V2& v2) { return vsum_t<V1,V2>(v1,v2); }

// обёртка над кирпичиками позволяет избежать комбинаторного взрыва
template<class V> struct vid_t
{
    const V& v;
    vid_t(const V& v) : v(v) {}
    double operator[](int i) const { return v[i]; }
};
template<class V>
    vid_t<V>
        vid(const V& v) { return vid_t<V>(v); }

// строим выражения: сперва с участием конкретных типов слева (вектор, число)

template<class V>
    vid_t<vmul_t<V> >
        operator* (double m, const V& v) { return vid(vmul(v,m)); }

    vid_t<vmul_t<vector> >
        operator* (const vector& v, double m) { return vid(vmul(v,m)); }
    vid_t<vmul_t<vector> >
        operator/ (const vector& v, double m) { return vid(vmul(v,1/m)); }

template<class V2>
    vid_t<vsum_t<vector,V2> >
        operator+ (const vector& v1, const V2& v2) { return vid(vsum(v1,v2)); }
template<class V2>
    vid_t<vsum_t<vector,vmul_t<V2> > >
        operator- (const vector& v1, const V2& v2) { return vid(vsum(v1,vmul(v2,-1))); }

// а теперь слева шаблон vid_t

template<class V>
    vid_t<vmul_t<V> >
        operator* (const vid_t<V>& v, double m) { return vid(vmul(v,m)); }
template<class V>
    vid_t<vmul_t<V> >
        operator/ (const vid_t<V>& v, double m) { return vid(vmul(v,1/m)); }

template<class V1, class V2>
    vid_t<vsum_t<V1,V2> >
        operator+ (const vid_t<V>& v1, const V2& v2) { return vid(vsum(v1,v2)); }
template<class V1, class V2>
    vid_t<vsum_t<V1,vmul_t<V2> > >
        operator- (const vid_t<V>& v1, const V2& v2) { return vid(vsum(v1,vmul(v2,-1))); }


Здесь можно добавить следующие вещи:
1) избавиться от лишней косвенности (т.е. снимать обёртку)
template<class V> struct clean_t { typedef V type; };
template<class V> struct clean_t<vid_t<V> > { typedef V type; };

template<class V> const V& clean(const V& v) { return v; }
template<class V> const V& clean(const vid_t<V>& v) { return v.v; }

// и пропатчить все операторы вот так:

template<class V1, class V2>
    vid_t<vsum_t<typename clean_t<V1>::type, typename clean_t<V2>::type> >
        operator+ (const vid_t<V>& v1, const V2& v2) { return vid(vsum(clean(v1), clean(v2)); }

2) протащить через выражения не только operator[], но и функцию size()
3) сделать нормальное деление и вычитание вместо эмуляции на сложении и умножении
и т.д. и т.п.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.