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 #include "itkNumericTraits.h"
00025 #include <iostream>
00026
00028 #ifndef ITK_CONCEPT_NO_CHECKING
00029 # if defined(_MSC_VER) && !defined(__ICL)
00030 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00031 # elif defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
00032 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00033 # elif defined(__MWERKS__) && (__MWERKS__ <= 0x3002)
00034 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00035 # elif defined(__SUNPRO_CC)
00036 # define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00037 # else
00038 # define ITK_CONCEPT_IMPLEMENTATION_STANDARD
00039 # endif
00040 #endif
00041
00043 #if defined(ITK_CONCEPT_IMPLEMENTATION_STANDARD)
00044
00052
00053
00054
00055 # define itkConceptConstraintsMacro() \
00056 template <void (Constraints::*)()> struct Enforcer {}; \
00057 typedef Enforcer<&Constraints::constraints> EnforcerInstantiation
00058 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00059
00060 #elif defined(ITK_CONCEPT_IMPLEMENTATION_VTABLE)
00061
00067 # define itkConceptConstraintsMacro() \
00068 virtual void Enforcer() { &Constraints::constraints; }
00069 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00070
00071
00072 #elif defined(ITK_CONCEPT_IMPLEMENTATION_CALL)
00073
00075 # define itkConceptConstraintsMacro()
00076 # define itkConceptMacro(name, concept) enum { name = 0 }
00077
00078 #else
00079
00081 # define itkConceptConstraintsMacro()
00082 # define itkConceptMacro(name, concept) enum { name = 0 }
00083
00084 #endif
00085
00086 namespace itk
00087 {
00088
00091 namespace Concept
00092 {
00093
00101 namespace Detail
00102 {
00103
00104 template <typename T> struct UniqueType {};
00105 template <int> struct UniqueType_int {};
00106 template <unsigned int> struct UniqueType_unsigned_int {};
00107 template <bool> struct UniqueType_bool {};
00108
00109
00115 template <typename T> inline void IgnoreUnusedVariable(T) {}
00116
00122 template <class T>
00123 void RequireBooleanExpression(const T& t)
00124 {
00125 bool x = t;
00126 IgnoreUnusedVariable(x);
00127 }
00129
00130 }
00131
00132
00134 template <typename T>
00135 struct DefaultConstructible
00136 {
00137 struct Constraints
00138 {
00139 void constraints()
00140 {
00141 T a;
00142 Detail::IgnoreUnusedVariable(a);
00143 }
00144 };
00146
00147 itkConceptConstraintsMacro();
00148 };
00149
00151 template <typename T>
00152 struct CopyConstructible
00153 {
00154 struct Constraints
00155 {
00156 void constraints()
00157 {
00158 T a(b);
00159 T* p = &a;
00160 const_constraints(a);
00161 Detail::IgnoreUnusedVariable(p);
00162 }
00163 void const_constraints(const T& a)
00164 {
00165 T c(a);
00166 const T* p = &a;
00167 Detail::IgnoreUnusedVariable(c);
00168 Detail::IgnoreUnusedVariable(p);
00169 }
00170 T b;
00171 };
00173
00174 itkConceptConstraintsMacro();
00175 };
00176
00178 template <typename T1, typename T2>
00179 struct Convertible
00180 {
00181 struct Constraints
00182 {
00183 void constraints()
00184 {
00185 T2 b = static_cast<T2>(a);
00186 Detail::IgnoreUnusedVariable(b);
00187 }
00188 T1 a;
00189 };
00190 itkConceptConstraintsMacro();
00191 };
00193
00195 template <typename T>
00196 struct Assignable
00197 {
00198 struct Constraints
00199 {
00200 void constraints()
00201 {
00202 a = a;
00203 const_constraints(a);
00204 }
00205 void const_constraints(const T& b)
00206 {
00207 a = b;
00208 }
00209 T a;
00210 };
00212
00213 itkConceptConstraintsMacro();
00214 };
00215
00218 template <typename T1, typename T2=T1>
00219 struct LessThanComparable
00220 {
00221 struct Constraints
00222 {
00223 void constraints()
00224 {
00225 Detail::RequireBooleanExpression(a < b);
00226 Detail::RequireBooleanExpression(a <= b);
00227 }
00228 T1 a;
00229 T2 b;
00230 };
00232
00233 itkConceptConstraintsMacro();
00234 };
00235
00238 template <typename T1, typename T2=T1>
00239 struct GreaterThanComparable
00240 {
00241 struct Constraints
00242 {
00243 void constraints()
00244 {
00245 Detail::RequireBooleanExpression(a > b);
00246 Detail::RequireBooleanExpression(a >= b);
00247 }
00248 T1 a;
00249 T2 b;
00250 };
00252
00253 itkConceptConstraintsMacro();
00254 };
00255
00258 template <typename T1, typename T2=T1>
00259 struct EqualityComparable
00260 {
00261 struct Constraints
00262 {
00263 void constraints()
00264 {
00265 Detail::RequireBooleanExpression(a == b);
00266 Detail::RequireBooleanExpression(a != b);
00267 }
00268 T1 a;
00269 T2 b;
00270 };
00272
00273 itkConceptConstraintsMacro();
00274 };
00275
00278 template <typename T1, typename T2=T1>
00279 struct Comparable
00280 {
00281 struct Constraints
00282 {
00283 void constraints()
00284 {
00285 Detail::RequireBooleanExpression(a < b);
00286 Detail::RequireBooleanExpression(a > b);
00287 Detail::RequireBooleanExpression(a <= b);
00288 Detail::RequireBooleanExpression(a >= b);
00289 Detail::RequireBooleanExpression(a == b);
00290 Detail::RequireBooleanExpression(a != b);
00291 }
00292 T1 a;
00293 T2 b;
00294 };
00296
00297 itkConceptConstraintsMacro();
00298 };
00299
00302 template <typename T1, typename T2=T1, typename T3=T1>
00303 struct AdditiveOperators
00304 {
00305 struct Constraints
00306 {
00307 void constraints()
00308 {
00309 a = static_cast<T3>(b + c);
00310 a = static_cast<T3>(b - c);
00311 a += static_cast<T3>(c);
00312 a -= static_cast<T3>(c);
00313 const_constraints(b, c);
00314 }
00315 void const_constraints(const T1& d, const T2& e)
00316 {
00317 a = static_cast<T3>(d + e);
00318 a = static_cast<T3>(d - e);
00319 a += static_cast<T3>(e);
00320 a -= static_cast<T3>(e);
00321 }
00322 T3 a;
00323 T1 b;
00324 T2 c;
00325 };
00327
00328 itkConceptConstraintsMacro();
00329 };
00330
00333 template <typename T1, typename T2=T1, typename T3=T1>
00334 struct MultiplyOperator
00335 {
00336 struct Constraints
00337 {
00338 void constraints()
00339 {
00340 a = static_cast<T3>(b * c);
00341 const_constraints(b, c);
00342 }
00343 void const_constraints(const T1& d, const T2& e)
00344 {
00345 a = static_cast<T3>(d * e);
00346 }
00347 T3 a;
00348 T1 b;
00349 T2 c;
00350 };
00352
00353 itkConceptConstraintsMacro();
00354 };
00355
00358 template <typename T1, typename T2=T1>
00359 struct MultiplyAndAssignOperator
00360 {
00361 struct Constraints
00362 {
00363 void constraints()
00364 {
00365 a *= static_cast<T2>(b);
00366 const_constraints(b);
00367 }
00368 void const_constraints(const T1& d)
00369 {
00370 a *= static_cast<T2>(d);
00371 }
00372 T2 a;
00373 T1 b;
00374 };
00376
00377 itkConceptConstraintsMacro();
00378 };
00379
00382 template <typename T1, typename T2=T1, typename T3=T1>
00383 struct DivisionOperators
00384 {
00385 struct Constraints
00386 {
00387 void constraints()
00388 {
00389 a = static_cast<T3>(b / c);
00390 a /= c;
00391 const_constraints(b, c);
00392 }
00393 void const_constraints(const T1& d, const T2& e)
00394 {
00395 a = static_cast<T3>(d / e);
00396 a /= e;
00397 }
00398 T3 a;
00399 T1 b;
00400 T2 c;
00401 };
00403
00404 itkConceptConstraintsMacro();
00405 };
00406
00409 template <typename T1, typename T2=T1, typename T3=T1>
00410 struct LogicalOperators
00411 {
00412 struct Constraints
00413 {
00414 void constraints()
00415 {
00416 a = static_cast<T3>(b & c);
00417 a = static_cast<T3>(b | c);
00418 a = static_cast<T3>(b ^ c);
00419 a &= static_cast<T3>(c);
00420 a |= static_cast<T3>(c);
00421 a ^= static_cast<T3>(c);
00422 const_constraints(b, c);
00423 }
00424 void const_constraints(const T1& d, const T2& e)
00425 {
00426 a = static_cast<T3>(d & e);
00427 a = static_cast<T3>(d | e);
00428 a = static_cast<T3>(d ^ e);
00429 a &= static_cast<T3>(e);
00430 a |= static_cast<T3>(e);
00431 a ^= static_cast<T3>(e);
00432 }
00433 T3 a;
00434 T1 b;
00435 T2 c;
00436 };
00438
00439 itkConceptConstraintsMacro();
00440 };
00441
00444 template <typename T1, typename T2=T1, typename T3=T1>
00445 struct BracketOperator
00446 {
00447 struct Constraints
00448 {
00449 void constraints()
00450 {
00451 a = static_cast<T3>(b [ c ]);
00452 const_constraints(b, c);
00453 }
00454 void const_constraints(const T1& d, const T2& e)
00455 {
00456 a = static_cast<T3>(b [ c ]);
00457 }
00458 T3 a;
00459 T1 b;
00460 T2 c;
00461 };
00463
00464 itkConceptConstraintsMacro();
00465 };
00466
00467
00469 template <typename T>
00470 struct NotOperator
00471 {
00472 struct Constraints
00473 {
00474 void constraints()
00475 {
00476 a = !a;
00477 }
00478 T a;
00479 };
00480
00481 itkConceptConstraintsMacro();
00482 };
00483
00485 template <typename T>
00486 struct IncrementDecrementOperators
00487 {
00488 struct Constraints
00489 {
00490 void constraints()
00491 {
00492 a++;
00493 a--;
00494 ++a;
00495 --a;
00496 }
00497 T a;
00498 };
00499
00500 itkConceptConstraintsMacro();
00501 };
00502
00504 template <typename T>
00505 struct OStreamWritable
00506 {
00507 struct Constraints
00508 {
00509 void constraints()
00510 {
00511 std::cout << a;
00512 }
00513 T a;
00514 };
00515
00516 itkConceptConstraintsMacro();
00517 };
00518
00520 template <typename T>
00521 struct Signed
00522 {
00523 typedef Signed Self;
00524 itkStaticConstMacro(IsSigned, bool, NumericTraits<T>::is_signed);
00525 struct Constraints
00526 {
00527 typedef Detail::UniqueType_bool<true> TrueT;
00528 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsSigned)> SignedT;
00529 void constraints()
00530 {
00531 SignedT a = TrueT();
00532 Detail::IgnoreUnusedVariable(a);
00533 }
00534 };
00536
00537 itkConceptConstraintsMacro();
00538 };
00539
00541 template <typename T1, typename T2>
00542 struct SameType
00543 {
00544 struct Constraints
00545 {
00546 void constraints()
00547 {
00548 Detail::UniqueType<T1> a = Detail::UniqueType<T2>();
00549 Detail::IgnoreUnusedVariable(a);
00550 }
00551 };
00552 itkConceptConstraintsMacro();
00553 };
00555
00557 template <unsigned int D1, unsigned int D2>
00558 struct SameDimension
00559 {
00560 struct Constraints
00561 {
00562 typedef Detail::UniqueType_unsigned_int<D1> DT1;
00563 typedef Detail::UniqueType_unsigned_int<D2> DT2;
00564 void constraints()
00565 {
00566 DT1 a = DT2();
00567 Detail::IgnoreUnusedVariable(a);
00568 }
00569 };
00570 itkConceptConstraintsMacro();
00571 };
00573
00575 template <typename T>
00576 struct HasNumericTraits
00577 {
00578 struct Constraints
00579 {
00580 void constraints()
00581 {
00582 typedef typename NumericTraits<T>::ValueType ValueType;
00583 typedef typename NumericTraits<T>::PrintType PrintType;
00584 typedef typename NumericTraits<T>::AbsType AbsType;
00585 typedef typename NumericTraits<T>::AccumulateType AccumulateType;
00586 typedef typename NumericTraits<T>::RealType RealType;
00587 typedef typename NumericTraits<T>::ScalarRealType ScalarRealType;
00588 typedef typename NumericTraits<T>::FloatType FloatType;
00589 T a;
00590 bool b;
00591 a = NumericTraits<T>::Zero;
00592 a = NumericTraits<T>::One;
00593 a = NumericTraits<T>::NonpositiveMin();
00594 a = NumericTraits<T>::ZeroValue();
00595 b = NumericTraits<T>::IsPositive(a);
00596 b = NumericTraits<T>::IsNonpositive(a);
00597 b = NumericTraits<T>::IsNegative(a);
00598 b = NumericTraits<T>::IsNonnegative(a);
00599 Detail::IgnoreUnusedVariable(a);
00600 Detail::IgnoreUnusedVariable(b);
00601 }
00602 };
00604
00605 itkConceptConstraintsMacro();
00606 };
00607
00609 template <typename T>
00610 struct HasPixelTraits
00611 {
00612 struct Constraints
00613 {
00614 void constraints()
00615 {
00616 typedef typename PixelTraits<T>::ValueType ValueType;
00617 unsigned int a = PixelTraits<T>::Dimension;
00618 Detail::IgnoreUnusedVariable(a);
00619 }
00620 };
00622
00623 itkConceptConstraintsMacro();
00624 };
00625
00627 template <typename T>
00628 struct HasValueType
00629 {
00630 struct Constraints
00631 {
00632 void constraints()
00633 {
00634 typedef typename T::ValueType ValueType;
00635 }
00636 };
00637
00638 itkConceptConstraintsMacro();
00639 };
00640
00641
00643 template <typename T>
00644 struct HasZero
00645 {
00646 struct Constraints
00647 {
00648 void constraints()
00649 {
00650 T a;
00651 a = NumericTraits<T>::Zero;
00652 Detail::IgnoreUnusedVariable(a);
00653 }
00654 };
00656
00657 itkConceptConstraintsMacro();
00658 };
00659
00661 template <typename T1, typename T2>
00662 struct HasJoinTraits
00663 {
00664 struct Constraints
00665 {
00666 void constraints()
00667 {
00668 typedef typename JoinTraits<T1, T2>::ValueType ValueType;
00669 }
00670 };
00671
00672 itkConceptConstraintsMacro();
00673 };
00674
00676 template <unsigned int D1, unsigned int D2>
00677 struct SameDimensionOrMinusOne
00678 {
00679 struct Constraints
00680 {
00681 typedef Detail::UniqueType_unsigned_int< D1 > Type1;
00682 typedef Detail::UniqueType_unsigned_int< D1-1 > Type2;
00683
00684 void f( Type1 ) {}
00685 void f( Type2, int = 0 ) {}
00686
00687 void constraints()
00688 {
00689 Detail::UniqueType_unsigned_int< D2 > tt;
00690 this->f( tt );
00691 }
00692 };
00693 itkConceptConstraintsMacro();
00694 };
00695
00697 template <typename T>
00698 struct IsInteger
00699 {
00700 typedef IsInteger Self;
00701 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00702 struct Constraints
00703 {
00704 typedef Detail::UniqueType_bool<true> TrueT;
00705 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00706 void constraints()
00707 {
00708 IntegralT a = TrueT();
00709 Detail::IgnoreUnusedVariable(a);
00710 }
00711 };
00713
00714 itkConceptConstraintsMacro();
00715 };
00716
00718 template <typename T>
00719 struct IsNonInteger
00720 {
00721 typedef IsNonInteger Self;
00722 itkStaticConstMacro(NonIntegral, bool, NumericTraits<T>::is_integer);
00723 struct Constraints
00724 {
00725 typedef Detail::UniqueType_bool<false> FalseT;
00726 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(NonIntegral)> NonIntegralT;
00727 void constraints()
00728 {
00729 NonIntegralT a = FalseT();
00730 Detail::IgnoreUnusedVariable(a);
00731 }
00732 };
00734
00735 itkConceptConstraintsMacro();
00736 };
00737
00739 template <typename T>
00740 struct IsFloatingPoint
00741 {
00742 typedef IsFloatingPoint Self;
00743 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00744 itkStaticConstMacro(IsExact, bool, NumericTraits<T>::is_exact);
00745 struct Constraints
00746 {
00747 typedef Detail::UniqueType_bool<false> FalseT;
00748 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00749 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsExact)> ExactT;
00750 void constraints()
00751 {
00752 IntegralT a = FalseT();
00753 ExactT b = FalseT();
00754 Detail::IgnoreUnusedVariable(a);
00755 Detail::IgnoreUnusedVariable(b);
00756 }
00757 };
00759
00760 itkConceptConstraintsMacro();
00761 };
00762
00764 template <typename T>
00765 struct IsFixedPoint
00766 {
00767 typedef IsFixedPoint Self;
00768 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00769 itkStaticConstMacro(IsExact, bool, NumericTraits<T>::is_exact);
00770 struct Constraints
00771 {
00772 typedef Detail::UniqueType_bool<true> TrueT;
00773 typedef Detail::UniqueType_bool<false> FalseT;
00774 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00775 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsExact)> ExactT;
00776 void constraints()
00777 {
00778 IntegralT a = FalseT();
00779 ExactT b = TrueT();
00780 Detail::IgnoreUnusedVariable(a);
00781 Detail::IgnoreUnusedVariable(b);
00782 }
00783 };
00785
00786 itkConceptConstraintsMacro();
00787 };
00788
00789 }
00790
00791 }
00792
00793 #endif
00794