00001 #ifndef _FIELD_HPP_
00002 #define _FIELD_HPP_
00003
00004 #include <cassert>
00005 #include <string.h>
00006 #include <iostream>
00007
00013 namespace Memory {
00014
00015 template <int DIM, typename T>
00016 class Field;
00017
00018 template <int DIM, typename T>
00019 std::ostream & operator<< (std::ostream & os, const Field<DIM,T> & f);
00020
00022 template <int DIM, typename T>
00023 class Field {
00024 public:
00025 static const int size = DIM;
00026 Field() { init(0); }
00027 explicit Field(const int c) { init(c); }
00028 Field(const Field& f) { memcpy(this, &f, DIM * sizeof(T)); }
00029
00030 void init(const int c) { memset(this, c, DIM * sizeof(T)); }
00031
00032 inline T& operator[](const int i) { assert(i >= 0 && i < DIM); return arr[i]; }
00033 inline const T& operator[](const int i) const { assert(i >= 0 && i < DIM); return arr[i]; }
00034
00035 const Field& operator=(const T val) {
00036 for(register int i = 0; i < DIM; ++i)
00037 arr[i] = val;
00038 return *this;
00039 }
00040 const Field& operator=(const Field & f) {
00041 if(this != &f)
00042 memcpy(this, &f, DIM * sizeof(T));
00043 return *this;
00044 }
00045
00046 operator const T * () const { return arr; }
00047 operator T* () { return arr; }
00048
00049 void addAX(register const Field& f, register const T a = 1.0) {
00050 for(register int i = 0; i < DIM; ++i)
00051 arr[i] += f.arr[i] * a;
00052 }
00053
00054 T* getArray() { return arr; }
00055
00056 friend std::ostream& operator<< <>(std::ostream& os, const Field& f);
00057
00058 private:
00059 T arr[DIM];
00060 };
00061
00063 template <typename T>
00064 class Field<1, T>
00065 {
00066 public:
00067 Field() : v(T(0)) {}
00068 Field(const T & c) : v(c) {}
00069 Field(const Field& f) : v(f.v) {}
00070
00071 void init(const int c) { v = c; }
00072
00073 T& operator[](const int) { return v; }
00074 const T& operator[](const int) const { return v; }
00075
00076 const Field& operator=(const T val) { v = val; return *this; }
00077 const Field& operator=(const Field& f) { v = f.v; return *this; }
00078
00079 void addAX(register const Field& f, register const T a = 1.0) { v += a * f.v; }
00080
00081 friend std::ostream& operator<< <>(std::ostream& os, const Field& f);
00082
00083 private:
00084 T v;
00085 };
00086
00088
00089 template <typename T>
00090 class Field<0, T>
00091 {
00092 public:
00093 void init(const int) {};
00094 };
00095
00096 template <int DIM>
00097 class Field<DIM, void>
00098 {
00099 public:
00100 void init(const int) {};
00101 };
00102
00104
00105 template <int DIM, typename T>
00106 std::ostream& operator<<(std::ostream& os, const Field<DIM, T>& f) {
00107 os << "(";
00108 for(register int i = 0; i < DIM; ++i)
00109 os << f.arr[i] << ", ";
00110 os << "\b\b)";
00111 return os;
00112 }
00113
00114 template <typename T>
00115 std::ostream& operator<<(std::ostream& os, const Field<1, T>& f) {
00116 os << "(" << f.v << ")";
00117 return os;
00118 }
00119
00121
00122
00123
00124
00125
00127
00128
00129
00130
00131
00132
00133 template <typename T>
00134 struct Type2Ref {
00135 typedef T& refType;
00136 typedef const T& constRefType;
00137 };
00138
00139 template <>
00140 struct Type2Ref<void> {
00141 typedef void refType;
00142 typedef void constRefType;
00143 };
00144 }
00145
00146
00149 #endif