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-12-08 17:16:01 $
00007   Version:   $Revision: 1.30 $
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 
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 } // end namespace Concept
00790 
00791 } // end namespace itk
00792 
00793 #endif
00794 

Generated at Tue Jul 29 19:36:12 2008 for ITK by doxygen 1.5.1 written by Dimitri van Heesch, © 1997-2000