ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
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