Commit 5c04d578 authored by Roger Kaeppeli's avatar Roger Kaeppeli

Add week 11

parent 6b488aa0
#include <algorithm> // for std::swap
#include <cassert>
// This class encapsulates the "+" operation.
struct plus {
public:
static inline double apply(double a, double b) {
return a + b;
};
};
// eXpression
template<typename Left,typename Op,typename Right>
class X {
public:
// ctor
X(const Left& x,const Right& y) : left_(x), right_(y) { }
// subscript operator
double operator[](int i) const {
return Op::apply(left_[i], right_[i]);
}
private:
const Left& left_;
const Right& right_;
};
// etvector class
template <typename T>
class etvector {
public:
typedef T value_type;
typedef T& reference;
typedef unsigned int size_type;
// ctor
etvector(size_type s=0) : p_(new value_type[s]), sz_(s) {}
// copy ctor
etvector(const etvector& v) : p_(new value_type[v.size()])
, sz_(v.size()) {
for (int i=0; i<size(); ++i) {
p_[i] = v.p_[i];
}
}
// dtor
~etvector() { delete[] p_;}
// swap
void swap(etvector& v) {
std::swap(p_,v.p_);
std::swap(sz_,v.sz_);
}
// copy assignment
const etvector& operator=(etvector v) {
swap(v);
return *this;
}
// assignment from eXpression object
template <typename L,typename Op,typename R>
const etvector& operator=(const X<L,Op,R>& v) {
for (int i=0;i<size();++i)
p_[i]=v[i];
return *this;
}
// size
size_type size() const { return sz_;}
// subscript operator
value_type operator[](size_type i) const { return p_[i]; }
reference operator[](size_type i) { return p_[i]; }
private:
value_type* p_;
size_type sz_;
};
// binary "+" operator (non-member / free function)
template<typename Left,typename T>
inline X<Left,plus,etvector<T> > operator+(const Left& a
,const etvector<T>& b) {
return X<Left,plus,etvector<T> >(a, b);
}
#include <algorithm> // for std::swap
#include <cassert>
// This class encapsulates the "+" operation.
struct plus {
public:
static inline double apply(double a, double b) {
return a + b;
};
};
// This class encapsulates the "-" operation.
struct minus {
public:
static inline double apply(double a, double b) {
return a - b;
};
};
// This class encapsulates the "*" operation.
struct mult {
public:
static inline double apply(double a, double b) {
return a * b;
};
};
// This class encapsulates the "/" operation.
struct divide {
public:
static inline double apply(double a, double b) {
return a / b;
};
};
// eXpression
template<typename Left,typename Op,typename Right>
class X {
public:
// ctor
X(const Left& x,const Right& y) : left_(x), right_(y) { }
// subscript operator
double operator[](int i) const {
return Op::apply(left_[i], right_[i]);
}
private:
const Left& left_;
const Right& right_;
};
// etvector class
template <typename T>
class etvector {
public:
typedef T value_type;
typedef T& reference;
typedef unsigned int size_type;
// ctor
etvector(size_type s=0) : p_(new value_type[s]), sz_(s) {}
// copy ctor
etvector(const etvector& v) : p_(new value_type[v.size()])
, sz_(v.size()) {
for (int i=0; i<size(); ++i) {
p_[i] = v.p_[i];
}
}
// dtor
~etvector() { delete[] p_;}
// swap
void swap(etvector& v) {
std::swap(p_,v.p_);
std::swap(sz_,v.sz_);
}
// copy assignment
const etvector& operator=(etvector v) {
swap(v);
return *this;
}
// assignment from eXpression object
template <typename L,typename Op,typename R>
const etvector& operator=(const X<L,Op,R>& v) {
for (int i=0;i<size();++i)
p_[i]=v[i];
return *this;
}
// size
size_type size() const { return sz_;}
// subscript operator
value_type operator[](size_type i) const { return p_[i]; }
reference operator[](size_type i) { return p_[i]; }
private:
value_type* p_;
size_type sz_;
};
// binary "+" operator (non-member / free function)
template<typename Left,typename T>
inline X<Left,plus,etvector<T> > operator+(const Left& a
,const etvector<T>& b) {
return X<Left,plus,etvector<T> >(a, b);
}
// binary "-" operator (non-member / free function)
template<typename Left, typename T>
inline X<Left,minus,etvector<T> > operator-(const Left& a
,const etvector<T>& b) {
return X<Left,minus,etvector<T> >(a, b);
}
// binary "*" operator (non-member / free function)
template<typename Left,typename T>
inline X<Left,mult,etvector<T> > operator*(const Left& a
,const etvector<T>& b) {
return X<Left,mult,etvector<T> >(a, b);
}
// binary "/" operator (non-member / free function)
template<typename Left,typename T>
inline X<Left,divide,etvector<T> > operator/(const Left& a
,const etvector<T>& b) {
return X<Left,divide,etvector<T> >(a, b);
}
#include <algorithm> // for std::swap
#include <cassert>
// forward-declare vectorsum class as it is needed in lazyvector class
template <typename T>
class vectorsum;
// lazyvector
template <typename T>
class lazyvector {
public:
typedef T value_type;
typedef T& reference;
typedef unsigned int size_type;
// ctor
lazyvector(size_type s=0) : p_(new value_type[s]),sz_(s) {}
// copy ctor
lazyvector(const lazyvector& v) : p_(new value_type[v.size()])
, sz_(v.size()) {
for (int i=0;i<size();++i) {
p_[i] = v.p_[i];
}
}
// dtor
~lazyvector() { delete[] p_;}
// swap
void swap(lazyvector& v) {
std::swap(p_,v.p_);
std::swap(sz_,v.sz_);
}
// copy assignment
lazyvector& operator=(lazyvector v) {
swap(v);
return *this;
}
// assignment from a vectorsum object
lazyvector& operator=(const vectorsum<T>& v) {
for (int i=0; i<size(); ++i)
p_[i] = v[i];
return *this;
}
// size
size_type size() const { return sz_; }
// subscript operator
value_type operator[](size_type i) const { return p_[i]; }
reference operator[](size_type i) { return p_[i]; }
private:
value_type* p_;
size_type sz_;
};
// vectorsum class
template <typename T>
class vectorsum {
public:
typedef T value_type;
typedef unsigned int size_type;
// ctor
vectorsum(const lazyvector<T>& x,const lazyvector<T>& y) : left_(x)
, right_(y) {}
// subscript operator
value_type operator[](size_type i) const {
return left_[i] + right_[i];
}
private:
const lazyvector<T>& left_;
const lazyvector<T>& right_;
};
// binary "+" operator (non-member / free function)
template <typename T>
inline vectorsum<T> operator+(const lazyvector<T>& x,const lazyvector<T>& y) {
return vectorsum<T>(x,y);
}
#include <algorithm> // for std::swap
#include <cassert>
// This class encapsulates the "+" operation.
struct plus {
public:
static inline double apply(double a, double b) {
return a + b;
};
};
// This class encapsulates the "-" operation.
struct minus {
public:
static inline double apply(double a, double b) {
return a - b;
};
};
// forward-declare vectorsum class as it is needed in lazyvector class
// now also templated on the Operation!
template <typename T,typename Op>
class vectorsum;
// lazyvector
template <typename T>
class lazyvector {
public:
typedef T value_type;
typedef T& reference;
typedef unsigned int size_type;
// ctor
lazyvector(size_type s=0) : p_(new value_type[s]),sz_(s) {}
// copy ctor
lazyvector(const lazyvector& v) : p_(new value_type[v.size()])
, sz_(v.size()) {
for (int i=0;i<size();++i) {
p_[i] = v.p_[i];
}
}
// dtor
~lazyvector() { delete[] p_;}
// swap
void swap(lazyvector& v) {
std::swap(p_,v.p_);
std::swap(sz_,v.sz_);
}
// copy assignment
const lazyvector& operator=(lazyvector v) {
swap(v);
return *this;
}
// assignment from a vectorsum object
template <typename Op>
const lazyvector& operator=(const vectorsum<T,Op>& v) {
for (int i=0;i<size();++i) {
p_[i] = v[i];
}
return *this;
}
// size
size_type size() const { return sz_; }
// subscript operator
value_type operator[](size_type i) const { return p_[i]; }
reference operator[](size_type i) { return p_[i]; }
private:
value_type* p_;
size_type sz_;
};
// vectorsum class
template <typename T,typename Op>
class vectorsum {
public:
typedef unsigned int size_type;
typedef T value_type;
// ctor
vectorsum(const lazyvector<T>& x, const lazyvector<T>& y) : left_(x)
, right_(y) {}
// subscript operator
value_type operator[](size_type i) const {
return Op::apply(left_[i], right_[i]);
}
private:
const lazyvector<T>& left_;
const lazyvector<T>& right_;
};
// binary "+" operator (non-member / free function)
template <typename T>
inline vectorsum<T,plus> operator+(const lazyvector<T>& x
,const lazyvector<T>& y) {
return vectorsum<T,plus>(x, y);
}
// binary "-" operator (non-member / free function)
template <typename T>
inline vectorsum<T,minus> operator-(const lazyvector<T>& x
,const lazyvector<T>& y) {
return vectorsum<T,minus>(x ,y);
}
#include <algorithm> // for std::swap
#include <cassert>
template <typename T>
class simplevector {
public:
typedef T value_type;
typedef T& reference;
typedef unsigned int size_type;
// ctor
explicit simplevector(size_type s=0) : p_(new value_type[s]),sz_(s) {}
// copy ctor
simplevector(const simplevector& v) : p_(new value_type[v.size()])
, sz_(v.size()) {
for (size_type i=0;i<size();++i) {
p_[i] = v.p_[i];
}
}
// dtor
~simplevector() { delete[] p_;}
// swap
void swap(simplevector& v) {
std::swap(p_,v.p_);
std::swap(sz_,v.sz_);
}
// copy assignment
simplevector& operator=(simplevector v) {
swap(v);
return *this;
}
// compound plus assignment
simplevector& operator+=(const simplevector& v) {
assert(size() == v.size());
for (size_type i=0;i<size();++i) {
p_[i] += v.p_[i];
}
return *this;
}
// size
size_type size() const { return sz_; }
// subscript operator
value_type operator[](size_type i) const { return p_[i]; }
reference operator[](size_type i) { return p_[i]; }
private:
value_type* p_;
size_type sz_;
};
// binary plus operator (non-member / free function)
template <typename T>
simplevector<T> operator+(const simplevector<T>& x
,const simplevector<T>& y) {
simplevector<T> result = x;
result += y;
return result;
}
#include <iostream>
#include "etvector.hpp"
int main() {
const int N = 10000000;
etvector<double> a(N), b(N), c(N), d(N);
for (int i=0; i<100; ++i) {
a = b + c + d;
}
std::cout << a[0] << std::endl;
}
#include "lazyvector.hpp"
#include <iostream>
int main() {
const int N = 10000000;
lazyvector<double> a(N), b(N), c(N);
for (int i=0; i<100; ++i) {
a = b + c;
c[0] += i; // avoid loop inversion
}
std::cout << a[0] << std::endl;
}
#include "lazyvectorflex.hpp"
#include <iostream>
int main() {
const int N = 10000000;
lazyvector<double> a(N), b(N), c(N);
for (int i=0; i<100; ++i) {
a = b - c;
c[0] += i; // avoid loop inversion
}
std::cout << a[0] << std::endl;
}
#include <iostream>
#include "simplevector.hpp"
int main() {
const int N = 10000000;
simplevector<double> a(N), b(N), c(N), d(N);
for (int i=0; i<100; ++i) {
a = b + c + d;
}
std::cout << a[0] << std::endl;
}
#include "simplevector.hpp"
#include <iostream>
int main() {
const int N = 10000000;
simplevector<double> a(N), b(N), c(N);
for (int i=0; i<100; ++i) {
a = b + c;
}
std::cout << a[0] << std::endl;
}
#include <iostream>
#include "simplevector.hpp"
int main() {
const int N = 10000000;
simplevector<double> a(N), b(N), c(N);
for (int i=0; i<100; ++i) {
for (int j=0; j<a.size(); ++j) {
a[j] = b[j] + c[j];
}
c[0] += i; // avoid loop inversion
}
std::cout << a[0] << std::endl;
}
#include "simplevector.hpp"
#include <iostream>
int main() {
const int N = 10000000;
simplevector<double> a(N), b(N), c(N), d(N);
for (int i=0; i<100; ++i) {
for (int j=0; j<a.size(); ++j) {
a[j] = b[j] + c[j] + d[j];
}
}
std::cout << a[0] << std::endl;
}
#include "simplevector.hpp"
#include <iostream>
int main() {
const int N = 10000000;
simplevector<double> a(N), b(N), c(N), d(N);
for (int i=0; i<100; ++i) {
for (int j=0; j<a.size(); ++j) {
a[j] = b[j] + c[j] + d[j];
}
d[0] += i; // avoid loop inversion
}
std::cout << a[0] << std::endl;
}
template<typename T,int N>
class TinyVector {
public:
T& operator[](int i) { return data[i]; }
T operator[](int i) const { return data[i]; }
private:
T data[N];
};
#include <iostream>
// the general factorial
template<int N>
struct Factorial {
enum { value = N * Factorial<N-1>::value };
};
// the specialization that stops the recursion
template<>
struct Factorial<1> {
enum { value = 1 };
};
int main() {
std::cout << "Factorial< 5>::value = " << Factorial< 5>::value << "\n";
std::cout << "Factorial<11>::value = " << Factorial<11>::value << "\n";
}
// Erwin Unruh, untitled program, ANSI X3J16-94-0075/ISO WG21-462, 1994.
template<int i> struct D { D(void*); operator int(); };
template<int p, int i> struct is_prime {
enum { prim = (p%i) && is_prime<(i > 2 ? p : 0), i-1> :: prim };
};