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
00104
template <
typename T>
inline void IgnoreUnusedVariable(T) {}
00105
00111
template <
class T>
00112
void RequireBooleanExpression(
const T& t)
00113 {
00114 bool x = t;
00115
IgnoreUnusedVariable(x);
00116 }
00117
00118 }
00119
00120
00122
template <
typename T>
00123
struct DefaultConstructible
00124 {
00125
struct Constraints
00126 {
00127
void constraints()
00128 {
00129 T a;
00130 Detail::IgnoreUnusedVariable(a);
00131 }
00132 };
00133
00134
itkConceptConstraintsMacro();
00135 };
00136
00138
template <
typename T>
00139
struct CopyConstructible
00140 {
00141
struct Constraints
00142 {
00143 void constraints()
00144 {
00145 T a(b);
00146 T* p = &a;
00147 const_constraints(a);
00148
Detail::IgnoreUnusedVariable(p);
00149 }
00150
void const_constraints(
const T& a)
00151 {
00152 T c(a);
00153
const T* p = &a;
00154 Detail::IgnoreUnusedVariable(c);
00155
Detail::IgnoreUnusedVariable(p);
00156 }
00157 T b;
00158 };
00159
00160
itkConceptConstraintsMacro();
00161 };
00162
00164
template <
typename T1,
typename T2>
00165
struct Convertible
00166 {
00167
struct Constraints
00168 {
00169
void constraints()
00170 {
00171 T2 b = a;
00172 Detail::IgnoreUnusedVariable(b);
00173 }
00174 T1
a;
00175 };
00176
itkConceptConstraintsMacro();
00177 };
00178
00180
template <
typename T>
00181
struct Assignable
00182 {
00183
struct Constraints
00184 {
00185
void constraints()
00186 {
00187 a = a;
00188
const_constraints(a);
00189 }
00190
void const_constraints(
const T& b)
00191 {
00192
a = b;
00193 }
00194 T a;
00195 };
00196
00197
itkConceptConstraintsMacro();
00198 };
00199
00201
template <
typename T>
00202
struct LessThanComparable
00203 {
00204
struct Constraints
00205 {
00206
void constraints()
00207 {
00208
Detail::RequireBooleanExpression(a < b);
00209 }
00210 T a, b;
00211 };
00212
00213 itkConceptConstraintsMacro();
00214 };
00215
00217 template <
typename T>
00218
struct EqualityComparable
00219 {
00220
struct Constraints
00221 {
00222
void constraints()
00223 {
00224
Detail::RequireBooleanExpression(a == b);
00225
Detail::RequireBooleanExpression(a != b);
00226 }
00227 T a, b;
00228 };
00229
00230 itkConceptConstraintsMacro();
00231 };
00232
00234
template <
typename T>
00235 struct Comparable
00236 {
00237
struct Constraints
00238 {
00239
void constraints()
00240 {
00241
Detail::RequireBooleanExpression(a < b);
00242
Detail::RequireBooleanExpression(a > b);
00243
Detail::RequireBooleanExpression(a <= b);
00244 Detail::RequireBooleanExpression(a >= b);
00245
Detail::RequireBooleanExpression(a == b);
00246 Detail::RequireBooleanExpression(a != b);
00247 }
00248 T
a,
b;
00249 };
00250
00251
itkConceptConstraintsMacro();
00252 };
00253
00255
template <
typename T>
00256
struct AdditiveOperators
00257 {
00258
struct Constraints
00259 {
00260
void constraints()
00261 {
00262 a = b + b;
00263 a = b - b;
00264 a += b;
00265 a -= b;
00266 const_constraints(b);
00267 }
00268 void const_constraints(
const T& c)
00269 {
00270 a = c + c;
00271
a = c - c;
00272
a += c;
00273
a -= c;
00274 }
00275 T a, b;
00276 };
00277
00278 itkConceptConstraintsMacro();
00279 };
00280
00282
template <
typename T>
00283
struct MultiplicativeOperators
00284 {
00285 struct Constraints
00286 {
00287
void constraints()
00288 {
00289 a = b * b;
00290 a = b / b;
00291 a *= b;
00292 a /= b;
00293
const_constraints(b);
00294 }
00295
void const_constraints(
const T& c)
00296 {
00297
a = c * c;
00298 a = c / c;
00299
a *= c;
00300
a /= c;
00301 }
00302 T a, b;
00303 };
00304
00305
itkConceptConstraintsMacro();
00306 };
00307
00308
00310
template <
typename T1,
typename T2>
00311
struct SameType
00312 {
00313 struct Constraints
00314 {
00315
void constraints()
00316 {
00317
Detail::UniqueType<T1> a =
Detail::UniqueType<T2>();
00318
Detail::IgnoreUnusedVariable(a);
00319 }
00320 };
00321
itkConceptConstraintsMacro();
00322 };
00323
00325 template <
unsigned int D1,
unsigned int D2>
00326
struct SameDimension
00327 {
00328
struct Constraints
00329 {
00330
typedef Detail::UniqueType_unsigned_int<D1> DT1;
00331
typedef Detail::UniqueType_unsigned_int<D2> DT2;
00332
void constraints()
00333 {
00334 DT1 a =
DT2();
00335
Detail::IgnoreUnusedVariable(a);
00336 }
00337 };
00338
itkConceptConstraintsMacro();
00339 };
00340
00341 }
00342
00343 }
00344
00345 #endif