Main Page   Groups   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Concepts

itkConceptChecking.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Insight Segmentation & Registration Toolkit
00004   Module:    $RCSfile: itkConceptChecking.h,v $
00005   Language:  C++
00006   Date:      $Date: 2007/02/13 18:34:17 $
00007   Version:   $Revision: 1.28 $
00008 
00009   Copyright (c) Insight Software Consortium. All rights reserved.
00010   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
00011 
00012   Portions of this code are covered under the VTK copyright.
00013   See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
00014 
00015      This software is distributed WITHOUT ANY WARRANTY; without even 
00016      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00017      PURPOSE.  See the above copyright notices for more information.
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 // Leave ()'s off the sizeof to force the caller to pass them in the
00051 // concept argument of the itkConceptMacro.  This is necessary because
00052 // the argument may contain commas.
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 } // namespace Detail
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 } // end namespace Concept
00788 
00789 } // end namespace itk
00790 
00791 #endif
00792 

Generated at Sun Sep 23 12:14:48 2007 for ITK by doxygen 1.5.1 written by Dimitri van Heesch, © 1997-2000