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(__SUNPRO_CC) && (__SUNPRO_CC <= 0x500)
00030 # define ITK_CONCEPT_IMPLEMENTATION_CALL
00031 # else
00032 # define ITK_CONCEPT_IMPLEMENTATION_STANDARD
00033 # endif
00034 #endif
00035
00037 #if defined(ITK_CONCEPT_IMPLEMENTATION_STANDARD)
00038
00045 # define itkConceptConstraintsMacro() \
00046 template <void (Constraints::*)()> struct Enforcer {}; \
00047 typedef Enforcer<&Constraints::constraints> EnforcerInstantiation
00048 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00049
00050 #elif defined(ITK_CONCEPT_IMPLEMENTATION_VTABLE)
00051
00057 # define itkConceptConstraintsMacro() \
00058 virtual void Enforcer() { &Constraints::constraints; }
00059 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00060
00061 #elif define(ITK_CONCEPT_IMPLEMENTATION_CALL)
00062
00064 # define itkConceptConstraintsMacro()
00065 # define itkConceptMacro(name, concept) enum { name = 0 }
00066
00067 #else
00068
00070 # define itkConceptConstraintsMacro()
00071 # define itkConceptMacro(name, concept) enum { name = 0 }
00072
00073 #endif
00074
00075 namespace itk
00076 {
00077
00080 namespace Concept
00081 {
00082
00090 namespace Detail
00091 {
00092
00093 template <typename T> struct UniqueType {};
00094 template <int> struct UniqueType_int {};
00095 template <unsigned int> struct UniqueType_unsigned_int {};
00096
00102 template <typename T> inline void IgnoreUnusedVariable(T) {}
00103
00109 template <class T>
00110 void RequireBooleanExpression(const T& t)
00111 {
00112 bool x = t;
00113 IgnoreUnusedVariable(x);
00114 }
00115
00116 }
00117
00118
00120 template <typename T>
00121 struct DefaultConstructible
00122 {
00123 struct Constraints
00124 {
00125 void constraints()
00126 {
00127 T a;
00128 Detail::IgnoreUnusedVariable(a);
00129 }
00130 };
00131
00132 itkConceptConstraintsMacro();
00133 };
00134
00136 template <typename T>
00137 struct CopyConstructible
00138 {
00139 struct Constraints
00140 {
00141 void constraints()
00142 {
00143 T a(b);
00144 T* p = &a;
00145 const_constraints(a);
00146 Detail::IgnoreUnusedVariable(p);
00147 }
00148 void const_constraints(const T& a)
00149 {
00150 T c(a);
00151 const T* p = &a;
00152 Detail::IgnoreUnusedVariable(c);
00153 Detail::IgnoreUnusedVariable(p);
00154 }
00155 T b;
00156 };
00157
00158 itkConceptConstraintsMacro();
00159 };
00160
00162 template <typename T1, typename T2>
00163 struct Convertible
00164 {
00165 struct Constraints
00166 {
00167 void constraints()
00168 {
00169 T2 b = a;
00170 Detail::IgnoreUnusedVariable(b);
00171 }
00172 T1 a;
00173 };
00174 itkConceptConstraintsMacro();
00175 };
00176
00178 template <typename T>
00179 struct Assignable
00180 {
00181 struct Constraints
00182 {
00183 void constraints()
00184 {
00185 a = a;
00186 const_constraints(a);
00187 }
00188 void const_constraints(const T& b)
00189 {
00190 a = b;
00191 }
00192 T a;
00193 };
00194
00195 itkConceptConstraintsMacro();
00196 };
00197
00199 template <typename T>
00200 struct LessThanComparable
00201 {
00202 struct Constraints
00203 {
00204 void constraints()
00205 {
00206 Detail::RequireBooleanExpression(a < b);
00207 }
00208 T a, b;
00209 };
00210
00211 itkConceptConstraintsMacro();
00212 };
00213
00215 template <typename T>
00216 struct EqualityComparable
00217 {
00218 struct Constraints
00219 {
00220 void constraints()
00221 {
00222 Detail::RequireBooleanExpression(a == b);
00223 Detail::RequireBooleanExpression(a != b);
00224 }
00225 T a, b;
00226 };
00227
00228 itkConceptConstraintsMacro();
00229 };
00230
00232 template <typename T>
00233 struct Comparable
00234 {
00235 struct Constraints
00236 {
00237 void constraints()
00238 {
00239 Detail::RequireBooleanExpression(a < b);
00240 Detail::RequireBooleanExpression(a > b);
00241 Detail::RequireBooleanExpression(a <= b);
00242 Detail::RequireBooleanExpression(a >= b);
00243 Detail::RequireBooleanExpression(a == b);
00244 Detail::RequireBooleanExpression(a != b);
00245 }
00246 T a, b;
00247 };
00248
00249 itkConceptConstraintsMacro();
00250 };
00251
00253 template <typename T>
00254 struct AdditiveOperators
00255 {
00256 struct Constraints
00257 {
00258 void constraints()
00259 {
00260 a = b + b;
00261 a = b - b;
00262 a += b;
00263 a -= b;
00264 const_constraints(b);
00265 }
00266 void const_constraints(const T& c)
00267 {
00268 a = c + c;
00269 a = c - c;
00270 a += c;
00271 a -= c;
00272 }
00273 T a, b;
00274 };
00275
00276 itkConceptConstraintsMacro();
00277 };
00278
00280 template <typename T>
00281 struct MultiplicativeOperators
00282 {
00283 struct Constraints
00284 {
00285 void constraints()
00286 {
00287 a = b * b;
00288 a = b / b;
00289 a *= b;
00290 a /= b;
00291 const_constraints(b);
00292 }
00293 void const_constraints(const T& c)
00294 {
00295 a = c * c;
00296 a = c / c;
00297 a *= c;
00298 a /= c;
00299 }
00300 T a, b;
00301 };
00302
00303 itkConceptConstraintsMacro();
00304 };
00305
00306
00308 template <typename T1, typename T2>
00309 struct SameType
00310 {
00311 struct Constraints
00312 {
00313 void constraints()
00314 {
00315 Detail::UniqueType<T1> a = Detail::UniqueType<T2>();
00316 Detail::IgnoreUnusedVariable(a);
00317 }
00318 };
00319 itkConceptConstraintsMacro();
00320 };
00321
00323 template <unsigned int D1, unsigned int D2>
00324 struct SameDimension
00325 {
00326 struct Constraints
00327 {
00328 typedef Detail::UniqueType_unsigned_int<D1> DT1;
00329 typedef Detail::UniqueType_unsigned_int<D2> DT2;
00330 void constraints()
00331 {
00332 DT1 a = DT2();
00333 Detail::IgnoreUnusedVariable(a);
00334 }
00335 };
00336 itkConceptConstraintsMacro();
00337 };
00338
00339 }
00340
00341 }
00342
00343 #endif