1 #ifndef DUNE_MULTITYPEVECTOR_HH
2 #define DUNE_MULTITYPEVECTOR_HH
5 #ifdef HAVE_BOOST_FUSION
12 #include <boost/fusion/sequence.hpp>
13 #include <boost/fusion/container.hpp>
14 #include <boost/fusion/iterator.hpp>
15 #include <boost/typeof/typeof.hpp>
16 #include <boost/fusion/algorithm.hpp>
18 namespace mpl=boost::mpl;
19 namespace fusion=boost::fusion;
23 template<
typename T1,
typename T2=fusion::void_,
typename T3=fusion::void_,
typename T4=fusion::void_,
24 typename T5=fusion::void_,
typename T6=fusion::void_,
typename T7=fusion::void_,
25 typename T8=fusion::void_,
typename T9=fusion::void_>
26 class MultiTypeBlockVector;
56 template<
int current_element,
int remaining_elements,
typename TVec>
57 class MultiTypeBlockVector_Print {
62 static void print(
const TVec& v) {
63 std::cout <<
"\t(" << current_element <<
"):\n" << fusion::at_c<current_element>(v) <<
"\n";
64 MultiTypeBlockVector_Print<current_element+1,remaining_elements-1,TVec>::print(v);
67 template<
int current_element,
typename TVec>
68 class MultiTypeBlockVector_Print<current_element,0,TVec> {
70 static void print(
const TVec& v) {std::cout <<
"\n";}
86 template<
int count,
typename T1,
typename T2>
87 class MultiTypeBlockVector_Ident {
94 static void equalize(T1& a,
const T2& b) {
95 fusion::at_c<
count-1>(a) = b;
96 MultiTypeBlockVector_Ident<count-1,T1,T2>::equalize(a,b);
99 template<
typename T1,
typename T2>
100 class MultiTypeBlockVector_Ident<0,T1,T2> {
public:
static void equalize (T1& a,
const T2& b) {} };
112 template<
int count,
typename T>
113 class MultiTypeBlockVector_Add {
119 static void add (T& a,
const T& b) {
120 fusion::at_c<(
count-1)>(a) += fusion::at_c<(
count-1)>(b);
121 MultiTypeBlockVector_Add<count-1,T>::add(a,b);
127 static void sub (T& a,
const T& b) {
128 fusion::at_c<(
count-1)>(a) -= fusion::at_c<(
count-1)>(b);
129 MultiTypeBlockVector_Add<count-1,T>::sub(a,b);
133 class MultiTypeBlockVector_Add<0,T> {
public:
static void add (T& a,
const T& b) {}
static void sub (T& a,
const T& b) {} };
142 template<
int count,
typename TVec,
typename Ta>
143 class MultiTypeBlockVector_AXPY {
149 static void axpy(TVec& x,
const Ta& a,
const TVec& y) {
150 fusion::at_c<(
count-1)>(x).axpy(a,fusion::at_c<(
count-1)>(y));
151 MultiTypeBlockVector_AXPY<count-1,TVec,Ta>::axpy(x,a,y);
154 template<
typename TVec,
typename Ta>
155 class MultiTypeBlockVector_AXPY<0,TVec,Ta> {
public:
static void axpy (TVec& x,
const Ta& a,
const TVec& y) {} };
163 template<
int count,
typename TVec,
typename Ta>
164 class MultiTypeBlockVector_Mulscal {
170 static void mul(TVec& x,
const Ta& a) {
171 fusion::at_c<(
count-1)>(x) *= a;
172 MultiTypeBlockVector_Mulscal<count-1,TVec,Ta>::mul(x,a);
175 template<
typename TVec,
typename Ta>
176 class MultiTypeBlockVector_Mulscal<0,TVec,Ta> {
public:
static void mul (TVec& x,
const Ta& a) {} };
186 template<
int count,
typename TVec>
187 class MultiTypeBlockVector_Mul {
189 static typename TVec::field_type mul(
const TVec& x,
const TVec& y) {
190 return (fusion::at_c<count-1>(x) * fusion::at_c<count-1>(y)) + MultiTypeBlockVector_Mul<count-1,TVec>::mul(x,y);
193 template<
typename TVec>
194 class MultiTypeBlockVector_Mul<0,TVec> {
195 public:
static typename TVec::field_type mul(
const TVec& x,
const TVec& y) {
return 0;}
208 template<
int count,
typename T>
209 class MultiTypeBlockVector_Norm {
215 static double result (
const T& a) {
216 return fusion::at_c<
count-1>(a).two_norm2() + MultiTypeBlockVector_Norm<count-1,T>::result(a);
221 class MultiTypeBlockVector_Norm<0,T> {
223 static double result (
const T& a) {
return 0.0;}
234 template<
typename T1,
typename T2,
typename T3,
typename T4,
235 typename T5,
typename T6,
typename T7,
typename T8,
typename T9>
236 class MultiTypeBlockVector :
public fusion::vector<T1, T2, T3, T4, T5, T6, T7, T8, T9> {
243 typedef MultiTypeBlockVector<T1, T2, T3, T4, T5, T6, T7, T8, T9>
type;
245 typedef typename T1::field_type field_type;
250 const int count() {
return mpl::size<type>::value;}
256 void operator= (
const T& newval) {MultiTypeBlockVector_Ident<mpl::size<type>::value,
type,T>::equalize(*
this, newval); }
261 void operator+= (
const type& newv) {MultiTypeBlockVector_Add<mpl::size<type>::value,
type>::add(*
this,newv);}
266 void operator-= (
const type& newv) {MultiTypeBlockVector_Add<mpl::size<type>::value,
type>::sub(*
this,newv);}
268 void operator*= (
const int& w) {MultiTypeBlockVector_Mulscal<mpl::size<type>::value,
type,
const int>::mul(*
this,w);}
269 void operator*= (
const float& w) {MultiTypeBlockVector_Mulscal<mpl::size<type>::value,
type,
const float>::mul(*
this,w);}
270 void operator*= (
const double& w) {MultiTypeBlockVector_Mulscal<mpl::size<type>::value,
type,
const double>::mul(*
this,w);}
272 field_type operator* (
const type& newv)
const {
return MultiTypeBlockVector_Mul<mpl::size<type>::value,
type>::mul(*
this,newv);}
277 double two_norm2()
const {
return MultiTypeBlockVector_Norm<mpl::size<type>::value,
type>::result(*
this);}
282 double two_norm()
const {
return sqrt(this->two_norm2());}
287 template<
typename Ta>
288 void axpy (
const Ta& a,
const type& y) {
289 MultiTypeBlockVector_AXPY<mpl::size<type>::value,
type,Ta>::axpy(*
this,a,y);
301 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9>
302 std::ostream& operator<< (std::ostream& s, const MultiTypeBlockVector<T1,T2,T3,T4,T5,T6,T7,T8,T9>& v) {
303 MultiTypeBlockVector_Print<0,mpl::size<MultiTypeBlockVector<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value,MultiTypeBlockVector<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::print(v);
311 #endif // end HAVE_BOOST_FUSION
312 #endif // end HAVE_BOOST