ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkConceptChecking.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 /*=========================================================================
00019  *
00020  *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
00021  *
00022  *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00023  *
00024  *  For complete copyright, license and disclaimer of warranty information
00025  *  please refer to the NOTICE file at the top of the ITK source tree.
00026  *
00027  *=========================================================================*/
00028 #ifndef __itkConceptChecking_h
00029 #define __itkConceptChecking_h
00030 
00031 #include "itkPixelTraits.h"
00032 #include "itkNumericTraits.h"
00033 #include <iostream>
00034 
00036 #ifndef ITK_CONCEPT_NO_CHECKING
00037 #if defined( _MSC_VER ) && !defined( __ICL )
00038 #define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00039 //TST_RMV_20100730 #elif defined(__SUNPRO_CC)
00040 //TST_RMV_20100730 #define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00041 #else
00042 #define ITK_CONCEPT_IMPLEMENTATION_STANDARD
00043 #endif
00044 #endif
00045 
00047 #if defined( ITK_CONCEPT_IMPLEMENTATION_STANDARD )
00048 
00056 // Leave ()'s off the sizeof to force the caller to pass them in the
00057 // concept argument of the itkConceptMacro.  This is necessary because
00058 // the argument may contain commas.
00059 #define itkConceptConstraintsMacro()    \
00060   template< void (Constraints::*) ( ) > \
00061   struct Enforcer {};                   \
00062   typedef Enforcer< & Constraints::constraints > EnforcerInstantiation
00063 #define itkConceptMacro(name, concept) enum { name = sizeof concept }
00064 
00065 #elif defined( ITK_CONCEPT_IMPLEMENTATION_VTABLE )
00066 
00072 #define itkConceptConstraintsMacro() \
00073   virtual void Enforcer() { &Constraints::constraints; }
00074 #define itkConceptMacro(name, concept) enum { name = sizeof concept }
00075 
00076 
00077 #elif defined( ITK_CONCEPT_IMPLEMENTATION_CALL )
00078 
00080 #define itkConceptConstraintsMacro()
00081 #define itkConceptMacro(name, concept) enum { name = 0 }
00082 
00083 #else
00084 
00086 #define itkConceptConstraintsMacro()
00087 #define itkConceptMacro(name, concept) enum { name = 0 }
00088 
00089 #endif
00090 
00091 namespace itk
00092 {
00095 namespace Concept
00096 {
00097 
00105 namespace Detail
00106 {
00107 template< typename T >
00108 struct UniqueType {};
00109 template< int >
00110 struct UniqueType_int {};
00111 template< unsigned int >
00112 struct UniqueType_unsigned_int {};
00113 template< bool >
00114 struct UniqueType_bool {};
00115 
00121 template< typename T >
00122 inline void IgnoreUnusedVariable(T) {}
00123 
00129 template< class T >
00130 void RequireBooleanExpression(const T & t)
00131 {
00132   bool x = t;
00133 
00134   IgnoreUnusedVariable(x);
00135 }
00136 }   // namespace Detail
00137 
00139 template< typename T >
00140 struct DefaultConstructible {
00141   struct Constraints {
00142     void constraints()
00143     {
00144       T a;
00145 
00146       Detail::IgnoreUnusedVariable(a);
00147     }
00148   };
00149 
00150   itkConceptConstraintsMacro();
00151 };
00152 
00154 template< typename T >
00155 struct CopyConstructible {
00156   struct Constraints {
00157     void constraints()
00158     {
00159       T  a(b);
00160       T *p = &a;
00162 
00163       const_constraints(a);
00164       Detail::IgnoreUnusedVariable(p);
00165     }
00166 
00167     void const_constraints(const T & a)
00168     {
00169       T        c(a);
00170       const T *p = &a;
00171 
00172       Detail::IgnoreUnusedVariable(c);
00173       Detail::IgnoreUnusedVariable(p);
00174     }
00175 
00176     T b;
00177   };
00178 
00179   itkConceptConstraintsMacro();
00180 };
00181 
00183 template< typename T1, typename T2 >
00184 struct Convertible {
00185   struct Constraints {
00186     void constraints()
00187     {
00188       T2 b = static_cast< T2 >( a );
00189 
00190       Detail::IgnoreUnusedVariable(b);
00191     }
00192 
00193     T1 a;
00194   };
00195   itkConceptConstraintsMacro();
00196 };
00197 
00199 template< typename T >
00200 struct Assignable {
00201   struct Constraints {
00202     void constraints()
00203     {
00204       a = a;
00205       const_constraints(a);
00206     }
00208 
00209     void const_constraints(const T & b)
00210     {
00211       a = b;
00212     }
00213 
00214     T a;
00215   };
00216 
00217   itkConceptConstraintsMacro();
00218 };
00219 
00222 template< typename T1, typename T2 = T1 >
00223 struct LessThanComparable {
00224   struct Constraints {
00225     void constraints()
00226     {
00227       Detail::RequireBooleanExpression(a < b);
00228       Detail::RequireBooleanExpression(a <= b);
00229     }
00231 
00232     T1 a;
00233     T2 b;
00234   };
00235 
00236   itkConceptConstraintsMacro();
00237 };
00238 
00241 template< typename T1, typename T2 = T1 >
00242 struct GreaterThanComparable {
00243   struct Constraints {
00244     void constraints()
00245     {
00246       Detail::RequireBooleanExpression(a > b);
00247       Detail::RequireBooleanExpression(a >= b);
00248     }
00250 
00251     T1 a;
00252     T2 b;
00253   };
00254 
00255   itkConceptConstraintsMacro();
00256 };
00257 
00260 template< typename T1, typename T2 = T1 >
00261 struct EqualityComparable {
00262   struct Constraints {
00263     void constraints()
00264     {
00265       Detail::RequireBooleanExpression(a == b);
00266       Detail::RequireBooleanExpression(a != b);
00267     }
00269 
00270     T1 a;
00271     T2 b;
00272   };
00273 
00274   itkConceptConstraintsMacro();
00275 };
00276 
00279 template< typename T1, typename T2 = T1 >
00280 struct Comparable {
00281   struct Constraints {
00282     void constraints()
00283     {
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       Detail::RequireBooleanExpression(a != b);
00290     }
00292 
00293     T1 a;
00294     T2 b;
00295   };
00296 
00297   itkConceptConstraintsMacro();
00298 };
00299 
00302 template< typename T1, typename T2 = T1, typename T3 = T1 >
00303 struct AdditiveOperators {
00304   struct Constraints {
00305     void constraints()
00306     {
00307       a = static_cast< T3 >( b + c );
00308       a = static_cast< T3 >( b - c );
00309       const_constraints(b, c);
00310     }
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     }
00318 
00319     T3 a;
00320     T1 b;
00321     T2 c;
00322   };
00323 
00324   itkConceptConstraintsMacro();
00325 };
00326 
00327 
00330 template< typename T1, typename T2 = T1>
00331 struct AdditiveAndAssignOperators {
00332   struct Constraints {
00333     void constraints()
00334     {
00335       a += c;
00336       a -= c;
00337       const_constraints(c);
00338     }
00340 
00341     void const_constraints(const T1 & d)
00342     {
00343       a += d;
00344       a -= d;
00345     }
00346 
00347     T2 a;
00348     T1 c;
00349   };
00350 
00351   itkConceptConstraintsMacro();
00352 };
00353 
00355 template< typename T1, typename T2 = T1, typename T3 = T1 >
00356 struct MultiplyOperator {
00357   struct Constraints {
00358     void constraints()
00359     {
00360       a = static_cast< T3 >( b * c );
00361       const_constraints(b, c);
00362     }
00364 
00365     void const_constraints(const T1 & d, const T2 & e)
00366     {
00367       a = static_cast< T3 >( d * e );
00368     }
00369 
00370     T3 a;
00371     T1 b;
00372     T2 c;
00373   };
00374   itkConceptConstraintsMacro();
00375 };
00376 
00378 template< typename T1, typename T2 = T1 >
00379 struct MultiplyAndAssignOperator {
00380   struct Constraints {
00381     void constraints()
00382     {
00383       a *= b;
00384       const_constraints(b);
00385     }
00387 
00388     void const_constraints(const T1 & d)
00389     {
00390       a *= d;
00391     }
00392 
00393     T2 a;
00394     T1 b;
00395   };
00396 
00397   itkConceptConstraintsMacro();
00398 };
00399 
00401 template< typename T1, typename T2 = T1, typename T3 = T1 >
00402 struct DivisionOperators {
00403   struct Constraints {
00404     void constraints()
00405     {
00406       a = static_cast< T3 >( b / c );
00407       const_constraints(b, c);
00408     }
00410 
00411     void const_constraints(const T1 & d, const T2 & e)
00412     {
00413       a = static_cast< T3 >( d / e );
00414     }
00415 
00416     T3 a;
00417     T1 b;
00418     T2 c;
00419   };
00420 
00421   itkConceptConstraintsMacro();
00422 };
00423 
00424 
00426 template< typename T1, typename T2 = T1 >
00427 struct DivisionAndAssignOperators {
00428   struct Constraints {
00429     void constraints()
00430     {
00431       a /= c;
00432       const_constraints(c);
00433     }
00435 
00436     void const_constraints(const T1 & d)
00437     {
00438       a /= d;
00439     }
00440 
00441     T1 c;
00442     T2 a;
00443   };
00444 
00445   itkConceptConstraintsMacro();
00446 };
00447 
00448 
00451 template< typename T1, typename T2 = T1, typename T3 = T1 >
00452 struct LogicalOperators {
00453   struct Constraints {
00454     void constraints()
00455     {
00456       a = static_cast< T3 >( b & c );
00457       a = static_cast< T3 >( b | c );
00458       a = static_cast< T3 >( b ^ c );
00459       a &= static_cast< T3 >( c );
00460       a |= static_cast< T3 >( c );
00461       a ^= static_cast< T3 >( c );
00462       const_constraints(b, c);
00463     }
00465 
00466     void const_constraints(const T1 & d, const T2 & e)
00467     {
00468       a = static_cast< T3 >( d & e );
00469       a = static_cast< T3 >( d | e );
00470       a = static_cast< T3 >( d ^ e );
00471       a &= static_cast< T3 >( e );
00472       a |= static_cast< T3 >( e );
00473       a ^= static_cast< T3 >( e );
00474     }
00475 
00476     T3 a;
00477     T1 b;
00478     T2 c;
00479   };
00480 
00481   itkConceptConstraintsMacro();
00482 };
00483 
00485 template< typename T1, typename T2 = T1, typename T3 = T1 >
00486 struct BracketOperator {
00487   struct Constraints {
00488     void constraints()
00489     {
00490       a = static_cast< T3 >( b[c] );
00491       const_constraints(b, c);
00492     }
00494 
00495     void const_constraints(const T1 & d, const T2 & e)
00496     {
00497       a = static_cast< T3 >( d[e] );
00498     }
00499 
00500     T3 a;
00501     T1 b;
00502     T2 c;
00503   };
00504 
00505   itkConceptConstraintsMacro();
00506 };
00507 
00509 template< typename T >
00510 struct NotOperator {
00511   struct Constraints {
00512     void constraints()
00513     {
00514       a = !a;
00515     }
00516 
00517     T a;
00518   };
00519 
00520   itkConceptConstraintsMacro();
00521 };
00522 
00524 template< typename T >
00525 struct IncrementDecrementOperators {
00526   struct Constraints {
00527     void constraints()
00528     {
00529       a++;
00530       a--;
00531       ++a;
00532       --a;
00533     }
00534 
00535     T a;
00536   };
00537 
00538   itkConceptConstraintsMacro();
00539 };
00540 
00542 template< typename T >
00543 struct OStreamWritable {
00544   struct Constraints {
00545     void constraints()
00546     {
00547       std::cout << a;
00548     }
00549 
00550     T a;
00551   };
00552 
00553   itkConceptConstraintsMacro();
00554 };
00555 
00557 template< typename T >
00558 struct Signed {
00559   typedef Signed Self;
00560   itkStaticConstMacro(IsSigned, bool, NumericTraits< T >::is_signed);
00561   struct Constraints {
00562     typedef Detail::UniqueType_bool< true >                             TrueT;
00563     typedef Detail::UniqueType_bool< itkGetStaticConstMacro(IsSigned) > SignedT;
00564     void constraints()
00565     {
00566       SignedT a = TrueT();
00568 
00569       Detail::IgnoreUnusedVariable(a);
00570     }
00571   };
00572 
00573   itkConceptConstraintsMacro();
00574 };
00575 
00577 template< typename T1, typename T2 >
00578 struct SameType {
00579   struct Constraints {
00580     void constraints()
00581     {
00582       Detail::UniqueType< T1 > a = Detail::UniqueType< T2 >();
00583       Detail::IgnoreUnusedVariable(a);
00584     }
00585   };
00586   itkConceptConstraintsMacro();
00587 };
00589 
00591 template< unsigned int D1, unsigned int D2 >
00592 struct SameDimension {
00593   struct Constraints {
00594     typedef Detail::UniqueType_unsigned_int< D1 > DT1;
00595     typedef Detail::UniqueType_unsigned_int< D2 > DT2;
00596     void constraints()
00597     {
00598       DT1 a = DT2();
00600 
00601       Detail::IgnoreUnusedVariable(a);
00602     }
00603   };
00604   itkConceptConstraintsMacro();
00605 };
00606 
00608 template< typename T >
00609 struct HasNumericTraits {
00610   struct Constraints {
00611     void constraints()
00612     {
00613       typedef typename NumericTraits< T >::ValueType      ValueType;
00614       typedef typename NumericTraits< T >::PrintType      PrintType;
00615       typedef typename NumericTraits< T >::AbsType        AbsType;
00616       typedef typename NumericTraits< T >::AccumulateType AccumulateType;
00617       typedef typename NumericTraits< T >::RealType       RealType;
00618       typedef typename NumericTraits< T >::ScalarRealType ScalarRealType;
00619       typedef typename NumericTraits< T >::FloatType      FloatType;
00620       T    a;
00621       bool b;
00622       a = NumericTraits< T >::Zero;
00623       a = NumericTraits< T >::One;
00624       a = NumericTraits< T >::NonpositiveMin();
00625       a = NumericTraits< T >::ZeroValue();
00626       b = NumericTraits< T >::IsPositive(a);
00627       b = NumericTraits< T >::IsNonpositive(a);
00628       b = NumericTraits< T >::IsNegative(a);
00629       b = NumericTraits< T >::IsNonnegative(a);
00630       Detail::IgnoreUnusedVariable(a);
00631       Detail::IgnoreUnusedVariable(b);
00632     }
00633   };
00635 
00636   itkConceptConstraintsMacro();
00637 };
00638 
00640 template< typename T >
00641 struct HasPixelTraits {
00642   struct Constraints {
00643     void constraints()
00644     {
00645       typedef typename PixelTraits< T >::ValueType ValueType;
00646       unsigned int a = PixelTraits< T >::Dimension;
00647       Detail::IgnoreUnusedVariable(a);
00648     }
00649   };
00651 
00652   itkConceptConstraintsMacro();
00653 };
00654 
00656 template< typename T >
00657 struct HasValueType {
00658   struct Constraints {
00659     void constraints()
00660     {
00661       typedef typename T::ValueType ValueType;
00662     }
00663   };
00664 
00665   itkConceptConstraintsMacro();
00666 };
00667 
00669 template< typename T >
00670 struct HasZero {
00671   struct Constraints {
00672     void constraints()
00673     {
00674       T a;
00675 
00676       a = NumericTraits< T >::Zero;
00677       Detail::IgnoreUnusedVariable(a);
00678     }
00679   };
00680 
00681   itkConceptConstraintsMacro();
00682 };
00683 
00685 template< typename T1, typename T2 >
00686 struct HasJoinTraits {
00687   struct Constraints {
00688     void constraints()
00689     {
00690       typedef typename JoinTraits< T1, T2 >::ValueType ValueType;
00691     }
00692   };
00693 
00694   itkConceptConstraintsMacro();
00695 };
00696 
00698 template< unsigned int D1, unsigned int D2 >
00699 struct SameDimensionOrMinusOne {
00700   struct Constraints {
00701     typedef Detail::UniqueType_unsigned_int< D1 >     Type1;
00702     typedef Detail::UniqueType_unsigned_int< D1 - 1 > Type2;
00703 
00704     void f(Type1) {}
00705     void f(Type2, int = 0) {}
00706 
00707     void constraints()
00708     {
00709       Detail::UniqueType_unsigned_int< D2 > tt;
00710       this->f(tt);
00711     }
00712   };
00713   itkConceptConstraintsMacro();
00714 };
00715 
00717 template< unsigned int D1, unsigned int D2 >
00718 struct SameDimensionOrMinusOneOrTwo {
00719   struct Constraints {
00720     typedef Detail::UniqueType_unsigned_int< D1 >     Type1;
00721     typedef Detail::UniqueType_unsigned_int< D1 - 1 > Type2;
00722     typedef Detail::UniqueType_unsigned_int< D1 - 2 > Type3;
00723 
00724     void f(Type1) {}
00725     void f(Type2, int = 0) {}
00726     void f(Type3, int = 0, int = 0) {}
00727 
00728     void constraints()
00729     {
00730       Detail::UniqueType_unsigned_int< D2 > tt;
00731       this->f(tt);
00732     }
00733   };
00734   itkConceptConstraintsMacro();
00735 };
00736 
00738 template< typename T >
00739 struct IsInteger {
00740   typedef IsInteger Self;
00741   itkStaticConstMacro(Integral, bool, NumericTraits< T >::is_integer);
00742   struct Constraints {
00743     typedef Detail::UniqueType_bool< true >                             TrueT;
00744     typedef Detail::UniqueType_bool< itkGetStaticConstMacro(Integral) > IntegralT;
00745     void constraints()
00746     {
00747       IntegralT a = TrueT();
00749 
00750       Detail::IgnoreUnusedVariable(a);
00751     }
00752   };
00753 
00754   itkConceptConstraintsMacro();
00755 };
00756 
00758 template< typename T >
00759 struct IsNonInteger {
00760   typedef IsNonInteger Self;
00761   itkStaticConstMacro(NonIntegral, bool, NumericTraits< T >::is_integer);
00762   struct Constraints {
00763     typedef Detail::UniqueType_bool< false >                               FalseT;
00764     typedef Detail::UniqueType_bool< itkGetStaticConstMacro(NonIntegral) > NonIntegralT;
00765     void constraints()
00766     {
00767       NonIntegralT a = FalseT();
00769 
00770       Detail::IgnoreUnusedVariable(a);
00771     }
00772   };
00773 
00774   itkConceptConstraintsMacro();
00775 };
00776 
00778 template< typename T >
00779 struct IsFloatingPoint {
00780   typedef IsFloatingPoint Self;
00781   itkStaticConstMacro(Integral, bool, NumericTraits< T >::is_integer);
00782   itkStaticConstMacro(IsExact, bool, NumericTraits< T >::is_exact);
00783   struct Constraints {
00784     typedef Detail::UniqueType_bool< false >                            FalseT;
00785     typedef Detail::UniqueType_bool< itkGetStaticConstMacro(Integral) > IntegralT;
00786     typedef Detail::UniqueType_bool< itkGetStaticConstMacro(IsExact) >  ExactT;
00787     void constraints()
00788     {
00789       IntegralT a = FalseT();
00790       ExactT    b = FalseT();
00792 
00793       Detail::IgnoreUnusedVariable(a);
00794       Detail::IgnoreUnusedVariable(b);
00795     }
00796   };
00797 
00798   itkConceptConstraintsMacro();
00799 };
00800 
00802 template< typename T >
00803 struct IsFixedPoint {
00804   typedef IsFixedPoint Self;
00805   itkStaticConstMacro(Integral, bool, NumericTraits< T >::is_integer);
00806   itkStaticConstMacro(IsExact, bool, NumericTraits< T >::is_exact);
00807   struct Constraints {
00808     typedef Detail::UniqueType_bool< true >                             TrueT;
00809     typedef Detail::UniqueType_bool< false >                            FalseT;
00810     typedef Detail::UniqueType_bool< itkGetStaticConstMacro(Integral) > IntegralT;
00811     typedef Detail::UniqueType_bool< itkGetStaticConstMacro(IsExact) >  ExactT;
00812     void constraints()
00813     {
00814       IntegralT a = FalseT();
00815       ExactT    b = TrueT();
00817 
00818       Detail::IgnoreUnusedVariable(a);
00819       Detail::IgnoreUnusedVariable(b);
00820     }
00821   };
00822 
00823   itkConceptConstraintsMacro();
00824 };
00825 } // end namespace Concept
00826 } // end namespace itk
00827 
00828 #endif
00829