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
00332 template <typename T1, typename T2=T1, typename T3=T1>
00333 struct MultiplyOperator
00334 {
00335 struct Constraints
00336 {
00337 void constraints()
00338 {
00339 a = static_cast<T3>(b * c);
00340 const_constraints(b, c);
00341 }
00342 void const_constraints(const T1& d, const T2& e)
00343 {
00344 a = static_cast<T3>(d * e);
00345 }
00346 T3 a;
00347 T1 b;
00348 T2 c;
00349 };
00350 itkConceptConstraintsMacro();
00351 };
00353
00355 template <typename T1, typename T2=T1>
00356 struct MultiplyAndAssignOperator
00357 {
00358 struct Constraints
00359 {
00360 void constraints()
00361 {
00362 a *= static_cast<T2>(b);
00363 const_constraints(b);
00364 }
00365 void const_constraints(const T1& d)
00366 {
00367 a *= static_cast<T2>(d);
00368 }
00369 T2 a;
00370 T1 b;
00371 };
00373
00374 itkConceptConstraintsMacro();
00375 };
00376
00378 template <typename T1, typename T2=T1, typename T3=T1>
00379 struct DivisionOperators
00380 {
00381 struct Constraints
00382 {
00383 void constraints()
00384 {
00385 a = static_cast<T3>(b / c);
00386 a /= c;
00387 const_constraints(b, c);
00388 }
00389 void const_constraints(const T1& d, const T2& e)
00390 {
00391 a = static_cast<T3>(d / e);
00392 a /= e;
00393 }
00394 T3 a;
00395 T1 b;
00396 T2 c;
00397 };
00399
00400 itkConceptConstraintsMacro();
00401 };
00402
00405 template <typename T1, typename T2=T1, typename T3=T1>
00406 struct LogicalOperators
00407 {
00408 struct Constraints
00409 {
00410 void constraints()
00411 {
00412 a = static_cast<T3>(b & c);
00413 a = static_cast<T3>(b | c);
00414 a = static_cast<T3>(b ^ c);
00415 a &= static_cast<T3>(c);
00416 a |= static_cast<T3>(c);
00417 a ^= static_cast<T3>(c);
00418 const_constraints(b, c);
00419 }
00420 void const_constraints(const T1& d, const T2& e)
00421 {
00422 a = static_cast<T3>(d & e);
00423 a = static_cast<T3>(d | e);
00424 a = static_cast<T3>(d ^ e);
00425 a &= static_cast<T3>(e);
00426 a |= static_cast<T3>(e);
00427 a ^= static_cast<T3>(e);
00428 }
00429 T3 a;
00430 T1 b;
00431 T2 c;
00432 };
00434
00435 itkConceptConstraintsMacro();
00436 };
00437
00439 template <typename T1, typename T2=T1, typename T3=T1>
00440 struct BracketOperator
00441 {
00442 struct Constraints
00443 {
00444 void constraints()
00445 {
00446 a = static_cast<T3>(b [ c ]);
00447 const_constraints(b, c);
00448 }
00449 void const_constraints(const T1& d, const T2& e)
00450 {
00451 a = static_cast<T3>(d [ e ]);
00452 }
00453 T3 a;
00454 T1 b;
00455 T2 c;
00456 };
00458
00459 itkConceptConstraintsMacro();
00460 };
00461
00462
00464 template <typename T>
00465 struct NotOperator
00466 {
00467 struct Constraints
00468 {
00469 void constraints()
00470 {
00471 a = !a;
00472 }
00473 T a;
00474 };
00475
00476 itkConceptConstraintsMacro();
00477 };
00478
00480 template <typename T>
00481 struct IncrementDecrementOperators
00482 {
00483 struct Constraints
00484 {
00485 void constraints()
00486 {
00487 a++;
00488 a--;
00489 ++a;
00490 --a;
00491 }
00492 T a;
00493 };
00494
00495 itkConceptConstraintsMacro();
00496 };
00497
00499 template <typename T>
00500 struct OStreamWritable
00501 {
00502 struct Constraints
00503 {
00504 void constraints()
00505 {
00506 std::cout << a;
00507 }
00508 T a;
00509 };
00510
00511 itkConceptConstraintsMacro();
00512 };
00513
00515 template <typename T>
00516 struct Signed
00517 {
00518 typedef Signed Self;
00519 itkStaticConstMacro(IsSigned, bool, NumericTraits<T>::is_signed);
00520 struct Constraints
00521 {
00522 typedef Detail::UniqueType_bool<true> TrueT;
00523 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsSigned)> SignedT;
00524 void constraints()
00525 {
00526 SignedT a = TrueT();
00527 Detail::IgnoreUnusedVariable(a);
00528 }
00529 };
00531
00532 itkConceptConstraintsMacro();
00533 };
00534
00536 template <typename T1, typename T2>
00537 struct SameType
00538 {
00539 struct Constraints
00540 {
00541 void constraints()
00542 {
00543 Detail::UniqueType<T1> a = Detail::UniqueType<T2>();
00544 Detail::IgnoreUnusedVariable(a);
00545 }
00546 };
00547 itkConceptConstraintsMacro();
00548 };
00550
00552 template <unsigned int D1, unsigned int D2>
00553 struct SameDimension
00554 {
00555 struct Constraints
00556 {
00557 typedef Detail::UniqueType_unsigned_int<D1> DT1;
00558 typedef Detail::UniqueType_unsigned_int<D2> DT2;
00559 void constraints()
00560 {
00561 DT1 a = DT2();
00562 Detail::IgnoreUnusedVariable(a);
00563 }
00564 };
00565 itkConceptConstraintsMacro();
00566 };
00568
00570 template <typename T>
00571 struct HasNumericTraits
00572 {
00573 struct Constraints
00574 {
00575 void constraints()
00576 {
00577 typedef typename NumericTraits<T>::ValueType ValueType;
00578 typedef typename NumericTraits<T>::PrintType PrintType;
00579 typedef typename NumericTraits<T>::AbsType AbsType;
00580 typedef typename NumericTraits<T>::AccumulateType AccumulateType;
00581 typedef typename NumericTraits<T>::RealType RealType;
00582 typedef typename NumericTraits<T>::ScalarRealType ScalarRealType;
00583 typedef typename NumericTraits<T>::FloatType FloatType;
00584 T a;
00585 bool b;
00586 a = NumericTraits<T>::Zero;
00587 a = NumericTraits<T>::One;
00588 a = NumericTraits<T>::NonpositiveMin();
00589 a = NumericTraits<T>::ZeroValue();
00590 b = NumericTraits<T>::IsPositive(a);
00591 b = NumericTraits<T>::IsNonpositive(a);
00592 b = NumericTraits<T>::IsNegative(a);
00593 b = NumericTraits<T>::IsNonnegative(a);
00594 Detail::IgnoreUnusedVariable(a);
00595 Detail::IgnoreUnusedVariable(b);
00596 }
00597 };
00599
00600 itkConceptConstraintsMacro();
00601 };
00602
00604 template <typename T>
00605 struct HasPixelTraits
00606 {
00607 struct Constraints
00608 {
00609 void constraints()
00610 {
00611 typedef typename PixelTraits<T>::ValueType ValueType;
00612 unsigned int a = PixelTraits<T>::Dimension;
00613 Detail::IgnoreUnusedVariable(a);
00614 }
00615 };
00617
00618 itkConceptConstraintsMacro();
00619 };
00620
00622 template <typename T>
00623 struct HasValueType
00624 {
00625 struct Constraints
00626 {
00627 void constraints()
00628 {
00629 typedef typename T::ValueType ValueType;
00630 }
00631 };
00632
00633 itkConceptConstraintsMacro();
00634 };
00635
00636
00638 template <typename T>
00639 struct HasZero
00640 {
00641 struct Constraints
00642 {
00643 void constraints()
00644 {
00645 T a;
00646 a = NumericTraits<T>::Zero;
00647 Detail::IgnoreUnusedVariable(a);
00648 }
00649 };
00651
00652 itkConceptConstraintsMacro();
00653 };
00654
00656 template <typename T1, typename T2>
00657 struct HasJoinTraits
00658 {
00659 struct Constraints
00660 {
00661 void constraints()
00662 {
00663 typedef typename JoinTraits<T1, T2>::ValueType ValueType;
00664 }
00665 };
00666
00667 itkConceptConstraintsMacro();
00668 };
00669
00671 template <unsigned int D1, unsigned int D2>
00672 struct SameDimensionOrMinusOne
00673 {
00674 struct Constraints
00675 {
00676 typedef Detail::UniqueType_unsigned_int< D1 > Type1;
00677 typedef Detail::UniqueType_unsigned_int< D1-1 > Type2;
00678
00679 void f( Type1 ) {}
00680 void f( Type2, int = 0 ) {}
00681
00682 void constraints()
00683 {
00684 Detail::UniqueType_unsigned_int< D2 > tt;
00685 this->f( tt );
00686 }
00687 };
00688 itkConceptConstraintsMacro();
00689 };
00690
00692 template <typename T>
00693 struct IsInteger
00694 {
00695 typedef IsInteger Self;
00696 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00697 struct Constraints
00698 {
00699 typedef Detail::UniqueType_bool<true> TrueT;
00700 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00701 void constraints()
00702 {
00703 IntegralT a = TrueT();
00704 Detail::IgnoreUnusedVariable(a);
00705 }
00706 };
00708
00709 itkConceptConstraintsMacro();
00710 };
00711
00713 template <typename T>
00714 struct IsNonInteger
00715 {
00716 typedef IsNonInteger Self;
00717 itkStaticConstMacro(NonIntegral, bool, NumericTraits<T>::is_integer);
00718 struct Constraints
00719 {
00720 typedef Detail::UniqueType_bool<false> FalseT;
00721 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(NonIntegral)> NonIntegralT;
00722 void constraints()
00723 {
00724 NonIntegralT a = FalseT();
00725 Detail::IgnoreUnusedVariable(a);
00726 }
00727 };
00729
00730 itkConceptConstraintsMacro();
00731 };
00732
00734 template <typename T>
00735 struct IsFloatingPoint
00736 {
00737 typedef IsFloatingPoint Self;
00738 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00739 itkStaticConstMacro(IsExact, bool, NumericTraits<T>::is_exact);
00740 struct Constraints
00741 {
00742 typedef Detail::UniqueType_bool<false> FalseT;
00743 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00744 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsExact)> ExactT;
00745 void constraints()
00746 {
00747 IntegralT a = FalseT();
00748 ExactT b = FalseT();
00749 Detail::IgnoreUnusedVariable(a);
00750 Detail::IgnoreUnusedVariable(b);
00751 }
00752 };
00754
00755 itkConceptConstraintsMacro();
00756 };
00757
00759 template <typename T>
00760 struct IsFixedPoint
00761 {
00762 typedef IsFixedPoint Self;
00763 itkStaticConstMacro(Integral, bool, NumericTraits<T>::is_integer);
00764 itkStaticConstMacro(IsExact, bool, NumericTraits<T>::is_exact);
00765 struct Constraints
00766 {
00767 typedef Detail::UniqueType_bool<true> TrueT;
00768 typedef Detail::UniqueType_bool<false> FalseT;
00769 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(Integral)> IntegralT;
00770 typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsExact)> ExactT;
00771 void constraints()
00772 {
00773 IntegralT a = FalseT();
00774 ExactT b = TrueT();
00775 Detail::IgnoreUnusedVariable(a);
00776 Detail::IgnoreUnusedVariable(b);
00777 }
00778 };
00780
00781 itkConceptConstraintsMacro();
00782 };
00783
00784 }
00785
00786 }
00787
00788 #endif
00789