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: 2006/04/03 13:08:09 $
00007   Version:   $Revision: 1.25 $
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 
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 } // end namespace Concept
00728 
00729 } // end namespace itk
00730 
00731 #endif
00732 

Generated at Fri Sep 8 02:52:39 2006 for ITK by doxygen 1.4.7 written by Dimitri van Heesch, © 1997-2000