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) && (__SUNPRO_CC <= 0x500)
00032 # define ITK_CONCEPT_IMPLEMENTATION_CALL
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
00104 template <typename T> inline void IgnoreUnusedVariable(T) {}
00105
00111 template <class T>
00112 void RequireBooleanExpression(const T& t)
00113 {
00114 bool x = t;
00115 IgnoreUnusedVariable(x);
00116 }
00117
00118 }
00119
00120
00122 template <typename T>
00123 struct DefaultConstructible
00124 {
00125 struct Constraints
00126 {
00127 void constraints()
00128 {
00129 T a;
00130 Detail::IgnoreUnusedVariable(a);
00131 }
00132 };
00133
00134 itkConceptConstraintsMacro();
00135 };
00136
00138 template <typename T>
00139 struct CopyConstructible
00140 {
00141 struct Constraints
00142 {
00143 void constraints()
00144 {
00145 T a(b);
00146 T* p = &a;
00147 const_constraints(a);
00148 Detail::IgnoreUnusedVariable(p);
00149 }
00150 void const_constraints(const T& a)
00151 {
00152 T c(a);
00153 const T* p = &a;
00154 Detail::IgnoreUnusedVariable(c);
00155 Detail::IgnoreUnusedVariable(p);
00156 }
00157 T b;
00158 };
00159
00160 itkConceptConstraintsMacro();
00161 };
00162
00164 template <typename T1, typename T2>
00165 struct Convertible
00166 {
00167 struct Constraints
00168 {
00169 void constraints()
00170 {
00171 T2 b = a;
00172 Detail::IgnoreUnusedVariable(b);
00173 }
00174 T1 a;
00175 };
00176 itkConceptConstraintsMacro();
00177 };
00178
00180 template <typename T>
00181 struct Assignable
00182 {
00183 struct Constraints
00184 {
00185 void constraints()
00186 {
00187 a = a;
00188 const_constraints(a);
00189 }
00190 void const_constraints(const T& b)
00191 {
00192 a = b;
00193 }
00194 T a;
00195 };
00196
00197 itkConceptConstraintsMacro();
00198 };
00199
00201 template <typename T>
00202 struct LessThanComparable
00203 {
00204 struct Constraints
00205 {
00206 void constraints()
00207 {
00208 Detail::RequireBooleanExpression(a < b);
00209 }
00210 T a, b;
00211 };
00212
00213 itkConceptConstraintsMacro();
00214 };
00215
00217 template <typename T>
00218 struct EqualityComparable
00219 {
00220 struct Constraints
00221 {
00222 void constraints()
00223 {
00224 Detail::RequireBooleanExpression(a == b);
00225 Detail::RequireBooleanExpression(a != b);
00226 }
00227 T a, b;
00228 };
00229
00230 itkConceptConstraintsMacro();
00231 };
00232
00234 template <typename T>
00235 struct Comparable
00236 {
00237 struct Constraints
00238 {
00239 void constraints()
00240 {
00241 Detail::RequireBooleanExpression(a < b);
00242 Detail::RequireBooleanExpression(a > b);
00243 Detail::RequireBooleanExpression(a <= b);
00244 Detail::RequireBooleanExpression(a >= b);
00245 Detail::RequireBooleanExpression(a == b);
00246 Detail::RequireBooleanExpression(a != b);
00247 }
00248 T a, b;
00249 };
00250
00251 itkConceptConstraintsMacro();
00252 };
00253
00255 template <typename T>
00256 struct AdditiveOperators
00257 {
00258 struct Constraints
00259 {
00260 void constraints()
00261 {
00262 a = b + b;
00263 a = b - b;
00264 a += b;
00265 a -= b;
00266 const_constraints(b);
00267 }
00268 void const_constraints(const T& c)
00269 {
00270 a = c + c;
00271 a = c - c;
00272 a += c;
00273 a -= c;
00274 }
00275 T a, b;
00276 };
00277
00278 itkConceptConstraintsMacro();
00279 };
00280
00282 template <typename T>
00283 struct MultiplicativeOperators
00284 {
00285 struct Constraints
00286 {
00287 void constraints()
00288 {
00289 a = b * b;
00290 a = b / b;
00291 a *= b;
00292 a /= b;
00293 const_constraints(b);
00294 }
00295 void const_constraints(const T& c)
00296 {
00297 a = c * c;
00298 a = c / c;
00299 a *= c;
00300 a /= c;
00301 }
00302 T a, b;
00303 };
00304
00305 itkConceptConstraintsMacro();
00306 };
00307
00308
00310 template <typename T1, typename T2>
00311 struct SameType
00312 {
00313 struct Constraints
00314 {
00315 void constraints()
00316 {
00317 Detail::UniqueType<T1> a = Detail::UniqueType<T2>();
00318 Detail::IgnoreUnusedVariable(a);
00319 }
00320 };
00321 itkConceptConstraintsMacro();
00322 };
00323
00325 template <unsigned int D1, unsigned int D2>
00326 struct SameDimension
00327 {
00328 struct Constraints
00329 {
00330 typedef Detail::UniqueType_unsigned_int<D1> DT1;
00331 typedef Detail::UniqueType_unsigned_int<D2> DT2;
00332 void constraints()
00333 {
00334 DT1 a = DT2();
00335 Detail::IgnoreUnusedVariable(a);
00336 }
00337 };
00338 itkConceptConstraintsMacro();
00339 };
00340
00341 }
00342
00343 }
00344
00345 #endif