00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#ifndef _itkConceptChecking_h
00021
#define _itkConceptChecking_h
00022
00024
#ifndef ITK_CONCEPT_NO_CHECKING
00025
# if defined(_MSC_VER) && !defined(__ICL)
00026
# define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00027
# elif defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
00028
# define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00029
# elif defined(__MWERKS__) && (__MWERKS__ <= 0x3002)
00030
# define ITK_CONCEPT_IMPLEMENTATION_VTABLE
00031
# elif defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x500)
00032
# define ITK_CONCEPT_IMPLEMENTATION_CALL
00033
# else
00034 # define ITK_CONCEPT_IMPLEMENTATION_STANDARD
00035
# endif
00036
#endif
00037
00039
#if defined(ITK_CONCEPT_IMPLEMENTATION_STANDARD)
00040
00047 # define itkConceptConstraintsMacro() \
00048
template <void (Constraints::*)()> struct Enforcer {}; \
00049
typedef Enforcer<&Constraints::constraints> EnforcerInstantiation
00050 # define itkConceptMacro(name, concept) enum { name = sizeof concept }
00051
00052
#elif defined(ITK_CONCEPT_IMPLEMENTATION_VTABLE)
00053
00059
# define itkConceptConstraintsMacro() \
00060
virtual void Enforcer() { &Constraints::constraints; }
00061
# define itkConceptMacro(name, concept) enum { name = sizeof concept }
00062
00063
#elif defined(ITK_CONCEPT_IMPLEMENTATION_CALL)
00064
00066
# define itkConceptConstraintsMacro()
00067
# define itkConceptMacro(name, concept) enum { name = 0 }
00068
00069
#else
00070
00072
# define itkConceptConstraintsMacro()
00073
# define itkConceptMacro(name, concept) enum { name = 0 }
00074
00075
#endif
00076
00077
namespace itk
00078 {
00079
00082
namespace Concept
00083 {
00084
00092
namespace Detail
00093 {
00094
00095
template <
typename T>
struct UniqueType {};
00096
template <
int>
struct UniqueType_int {};
00097 template <
unsigned int>
struct UniqueType_unsigned_int {};
00098 template <
bool>
struct UniqueType_bool {};
00099
00100
00106
template <
typename T>
inline void IgnoreUnusedVariable(T) {}
00107
00113
template <
class T>
00114
void RequireBooleanExpression(
const T& t)
00115 {
00116 bool x = t;
00117
IgnoreUnusedVariable(x);
00118 }
00119
00120 }
00121
00122
00124
template <
typename T>
00125
struct DefaultConstructible
00126 {
00127
struct Constraints
00128 {
00129
void constraints()
00130 {
00131 T a;
00132 Detail::IgnoreUnusedVariable(a);
00133 }
00134 };
00135
00136
itkConceptConstraintsMacro();
00137 };
00138
00140
template <
typename T>
00141
struct CopyConstructible
00142 {
00143
struct Constraints
00144 {
00145 void constraints()
00146 {
00147 T a(b);
00148 T* p = &a;
00149 const_constraints(a);
00150
Detail::IgnoreUnusedVariable(p);
00151 }
00152
void const_constraints(
const T& a)
00153 {
00154 T c(a);
00155
const T* p = &a;
00156 Detail::IgnoreUnusedVariable(c);
00157
Detail::IgnoreUnusedVariable(p);
00158 }
00159 T b;
00160 };
00161
00162
itkConceptConstraintsMacro();
00163 };
00164
00166
template <
typename T1,
typename T2>
00167
struct Convertible
00168 {
00169
struct Constraints
00170 {
00171
void constraints()
00172 {
00173 T2 b = a;
00174 Detail::IgnoreUnusedVariable(b);
00175 }
00176 T1
a;
00177 };
00178
itkConceptConstraintsMacro();
00179 };
00180
00182
template <
typename T>
00183
struct Assignable
00184 {
00185
struct Constraints
00186 {
00187
void constraints()
00188 {
00189 a = a;
00190
const_constraints(a);
00191 }
00192
void const_constraints(
const T& b)
00193 {
00194
a = b;
00195 }
00196 T a;
00197 };
00198
00199
itkConceptConstraintsMacro();
00200 };
00201
00203
template <
typename T>
00204
struct LessThanComparable
00205 {
00206
struct Constraints
00207 {
00208
void constraints()
00209 {
00210
Detail::RequireBooleanExpression(a < b);
00211 }
00212 T a, b;
00213 };
00214
00215 itkConceptConstraintsMacro();
00216 };
00217
00219 template <
typename T>
00220
struct EqualityComparable
00221 {
00222
struct Constraints
00223 {
00224
void constraints()
00225 {
00226
Detail::RequireBooleanExpression(a == b);
00227
Detail::RequireBooleanExpression(a != b);
00228 }
00229 T a, b;
00230 };
00231
00232 itkConceptConstraintsMacro();
00233 };
00234
00236
template <
typename T>
00237 struct Comparable
00238 {
00239
struct Constraints
00240 {
00241
void constraints()
00242 {
00243
Detail::RequireBooleanExpression(a < b);
00244
Detail::RequireBooleanExpression(a > b);
00245
Detail::RequireBooleanExpression(a <= b);
00246 Detail::RequireBooleanExpression(a >= b);
00247
Detail::RequireBooleanExpression(a == b);
00248 Detail::RequireBooleanExpression(a != b);
00249 }
00250 T
a,
b;
00251 };
00252
00253
itkConceptConstraintsMacro();
00254 };
00255
00257
template <
typename T>
00258
struct AdditiveOperators
00259 {
00260
struct Constraints
00261 {
00262
void constraints()
00263 {
00264 a = b + b;
00265 a = b - b;
00266 a += b;
00267 a -= b;
00268 const_constraints(b);
00269 }
00270 void const_constraints(
const T& c)
00271 {
00272 a = c + c;
00273
a = c - c;
00274
a += c;
00275
a -= c;
00276 }
00277 T a, b;
00278 };
00279
00280 itkConceptConstraintsMacro();
00281 };
00282
00284
template <
typename T>
00285
struct MultiplicativeOperators
00286 {
00287 struct Constraints
00288 {
00289
void constraints()
00290 {
00291 a = b * b;
00292 a = b / b;
00293 a *= b;
00294 a /= b;
00295
const_constraints(b);
00296 }
00297
void const_constraints(
const T& c)
00298 {
00299
a = c * c;
00300 a = c / c;
00301
a *= c;
00302
a /= c;
00303 }
00304 T a, b;
00305 };
00306
00307
itkConceptConstraintsMacro();
00308 };
00309
00311
template <
typename T>
00312
struct Signed
00313 {
00314
typedef Signed Self;
00315 itkStaticConstMacro(IsSigned,
bool,
NumericTraits<T>::is_signed);
00316
struct Constraints
00317 {
00318
typedef Detail::UniqueType_bool<true> TrueT;
00319
typedef Detail::UniqueType_bool<itkGetStaticConstMacro(IsSigned)> SignedT;
00320
void constraints()
00321 {
00322 SignedT a =
TrueT();
00323
Detail::IgnoreUnusedVariable(a);
00324 }
00325 };
00326
00327
itkConceptConstraintsMacro();
00328 };
00329
00331 template <
typename T1,
typename T2>
00332 struct SameType
00333 {
00334
struct Constraints
00335 {
00336
void constraints()
00337 {
00338
Detail::UniqueType<T1> a =
Detail::UniqueType<T2>();
00339
Detail::IgnoreUnusedVariable(a);
00340 }
00341 };
00342
itkConceptConstraintsMacro();
00343 };
00344
00346
template <
unsigned int D1,
unsigned int D2>
00347 struct SameDimension
00348 {
00349 struct Constraints
00350 {
00351
typedef Detail::UniqueType_unsigned_int<D1> DT1;
00352
typedef Detail::UniqueType_unsigned_int<D2> DT2;
00353
void constraints()
00354 {
00355 DT1 a =
DT2();
00356
Detail::IgnoreUnusedVariable(a);
00357 }
00358 };
00359
itkConceptConstraintsMacro();
00360 };
00361
00362 }
00363
00364 }
00365
00366 #endif