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: 2008-10-13 15:36:31 $
00007   Version:   $Revision: 1.31 $
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 #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 // Leave ()'s off the sizeof to force the caller to pass them in the
00053 // concept argument of the itkConceptMacro.  This is necessary because
00054 // the argument may contain commas.
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 } // namespace Detail
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>(b [ c ]);
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 } // end namespace Concept
00785 
00786 } // end namespace itk
00787 
00788 #endif
00789 

Generated at Wed Nov 5 20:55:12 2008 for ITK by doxygen 1.5.1 written by Dimitri van Heesch, © 1997-2000