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
00442 template <typename T1, typename T2=T1, typename T3=T1>
00443 struct BracketOperator
00444 {
00445 struct Constraints
00446 {
00447 void constraints()
00448 {
00449 a = static_cast<T3>(b [ c ]);
00450 const_constraints(b, c);
00451 }
00452 void const_constraints(const T1& d, const T2& e)
00453 {
00454 a = static_cast<T3>(b [ c ]);
00455 }
00456 T3 a;
00457 T1 b;
00458 T2 c;
00459 };
00461
00462 itkConceptConstraintsMacro();
00463 };
00464
00465
00467 template <typename T>
00468 struct NotOperator
00469 {
00470 struct Constraints
00471 {
00472 void constraints()
00473 {
00474 a = !a;
00475 }
00476 T a;
00477 };
00478
00479 itkConceptConstraintsMacro();
00480 };
00481
00483 template <typename T>
00484 struct IncrementDecrementOperators
00485 {
00486 struct Constraints
00487 {
00488 void constraints()
00489 {
00490 a++;
00491 a--;
00492 ++a;
00493 --a;
00494 }
00495 T a;
00496 };
00497
00498 itkConceptConstraintsMacro();
00499 };
00500
00502 template <typename T>
00503 struct OStreamWritable
00504 {
00505 struct Constraints
00506 {
00507 void constraints()
00508 {
00509 std::cout << a;
00510 }
00511 T a;
00512 };
00513
00514 itkConceptConstraintsMacro();
00515 };
00516
00518 template <typename T>
00519 struct Signed
00520 {
00521 typedef Signed Self;
00522 itkStaticConstMacro(IsSigned, bool, NumericTraits<T>::is_signed);
00523 struct Constraints
00524 {
00525 typedef Detail::UniqueType_bool<true> TrueT;
00526 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsSigned)> SignedT;
00527 void constraints()
00528 {
00529 SignedT a = TrueT();
00530 Detail::IgnoreUnusedVariable(a);
00531 }
00532 };
00534
00535 itkConceptConstraintsMacro();
00536 };
00537
00539 template <typename T1, typename T2>
00540 struct SameType
00541 {
00542 struct Constraints
00543 {
00544 void constraints()
00545 {
00546 Detail::UniqueType<T1> a = Detail::UniqueType<T2>();
00547 Detail::IgnoreUnusedVariable(a);
00548 }
00549 };
00550 itkConceptConstraintsMacro();
00551 };
00553
00555 template <unsigned int D1, unsigned int D2>
00556 struct SameDimension
00557 {
00558 struct Constraints
00559 {
00560 typedef Detail::UniqueType_unsigned_int<D1> DT1;
00561 typedef Detail::UniqueType_unsigned_int<D2> DT2;
00562 void constraints()
00563 {
00564 DT1 a = DT2();
00565 Detail::IgnoreUnusedVariable(a);
00566 }
00567 };
00568 itkConceptConstraintsMacro();
00569 };
00571
00573 template <typename T>
00574 struct HasNumericTraits
00575 {
00576 struct Constraints
00577 {
00578 void constraints()
00579 {
00580 typedef typename NumericTraits<T>::ValueType ValueType;
00581 typedef typename NumericTraits<T>::PrintType PrintType;
00582 typedef typename NumericTraits<T>::AbsType AbsType;
00583 typedef typename NumericTraits<T>::AccumulateType AccumulateType;
00584 typedef typename NumericTraits<T>::RealType RealType;
00585 typedef typename NumericTraits<T>::ScalarRealType ScalarRealType;
00586 typedef typename NumericTraits<T>::FloatType FloatType;
00587 T a;
00588 bool b;
00589 a = NumericTraits<T>::Zero;
00590 a = NumericTraits<T>::One;
00591 a = NumericTraits<T>::NonpositiveMin();
00592 a = NumericTraits<T>::ZeroValue();
00593 b = NumericTraits<T>::IsPositive(a);
00594 b = NumericTraits<T>::IsNonpositive(a);
00595 b = NumericTraits<T>::IsNegative(a);
00596 b = NumericTraits<T>::IsNonnegative(a);
00597 Detail::IgnoreUnusedVariable(a);
00598 Detail::IgnoreUnusedVariable(b);
00599 }
00600 };
00602
00603 itkConceptConstraintsMacro();
00604 };
00605
00607 template <typename T>
00608 struct HasPixelTraits
00609 {
00610 struct Constraints
00611 {
00612 void constraints()
00613 {
00614 typedef typename PixelTraits<T>::ValueType ValueType;
00615 unsigned int a = PixelTraits<T>::Dimension;
00616 Detail::IgnoreUnusedVariable(a);
00617 }
00618 };
00620
00621 itkConceptConstraintsMacro();
00622 };
00623
00625 template <typename T>
00626 struct HasValueType
00627 {
00628 struct Constraints
00629 {
00630 void constraints()
00631 {
00632 typedef typename T::ValueType ValueType;
00633 }
00634 };
00635
00636 itkConceptConstraintsMacro();
00637 };
00638
00639
00641 template <typename T>
00642 struct HasZero
00643 {
00644 struct Constraints
00645 {
00646 void constraints()
00647 {
00648 T a;
00649 a = NumericTraits<T>::Zero;
00650 Detail::IgnoreUnusedVariable(a);
00651 }
00652 };
00654
00655 itkConceptConstraintsMacro();
00656 };
00657
00659 template <typename T1, typename T2>
00660 struct HasJoinTraits
00661 {
00662 struct Constraints
00663 {
00664 void constraints()
00665 {
00666 typedef typename JoinTraits<T1, T2>::ValueType ValueType;
00667 }
00668 };
00669
00670 itkConceptConstraintsMacro();
00671 };
00672
00674 template <unsigned int D1, unsigned int D2>
00675 struct SameDimensionOrMinusOne
00676 {
00677 struct Constraints
00678 {
00679 typedef Detail::UniqueType_unsigned_int< D1 > Type1;
00680 typedef Detail::UniqueType_unsigned_int< D1-1 > Type2;
00681
00682 void f( Type1 ) {}
00683 void f( Type2, int = 0 ) {}
00684
00685 void constraints()
00686 {
00687 Detail::UniqueType_unsigned_int< D2 > tt;
00688 this->f( tt );
00689 }
00690 };
00691 itkConceptConstraintsMacro();
00692 };
00693
00695 template <typename T>
00696 struct IsInteger
00697 {
00698 typedef IsInteger Self;
00699 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00700 struct Constraints
00701 {
00702 typedef Detail::UniqueType_bool<true> TrueT;
00703 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00704 void constraints()
00705 {
00706 IntegralT a = TrueT();
00707 Detail::IgnoreUnusedVariable(a);
00708 }
00709 };
00711
00712 itkConceptConstraintsMacro();
00713 };
00714
00716 template <typename T>
00717 struct IsNonInteger
00718 {
00719 typedef IsNonInteger Self;
00720 itkStaticConstMacro(NonIntegral, bool, NumericTraits<T>::is_integer);
00721 struct Constraints
00722 {
00723 typedef Detail::UniqueType_bool<false> FalseT;
00724 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(NonIntegral)> NonIntegralT;
00725 void constraints()
00726 {
00727 NonIntegralT a = FalseT();
00728 Detail::IgnoreUnusedVariable(a);
00729 }
00730 };
00732
00733 itkConceptConstraintsMacro();
00734 };
00735
00737 template <typename T>
00738 struct IsFloatingPoint
00739 {
00740 typedef IsFloatingPoint Self;
00741 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00742 itkStaticConstMacro(IsExact, bool, NumericTraits<T>::is_exact);
00743 struct Constraints
00744 {
00745 typedef Detail::UniqueType_bool<false> FalseT;
00746 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00747 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsExact)> ExactT;
00748 void constraints()
00749 {
00750 IntegralT a = FalseT();
00751 ExactT b = FalseT();
00752 Detail::IgnoreUnusedVariable(a);
00753 Detail::IgnoreUnusedVariable(b);
00754 }
00755 };
00757
00758 itkConceptConstraintsMacro();
00759 };
00760
00762 template <typename T>
00763 struct IsFixedPoint
00764 {
00765 typedef IsFixedPoint Self;
00766 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00767 itkStaticConstMacro(IsExact, bool, NumericTraits<T>::is_exact);
00768 struct Constraints
00769 {
00770 typedef Detail::UniqueType_bool<true> TrueT;
00771 typedef Detail::UniqueType_bool<false> FalseT;
00772 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00773 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsExact)> ExactT;
00774 void constraints()
00775 {
00776 IntegralT a = FalseT();
00777 ExactT b = TrueT();
00778 Detail::IgnoreUnusedVariable(a);
00779 Detail::IgnoreUnusedVariable(b);
00780 }
00781 };
00783
00784 itkConceptConstraintsMacro();
00785 };
00786
00787 }
00788
00789 }
00790
00791 #endif
00792