00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _itkConceptChecking_h
00021 #define _itkConceptChecking_h
00022
00024 #ifndef ITK_CONCEPT_NO_CHECKING
00025 # if defined(_MSC_VER) && !defined(__ICL)
00026 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00027 # elif defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
00028 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00029 # elif defined(__MWERKS__) && (__MWERKS__ <= 0x3002)
00030 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00031 # elif defined(__SUNPRO_CC)
00032 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00033 # else
00034 # define ITK_CONCEPT_IMPLEMENTATION_STANDARD
00035 # endif
00036 #endif
00037
00039 #if defined(ITK_CONCEPT_IMPLEMENTATION_STANDARD)
00040
00047 # define itkConceptConstraintsMacro() \
00048 template <void (Constraints::*)()> struct Enforcer {}; \
00049 typedef Enforcer<&Constraints::constraints> EnforcerInstantiation
00050 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00051
00052 #elif defined(ITK_CONCEPT_IMPLEMENTATION_VTABLE)
00053
00059 # define itkConceptConstraintsMacro() \
00060 virtual void Enforcer() { &Constraints::constraints; }
00061 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00062
00063 #elif defined(ITK_CONCEPT_IMPLEMENTATION_CALL)
00064
00066 # define itkConceptConstraintsMacro()
00067 # define itkConceptMacro(name, concept) enum { name = 0 }
00068
00069 #else
00070
00072 # define itkConceptConstraintsMacro()
00073 # define itkConceptMacro(name, concept) enum { name = 0 }
00074
00075 #endif
00076
00077 namespace itk
00078 {
00079
00082 namespace Concept
00083 {
00084
00092 namespace Detail
00093 {
00094
00095 template <typename T> struct UniqueType {};
00096 template <int> struct UniqueType_int {};
00097 template <unsigned int> struct UniqueType_unsigned_int {};
00098 template <bool> struct UniqueType_bool {};
00099
00100
00106 template <typename T> inline void IgnoreUnusedVariable(T) {}
00107
00113 template <class T>
00114 void RequireBooleanExpression(const T& t)
00115 {
00116 bool x = t;
00117 IgnoreUnusedVariable(x);
00118 }
00119
00120 }
00121
00122
00124 template <typename T>
00125 struct DefaultConstructible
00126 {
00127 struct Constraints
00128 {
00129 void constraints()
00130 {
00131 T a;
00132 Detail::IgnoreUnusedVariable(a);
00133 }
00134 };
00135
00136 itkConceptConstraintsMacro();
00137 };
00138
00140 template <typename T>
00141 struct CopyConstructible
00142 {
00143 struct Constraints
00144 {
00145 void constraints()
00146 {
00147 T a(b);
00148 T* p = &a;
00149 const_constraints(a);
00150 Detail::IgnoreUnusedVariable(p);
00151 }
00152 void const_constraints(const T& a)
00153 {
00154 T c(a);
00155 const T* p = &a;
00156 Detail::IgnoreUnusedVariable(c);
00157 Detail::IgnoreUnusedVariable(p);
00158 }
00159 T b;
00160 };
00161
00162 itkConceptConstraintsMacro();
00163 };
00164
00166 template <typename T1, typename T2>
00167 struct Convertible
00168 {
00169 struct Constraints
00170 {
00171 void constraints()
00172 {
00173 T2 b = a;
00174 Detail::IgnoreUnusedVariable(b);
00175 }
00176 T1 a;
00177 };
00178 itkConceptConstraintsMacro();
00179 };
00180
00182 template <typename T>
00183 struct Assignable
00184 {
00185 struct Constraints
00186 {
00187 void constraints()
00188 {
00189 a = a;
00190 const_constraints(a);
00191 }
00192 void const_constraints(const T& b)
00193 {
00194 a = b;
00195 }
00196 T a;
00197 };
00198
00199 itkConceptConstraintsMacro();
00200 };
00201
00203 template <typename T>
00204 struct LessThanComparable
00205 {
00206 struct Constraints
00207 {
00208 void constraints()
00209 {
00210 Detail::RequireBooleanExpression(a < b);
00211 }
00212 T a, b;
00213 };
00214
00215 itkConceptConstraintsMacro();
00216 };
00217
00219 template <typename T>
00220 struct EqualityComparable
00221 {
00222 struct Constraints
00223 {
00224 void constraints()
00225 {
00226 Detail::RequireBooleanExpression(a == b);
00227 Detail::RequireBooleanExpression(a != b);
00228 }
00229 T a, b;
00230 };
00231
00232 itkConceptConstraintsMacro();
00233 };
00234
00236 template <typename T>
00237 struct Comparable
00238 {
00239 struct Constraints
00240 {
00241 void constraints()
00242 {
00243 Detail::RequireBooleanExpression(a < b);
00244 Detail::RequireBooleanExpression(a > b);
00245 Detail::RequireBooleanExpression(a <= b);
00246 Detail::RequireBooleanExpression(a >= b);
00247 Detail::RequireBooleanExpression(a == b);
00248 Detail::RequireBooleanExpression(a != b);
00249 }
00250 T a, b;
00251 };
00252
00253 itkConceptConstraintsMacro();
00254 };
00255
00257 template <typename T>
00258 struct AdditiveOperators
00259 {
00260 struct Constraints
00261 {
00262 void constraints()
00263 {
00264 a = b + b;
00265 a = b - b;
00266 a += b;
00267 a -= b;
00268 const_constraints(b);
00269 }
00270 void const_constraints(const T& c)
00271 {
00272 a = c + c;
00273 a = c - c;
00274 a += c;
00275 a -= c;
00276 }
00277 T a, b;
00278 };
00279
00280 itkConceptConstraintsMacro();
00281 };
00282
00284 template <typename T>
00285 struct MultiplicativeOperators
00286 {
00287 struct Constraints
00288 {
00289 void constraints()
00290 {
00291 a = b * b;
00292 a = b / b;
00293 a *= b;
00294 a /= b;
00295 const_constraints(b);
00296 }
00297 void const_constraints(const T& c)
00298 {
00299 a = c * c;
00300 a = c / c;
00301 a *= c;
00302 a /= c;
00303 }
00304 T a, b;
00305 };
00306
00307 itkConceptConstraintsMacro();
00308 };
00309
00311 template <typename T>
00312 struct Signed
00313 {
00314 typedef Signed Self;
00315 itkStaticConstMacro(IsSigned, bool, NumericTraits<T>::is_signed);
00316 struct Constraints
00317 {
00318 typedef Detail::UniqueType_bool<true> TrueT;
00319 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsSigned)> SignedT;
00320 void constraints()
00321 {
00322 SignedT a = TrueT();
00323 Detail::IgnoreUnusedVariable(a);
00324 }
00325 };
00326
00327 itkConceptConstraintsMacro();
00328 };
00329
00331 template <typename T1, typename T2>
00332 struct SameType
00333 {
00334 struct Constraints
00335 {
00336 void constraints()
00337 {
00338 Detail::UniqueType<T1> a = Detail::UniqueType<T2>();
00339 Detail::IgnoreUnusedVariable(a);
00340 }
00341 };
00342 itkConceptConstraintsMacro();
00343 };
00344
00346 template <unsigned int D1, unsigned int D2>
00347 struct SameDimension
00348 {
00349 struct Constraints
00350 {
00351 typedef Detail::UniqueType_unsigned_int<D1> DT1;
00352 typedef Detail::UniqueType_unsigned_int<D2> DT2;
00353 void constraints()
00354 {
00355 DT1 a = DT2();
00356 Detail::IgnoreUnusedVariable(a);
00357 }
00358 };
00359 itkConceptConstraintsMacro();
00360 };
00361
00362 }
00363
00364 }
00365
00366 #endif