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
00023 #include "itkPixelTraits.h"
00024
00026 #ifndef ITK_CONCEPT_NO_CHECKING
00027 # if defined(_MSC_VER) && !defined(__ICL)
00028 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00029 # elif defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
00030 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00031 # elif defined(__MWERKS__) && (__MWERKS__ <= 0x3002)
00032 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00033 # elif defined(__SUNPRO_CC)
00034 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00035 # else
00036 # define ITK_CONCEPT_IMPLEMENTATION_STANDARD
00037 # endif
00038 #endif
00039
00041 #if defined(ITK_CONCEPT_IMPLEMENTATION_STANDARD)
00042
00050
00051
00052
00053 # define itkConceptConstraintsMacro() \
00054 template <void (Constraints::*)()> struct Enforcer {}; \
00055 typedef Enforcer<&Constraints::constraints> EnforcerInstantiation
00056 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00057
00058 #elif defined(ITK_CONCEPT_IMPLEMENTATION_VTABLE)
00059
00065 # define itkConceptConstraintsMacro() \
00066 virtual void Enforcer() { &Constraints::constraints; }
00067 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00068
00069
00070 #elif defined(ITK_CONCEPT_IMPLEMENTATION_CALL)
00071
00073 # define itkConceptConstraintsMacro()
00074 # define itkConceptMacro(name, concept) enum { name = 0 }
00075
00076 #else
00077
00079 # define itkConceptConstraintsMacro()
00080 # define itkConceptMacro(name, concept) enum { name = 0 }
00081
00082 #endif
00083
00084 namespace itk
00085 {
00086
00089 namespace Concept
00090 {
00091
00099 namespace Detail
00100 {
00101
00102 template <typename T> struct UniqueType {};
00103 template <int> struct UniqueType_int {};
00104 template <unsigned int> struct UniqueType_unsigned_int {};
00105 template <bool> struct UniqueType_bool {};
00106
00107
00113 template <typename T> inline void IgnoreUnusedVariable(T) {}
00114
00120 template <class T>
00121 void RequireBooleanExpression(const T& t)
00122 {
00123 bool x = t;
00124 IgnoreUnusedVariable(x);
00125 }
00127
00128 }
00129
00130
00132 template <typename T>
00133 struct DefaultConstructible
00134 {
00135 struct Constraints
00136 {
00137 void constraints()
00138 {
00139 T a;
00140 Detail::IgnoreUnusedVariable(a);
00141 }
00142 };
00144
00145 itkConceptConstraintsMacro();
00146 };
00147
00149 template <typename T>
00150 struct CopyConstructible
00151 {
00152 struct Constraints
00153 {
00154 void constraints()
00155 {
00156 T a(b);
00157 T* p = &a;
00158 const_constraints(a);
00159 Detail::IgnoreUnusedVariable(p);
00160 }
00161 void const_constraints(const T& a)
00162 {
00163 T c(a);
00164 const T* p = &a;
00165 Detail::IgnoreUnusedVariable(c);
00166 Detail::IgnoreUnusedVariable(p);
00167 }
00168 T b;
00169 };
00171
00172 itkConceptConstraintsMacro();
00173 };
00174
00176 template <typename T1, typename T2>
00177 struct Convertible
00178 {
00179 struct Constraints
00180 {
00181 void constraints()
00182 {
00183 T2 b = static_cast<T2>(a);
00184 Detail::IgnoreUnusedVariable(b);
00185 }
00186 T1 a;
00187 };
00188 itkConceptConstraintsMacro();
00189 };
00191
00193 template <typename T>
00194 struct Assignable
00195 {
00196 struct Constraints
00197 {
00198 void constraints()
00199 {
00200 a = a;
00201 const_constraints(a);
00202 }
00203 void const_constraints(const T& b)
00204 {
00205 a = b;
00206 }
00207 T a;
00208 };
00210
00211 itkConceptConstraintsMacro();
00212 };
00213
00216 template <typename T1, typename T2=T1>
00217 struct LessThanComparable
00218 {
00219 struct Constraints
00220 {
00221 void constraints()
00222 {
00223 Detail::RequireBooleanExpression(a < b);
00224 Detail::RequireBooleanExpression(a <= b);
00225 }
00226 T1 a;
00227 T2 b;
00228 };
00230
00231 itkConceptConstraintsMacro();
00232 };
00233
00236 template <typename T1, typename T2=T1>
00237 struct GreaterThanComparable
00238 {
00239 struct Constraints
00240 {
00241 void constraints()
00242 {
00243 Detail::RequireBooleanExpression(a > b);
00244 Detail::RequireBooleanExpression(a >= b);
00245 }
00246 T1 a;
00247 T2 b;
00248 };
00250
00251 itkConceptConstraintsMacro();
00252 };
00253
00256 template <typename T1, typename T2=T1>
00257 struct EqualityComparable
00258 {
00259 struct Constraints
00260 {
00261 void constraints()
00262 {
00263 Detail::RequireBooleanExpression(a == b);
00264 Detail::RequireBooleanExpression(a != b);
00265 }
00266 T1 a;
00267 T2 b;
00268 };
00270
00271 itkConceptConstraintsMacro();
00272 };
00273
00276 template <typename T1, typename T2=T1>
00277 struct Comparable
00278 {
00279 struct Constraints
00280 {
00281 void constraints()
00282 {
00283 Detail::RequireBooleanExpression(a < b);
00284 Detail::RequireBooleanExpression(a > b);
00285 Detail::RequireBooleanExpression(a <= b);
00286 Detail::RequireBooleanExpression(a >= b);
00287 Detail::RequireBooleanExpression(a == b);
00288 Detail::RequireBooleanExpression(a != b);
00289 }
00290 T1 a;
00291 T2 b;
00292 };
00294
00295 itkConceptConstraintsMacro();
00296 };
00297
00300 template <typename T1, typename T2=T1, typename T3=T1>
00301 struct AdditiveOperators
00302 {
00303 struct Constraints
00304 {
00305 void constraints()
00306 {
00307 a = static_cast<T3>(b + c);
00308 a = static_cast<T3>(b - c);
00309 a += static_cast<T3>(c);
00310 a -= static_cast<T3>(c);
00311 const_constraints(b, c);
00312 }
00313 void const_constraints(const T1& d, const T2& e)
00314 {
00315 a = static_cast<T3>(d + e);
00316 a = static_cast<T3>(d - e);
00317 a += static_cast<T3>(e);
00318 a -= static_cast<T3>(e);
00319 }
00320 T3 a;
00321 T1 b;
00322 T2 c;
00323 };
00325
00326 itkConceptConstraintsMacro();
00327 };
00328
00331 template <typename T1, typename T2=T1, typename T3=T1>
00332 struct MultiplyOperator
00333 {
00334 struct Constraints
00335 {
00336 void constraints()
00337 {
00338 a = static_cast<T3>(b * c);
00339 const_constraints(b, c);
00340 }
00341 void const_constraints(const T1& d, const T2& e)
00342 {
00343 a = static_cast<T3>(d * e);
00344 }
00345 T3 a;
00346 T1 b;
00347 T2 c;
00348 };
00350
00351 itkConceptConstraintsMacro();
00352 };
00353
00356 template <typename T1, typename T2=T1>
00357 struct MultiplyAndAssignOperator
00358 {
00359 struct Constraints
00360 {
00361 void constraints()
00362 {
00363 a *= static_cast<T2>(b);
00364 const_constraints(b);
00365 }
00366 void const_constraints(const T1& d)
00367 {
00368 a *= static_cast<T2>(d);
00369 }
00370 T2 a;
00371 T1 b;
00372 };
00374
00375 itkConceptConstraintsMacro();
00376 };
00377
00380 template <typename T1, typename T2=T1, typename T3=T1>
00381 struct DivisionOperators
00382 {
00383 struct Constraints
00384 {
00385 void constraints()
00386 {
00387 a = static_cast<T3>(b / c);
00388 a /= static_cast<T3>(c);
00389 const_constraints(b, c);
00390 }
00391 void const_constraints(const T1& d, const T2& e)
00392 {
00393 a = static_cast<T3>(d / e);
00394 a /= static_cast<T3>(e);
00395 }
00396 T3 a;
00397 T1 b;
00398 T2 c;
00399 };
00401
00402 itkConceptConstraintsMacro();
00403 };
00404
00407 template <typename T1, typename T2=T1, typename T3=T1>
00408 struct LogicalOperators
00409 {
00410 struct Constraints
00411 {
00412 void constraints()
00413 {
00414 a = static_cast<T3>(b & c);
00415 a = static_cast<T3>(b | c);
00416 a = static_cast<T3>(b ^ c);
00417 a &= static_cast<T3>(c);
00418 a |= static_cast<T3>(c);
00419 a ^= static_cast<T3>(c);
00420 const_constraints(b, c);
00421 }
00422 void const_constraints(const T1& d, const T2& e)
00423 {
00424 a = static_cast<T3>(d & e);
00425 a = static_cast<T3>(d | e);
00426 a = static_cast<T3>(d ^ e);
00427 a &= static_cast<T3>(e);
00428 a |= static_cast<T3>(e);
00429 a ^= static_cast<T3>(e);
00430 }
00431 T3 a;
00432 T1 b;
00433 T2 c;
00434 };
00436
00437 itkConceptConstraintsMacro();
00438 };
00439
00441 template <typename T>
00442 struct NotOperator
00443 {
00444 struct Constraints
00445 {
00446 void constraints()
00447 {
00448 a = !a;
00449 }
00450 T a;
00451 };
00452
00453 itkConceptConstraintsMacro();
00454 };
00455
00457 template <typename T>
00458 struct IncrementDecrementOperators
00459 {
00460 struct Constraints
00461 {
00462 void constraints()
00463 {
00464 a++;
00465 a--;
00466 ++a;
00467 --a;
00468 }
00469 T a;
00470 };
00471
00472 itkConceptConstraintsMacro();
00473 };
00474
00476 template <typename T>
00477 struct OStreamWritable
00478 {
00479 struct Constraints
00480 {
00481 void constraints()
00482 {
00483 std::cout << a;
00484 }
00485 T a;
00486 };
00487
00488 itkConceptConstraintsMacro();
00489 };
00490
00492 template <typename T>
00493 struct Signed
00494 {
00495 typedef Signed Self;
00496 itkStaticConstMacro(IsSigned, bool, NumericTraits<T>::is_signed);
00497 struct Constraints
00498 {
00499 typedef Detail::UniqueType_bool<true> TrueT;
00500 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsSigned)> SignedT;
00501 void constraints()
00502 {
00503 SignedT a = TrueT();
00504 Detail::IgnoreUnusedVariable(a);
00505 }
00506 };
00508
00509 itkConceptConstraintsMacro();
00510 };
00511
00513 template <typename T1, typename T2>
00514 struct SameType
00515 {
00516 struct Constraints
00517 {
00518 void constraints()
00519 {
00520 Detail::UniqueType<T1> a = Detail::UniqueType<T2>();
00521 Detail::IgnoreUnusedVariable(a);
00522 }
00523 };
00524 itkConceptConstraintsMacro();
00525 };
00527
00529 template <unsigned int D1, unsigned int D2>
00530 struct SameDimension
00531 {
00532 struct Constraints
00533 {
00534 typedef Detail::UniqueType_unsigned_int<D1> DT1;
00535 typedef Detail::UniqueType_unsigned_int<D2> DT2;
00536 void constraints()
00537 {
00538 DT1 a = DT2();
00539 Detail::IgnoreUnusedVariable(a);
00540 }
00541 };
00542 itkConceptConstraintsMacro();
00543 };
00545
00547 template <typename T>
00548 struct HasNumericTraits
00549 {
00550 struct Constraints
00551 {
00552 void constraints()
00553 {
00554 typedef typename NumericTraits<T>::ValueType ValueType;
00555 typedef typename NumericTraits<T>::PrintType PrintType;
00556 typedef typename NumericTraits<T>::AbsType AbsType;
00557 typedef typename NumericTraits<T>::AccumulateType AccumulateType;
00558 typedef typename NumericTraits<T>::RealType RealType;
00559 typedef typename NumericTraits<T>::ScalarRealType ScalarRealType;
00560 typedef typename NumericTraits<T>::FloatType FloatType;
00561 T a;
00562 bool b;
00563 a = NumericTraits<T>::Zero;
00564 a = NumericTraits<T>::One;
00565 a = NumericTraits<T>::NonpositiveMin();
00566 a = NumericTraits<T>::ZeroValue();
00567 b = NumericTraits<T>::IsPositive(a);
00568 b = NumericTraits<T>::IsNonpositive(a);
00569 b = NumericTraits<T>::IsNegative(a);
00570 b = NumericTraits<T>::IsNonnegative(a);
00571 Detail::IgnoreUnusedVariable(a);
00572 Detail::IgnoreUnusedVariable(b);
00573 }
00574 };
00576
00577 itkConceptConstraintsMacro();
00578 };
00579
00581 template <typename T>
00582 struct HasPixelTraits
00583 {
00584 struct Constraints
00585 {
00586 void constraints()
00587 {
00588 typedef typename PixelTraits<T>::ValueType ValueType;
00589 unsigned int a = PixelTraits<T>::Dimension;
00590 Detail::IgnoreUnusedVariable(a);
00591 }
00592 };
00594
00595 itkConceptConstraintsMacro();
00596 };
00597
00599 template <typename T1, typename T2>
00600 struct HasJoinTraits
00601 {
00602 struct Constraints
00603 {
00604 void constraints()
00605 {
00606 typedef typename JoinTraits<T1, T2>::ValueType ValueType;
00607 }
00608 };
00609
00610 itkConceptConstraintsMacro();
00611 };
00612
00614 template <unsigned int D1, unsigned int D2>
00615 struct SameDimensionOrMinusOne
00616 {
00617 struct Constraints
00618 {
00619 typedef Detail::UniqueType_unsigned_int< D1 > Type1;
00620 typedef Detail::UniqueType_unsigned_int< D1-1 > Type2;
00621
00622 void f( Type1 ) {}
00623 void f( Type2, int = 0 ) {}
00624
00625 void constraints()
00626 {
00627 Detail::UniqueType_unsigned_int< D2 > tt;
00628 this->f( tt );
00629 }
00630 };
00631 itkConceptConstraintsMacro();
00632 };
00633
00635 template <typename T>
00636 struct IsInteger
00637 {
00638 typedef IsInteger Self;
00639 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00640 struct Constraints
00641 {
00642 typedef Detail::UniqueType_bool<true> TrueT;
00643 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00644 void constraints()
00645 {
00646 IntegralT a = TrueT();
00647 Detail::IgnoreUnusedVariable(a);
00648 }
00649 };
00651
00652 itkConceptConstraintsMacro();
00653 };
00654
00656 template <typename T>
00657 struct IsNonInteger
00658 {
00659 typedef IsNonInteger Self;
00660 itkStaticConstMacro(NonIntegral, bool, NumericTraits<T>::is_integer);
00661 struct Constraints
00662 {
00663 typedef Detail::UniqueType_bool<false> FalseT;
00664 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(NonIntegral)> NonIntegralT;
00665 void constraints()
00666 {
00667 NonIntegralT a = FalseT();
00668 Detail::IgnoreUnusedVariable(a);
00669 }
00670 };
00672
00673 itkConceptConstraintsMacro();
00674 };
00675
00677 template <typename T>
00678 struct IsFloatingPoint
00679 {
00680 typedef IsFloatingPoint Self;
00681 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00682 itkStaticConstMacro(IsExact, bool, NumericTraits<T>::is_exact);
00683 struct Constraints
00684 {
00685 typedef Detail::UniqueType_bool<false> FalseT;
00686 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00687 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsExact)> ExactT;
00688 void constraints()
00689 {
00690 IntegralT a = FalseT();
00691 ExactT b = FalseT();
00692 Detail::IgnoreUnusedVariable(a);
00693 Detail::IgnoreUnusedVariable(b);
00694 }
00695 };
00697
00698 itkConceptConstraintsMacro();
00699 };
00700
00702 template <typename T>
00703 struct IsFixedPoint
00704 {
00705 typedef IsFixedPoint Self;
00706 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00707 itkStaticConstMacro(IsExact, bool, NumericTraits<T>::is_exact);
00708 struct Constraints
00709 {
00710 typedef Detail::UniqueType_bool<true> TrueT;
00711 typedef Detail::UniqueType_bool<false> FalseT;
00712 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00713 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsExact)> ExactT;
00714 void constraints()
00715 {
00716 IntegralT a = FalseT();
00717 ExactT b = TrueT();
00718 Detail::IgnoreUnusedVariable(a);
00719 Detail::IgnoreUnusedVariable(b);
00720 }
00721 };
00723
00724 itkConceptConstraintsMacro();
00725 };
00726
00727 }
00728
00729 }
00730
00731 #endif
00732