00001 #ifndef NMWR_GB_POINT_TRAITS_H
00002 #define NMWR_GB_POINT_TRAITS_H
00003
00004
00005
00006
00007
00008 #include "Config/compiler-config.h"
00009 #include "Utility/pre-post-conditions.h"
00010
00015 template<class P>
00016 struct point_traits {};
00017
00018
00019
00020 struct fixed_dimension_tag {};
00021 struct variable_dimension_tag {};
00022
00023 struct tag_unknown_dim {};
00024
00025 struct tag1D : public fixed_dimension_tag {};
00026 struct tag2D : public fixed_dimension_tag {};
00027 struct tag3D : public fixed_dimension_tag {};
00028 struct tag4D : public fixed_dimension_tag {};
00029
00030 template<unsigned N>
00031 struct dim_tag {
00032 enum { dim = N};
00033 typedef fixed_dimension_tag dimension_tag;
00034 };
00035
00036 template<> struct dim_tag<1> { typedef tag1D dimension_tag;};
00037 template<> struct dim_tag<2> { typedef tag2D dimension_tag;};
00038 template<> struct dim_tag<3> { typedef tag3D dimension_tag;};
00039 template<> struct dim_tag<4> { typedef tag4D dimension_tag;};
00040
00041
00042 template<class POINT>
00043 struct point_traits_base
00044 {
00045 typedef tag_unknown_dim dimension_tag;
00046 typedef POINT Ptype;
00047
00048 };
00049
00050
00051 template<class POINT, unsigned DIM>
00052 struct point_traits_fixed_dim
00053 : public point_traits_base<POINT>
00054 {
00055 typedef dim_tag<N> dimension_tag;
00056 static unsigned Dim() { return DIM;}
00057 static unsigned Dim(Ptype const&) { return DIM;}
00058 static void ConstructWithDim(unsigned d, Ptype&)
00059 { REQUIRE(d == DIM, "Cannot construct: d = " << d << "; DIM = " << DIM,1);}
00060 };
00061
00062
00066 template<class REAL>
00067 struct real_point_traits : public point_traits_base<REAL> {
00068 typedef REAL Ptype;
00069 typedef tag1D dimension_tag;
00070 typedef REAL component_type;
00071 typedef component_type value_type;
00072
00073 static unsigned Dim(const Ptype&) { return 1;}
00074 static unsigned Dim() { return 1;}
00075
00076 static Ptype Origin(unsigned) { return REAL(0.0);}
00077 static Ptype Origin() { return REAL(0.0);}
00078 static component_type x(const Ptype& p) {return p;}
00079 static component_type& x( Ptype& p) {return p;}
00080 static component_type y(const Ptype&) {return component_type(0.0);}
00081 static component_type z(const Ptype&) {return component_type(0.0);}
00082 };
00083
00084 template<>
00085 struct point_traits<float>
00086 : public real_point_traits<float> {};
00087
00088 template<>
00089 struct point_traits<double>
00090 : public real_point_traits<double> {};
00091
00092
00093
00094
00095 template<class ARRAY, class COMPONENT, unsigned DIM>
00096 struct point_traits_fixed_size_array :
00097 public point_traits_base<ARRAY>
00098 {
00099 typedef ARRAY Ptype;
00100 typedef COMPONENT component_type;
00101 typedef component_type value_type;
00102 typedef dim_tag<DIM>::dimension_tag dimension_tag;
00103
00104 static void ConstructWithDim(unsigned d, Ptype&)
00105 { REQUIRE(d == DIM, "Cannot construct! d = " << d
00106 << ", DIM = " << DIM <<'\n',1);
00107 }
00108 static unsigned Dim(const Ptype&) { return DIM;}
00109 static unsigned Dim() { return DIM;}
00110
00111 static int LowerIndex() { return 0;}
00112 static int LowerIndex(Ptype const&) { return 0;}
00113 static int UpperIndex() { return DIM-1;}
00114 static int UpperIndex(Ptype const&) { return DIM-1;}
00115
00116
00117 static Ptype Origin() {
00118 Ptype p;
00119 for(unsigned i = 0; i < DIM; ++i) p[i] = component_type(0.0);
00120 return p;
00121 }
00122 static Ptype Origin(unsigned) { return Origin();}
00123
00124
00125
00126 static component_type x(const Ptype& p) {return p[0];}
00127 static component_type& x( Ptype& p) {return p[0];}
00128 static component_type y(const Ptype& p) {return p[1];}
00129 static component_type& y( Ptype& p) {return p[1];}
00130 static component_type z(const Ptype& p) {return p[2];}
00131 static component_type& z( Ptype& p) {return p[2];}
00132
00133 };
00134
00135
00136 template<class ARRAY, unsigned N>
00137 struct array_operators
00138 {
00139 ARRAY & to_derived() { return static_cast<ARRAY&>(*this);}
00140 ARRAY const& to_derived() const { return static_cast<ARRAY const&>(*this);}
00141
00142
00143 ARRAY& operator-=(ARRAY const& rhs) {
00144 for(unsigned i = 0; i < N; ++i)
00145 to_derived()[i] -= rhs[i];
00146 return to_derived();
00147 }
00148 ARRAY operator-(ARRAY const& rhs) const {
00149 ARRAY lhs(to_derived());
00150 return lhs -= rhs;
00151 }
00152 ARRAY& operator+=(ARRAY const& rhs) {
00153 for(unsigned i = 0; i < N; ++i)
00154 to_derived()[i] += rhs[i];
00155 return to_derived();
00156 }
00157 ARRAY operator+(ARRAY const& rhs) const {
00158 ARRAY lhs(to_derived());
00159 return lhs += rhs;
00160 }
00161
00162 };
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 template<class P, class Q>
00178 inline void assign_point(P & p,
00179 Q const& q)
00180 {
00181 typedef point_traits<P> ptP;
00182 typedef point_traits<Q> ptQ;
00183
00184
00185 ptP::ConstructWithDim(ptQ::Dim(q), p);
00186
00187
00188 REQUIRE( (ptP::Dim(p) == ptQ::Dim(q)),
00189 "Cannot assign points of different dimension!"
00190 << "(dim(p) = " << ptP::Dim(p) << ", "
00191 << "(dim(q) = " << ptQ::Dim(q), 1);
00192
00193 int iq = ptQ::LowerIndex(q);
00194 int ip = ptP::LowerIndex(p);
00195 for(; iq <= ptQ::UpperIndex(q); ++ip, ++iq)
00196 p[ip] = q[iq];
00197 }
00198
00199
00200 template<class P, class T>
00201 inline void assign_point(P & p, T const* b, T const* e)
00202 {
00203 REQUIRE( (e-b > 0), "invalid pointer range: b = " << b << "; e = " << e << "\n",1);
00204 typedef point_traits<P> ptP;
00205
00206
00207 ptP::ConstructWithDim(e-b,p);
00208
00209 REQUIRE( ptP::Dim(p) == e-b,
00210 "Cannot assign points of different dimension!"
00211 << "(dim(p) = " << ptP::Dim(p) << ", "
00212 << "e-p = " << e-p, 1);
00213
00214 int ip = ptP::LowerIndex(p);
00215 for(; b < e; ++ip, ++b)
00216 p[ip] = *b;
00217 }
00218
00219 template<class P>
00220 inline void assign_point(P& p, P const& q) { p = q;}
00221
00222
00223 template<class P>
00224 inline void assign_point(float& p, P const& q)
00225
00226 { p = point_traits<P>::x(q);}
00227
00228 inline void assign_point(float& p, float q) { p = q;}
00229
00230 #endif