00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00027
00029 #ifndef __TYPEDFIELDCHECK_H__
00030 #define __TYPEDFIELDCHECK_H__
00031
00032 #include <string>
00033 #include "Field.h"
00034 #include "Exception.h"
00035 #include "TypedFieldTypesTmpl.h"
00036 #include "TypedFieldAnyTmpl.h"
00037
00038 namespace H3D {
00044 H3D_API_EXCEPTION( TypedFieldError );
00045
00049 namespace TypedFieldTypeCheck {
00050
00056 H3D_API_EXCEPTION( InvalidTemplateArguments );
00057
00070 template< class Type >
00071 struct AnyNumber {
00076 static void checkTemplateArguments() {
00077 TypesType< Type >::checkTemplateArguments();
00078 }
00079
00086 static void checkType( Field *f, int index ) {
00087 TypesType< Type >::checkType( f );
00088 }
00089 };
00090
00095 template<H3D_TYPES_TEMPLATE_LIST>
00096 struct AnyNumber< H3D_TYPES_CLASS > {
00100 static void checkTemplateArguments() {
00101 H3D_TYPES_CLASS::checkTemplateArguments();
00102 }
00103
00110 static void checkType( Field *f, int index ) {
00111 int nr_types = H3D_TYPES_CLASS::numberTypes();
00112 H3D_TYPES_CLASS::checkType( f, index % nr_types );
00113 }
00114 };
00115
00122 template< class Type >
00123 struct AnyNumber< AnyNumber< Type > > {
00129 static void checkTemplateArguments() {
00130 string s="No AnyNumber statements allowed in AnyNumber statement.";
00131 throw InvalidTemplateArguments( s );
00132 }
00138 static void checkType( Field *f, int index ) {
00139 string s="No AnyNumber statements allowed in AnyNumber statement.";
00140 throw InvalidTemplateArguments( s );
00141 }
00142 };
00143
00149 template< class Type >
00150 struct AnyType {
00153
00154
00155 static void checkTemplateArguments() {}
00156
00159 static bool checkType( Field *f ) {
00160 return dynamic_cast< Type * >( f ) != NULL;
00161 }
00162 };
00163
00170 template<H3D_ANY_TEMPLATE_LIST>
00171 struct AnyType< H3D_ANY_CLASS > {
00177 static void checkTemplateArguments() {
00178 string s = "No Any statements allowed in Any statement.";
00179 throw InvalidTemplateArguments( s );
00180 }
00181
00187 static bool checkType( Field *f ) {
00188 string s = "No Any statements allowed in Any statement.";
00189 throw InvalidTemplateArguments( s );
00190 }
00191 };
00192
00199 template<H3D_TYPES_TEMPLATE_LIST>
00200 struct AnyType< H3D_TYPES_CLASS > {
00201
00207 static void checkTemplateArguments() {
00208 string s = "No Types statements allowed in Any statement.";
00209 throw InvalidTemplateArguments( s );
00210 }
00211
00217 static bool checkType( Field *f ) {
00218 string s = "No Types statements allowed in Any statement.";
00219 throw InvalidTemplateArguments( s );
00220 }
00221 };
00222
00229 template< class Type >
00230 struct AnyType< AnyNumber< Type > > {
00231
00237 static void checkTemplateArguments() {
00238 string s = "No AnyNumber statements allowed in Any statement.";
00239 throw InvalidTemplateArguments( s );
00240 }
00241
00247 static bool checkType( Field *f ) {
00248 string s = "No AnyNumber statements allowed in Any statement.";
00249 throw InvalidTemplateArguments( s );
00250 }
00251 };
00252
00258 template< class Type >
00259 struct TypesType {
00262
00263
00264 static void checkTemplateArguments() {}
00265
00268 static void checkType( Field *f ) {
00269 if( !dynamic_cast< Type * >( f ) ) {
00270 throw InvalidType( f->getTypeName(),
00271 Type::classTypeName() );
00272 }
00273 }
00274 };
00275
00280 template< H3D_ANY_TEMPLATE_LIST >
00281 struct TypesType< H3D_ANY_CLASS > {
00284 static void checkTemplateArguments() {
00285 H3D_ANY_CLASS::checkTemplateArguments();
00286 }
00287
00290 static void checkType( Field *f ) {
00291 H3D_ANY_CLASS::checkType( f );
00292 }
00293 };
00294
00301 template< H3D_TYPES_TEMPLATE_LIST >
00302 struct TypesType< H3D_TYPES_CLASS > {
00308 static void checkTemplateArguments() {
00309 string s = "No Types statements allowed in another Types statement.";
00310 throw InvalidTemplateArguments( s );
00311 }
00312
00318 static void checkType( Field *f ) {
00319 string s = "No Types statements allowed in another Types statement.";
00320 throw InvalidTemplateArguments( s );
00321 }
00322 };
00323
00331 template< class Type >
00332 struct TypesType< AnyNumber< Type > > {
00333
00339 static void checkTemplateArguments() {
00340 string s ="No AnyNumber statements allowed in Types statement.";
00341 throw InvalidTemplateArguments( s );
00342 }
00343
00349 static bool checkType( Field *f ) {
00350 string s ="No AnyNumber statements allowed in Types statement.";
00351 throw InvalidTemplateArguments( s );
00352 }
00353 };
00354
00360 template< class RequiredArgType,
00361 class OptionalArgTypes >
00362 struct TypedFieldCheck {
00366 static void checkTemplateArguments() {
00367 TypesType<RequiredArgType>::checkTemplateArguments();
00368 TypedFieldCheck< void,
00369 OptionalArgTypes >::checkTemplateArguments();
00370 }
00371
00380 static void checkFieldType( Field *f,
00381 int field_index,
00382 int type_index ) {
00383 if( field_index == type_index ) {
00384 try {
00385 TypesType<RequiredArgType>::checkType( f );
00386 } catch( ... ) {
00387 stringstream s;
00388 s << "Route " << field_index << " has type "
00389 << f->getTypeName() <<". Expecting "
00390 << RequiredArgType::classTypeName() << ".";
00391 throw H3D::TypedFieldError( s.str() );
00392 }
00393 } else {
00394 TypedFieldCheck< void,
00395 OptionalArgTypes >::checkFieldType( f,
00396 field_index,
00397 type_index + 1 );
00398 }
00399 }
00400 };
00401
00407 template< H3D_TYPES_TEMPLATE_LIST, class OptionalArgTypes >
00408 struct TypedFieldCheck< H3D_TYPES_CLASS, OptionalArgTypes >{
00412 static void checkTemplateArguments() {
00413 H3D_TYPES_CLASS::checkTemplateArguments();
00414 TypedFieldCheck< void,
00415 OptionalArgTypes >::checkTemplateArguments();
00416 }
00417
00426 static void checkFieldType( Field *f,
00427 int field_index,
00428 int type_index ) {
00429 int nr_types = H3D_TYPES_CLASS::numberTypes();
00430 if( field_index < type_index + nr_types ) {
00431 try {
00432 H3D_TYPES_CLASS::checkType( f,
00433 field_index - type_index );
00434 } catch( const InvalidType &e ) {
00435 stringstream s;
00436 s << "Route " << field_index << " has type "
00437 << e.value <<". Expecting "
00438 << e.message;
00439 throw H3D::TypedFieldError( s.str() );
00440 }
00441 } else {
00442 TypedFieldCheck< void,
00443 OptionalArgTypes >::checkFieldType( f,
00444 field_index,
00445 type_index +
00446 nr_types );
00447 }
00448 }
00449 };
00450
00457 template< class Type, class OptionalArgTypes >
00458 struct TypedFieldCheck< AnyNumber< Type >, OptionalArgTypes >{
00464 static void checkTemplateArguments() {
00465 string s = "AnyNumber statements not allowed as RequiredArgTypes";
00466 throw InvalidTemplateArguments( s );
00467 }
00468
00474 static void checkFieldType( Field *f,
00475 int field_index,
00476 int type_index ) {
00477 string s = "AnyNumber statements not allowed as RequiredArgTypes";
00478 throw InvalidTemplateArguments( s );
00479 }
00480 };
00481
00486 template<>
00487 struct TypedFieldCheck< void, void > {
00491 static void checkTemplateArguments() {}
00492
00501 static void checkFieldType( Field *f,
00502 int field_index,
00503 int type_index ) {
00504 stringstream s;
00505 s << "Too many routes. Expecing a maximum of "
00506 << type_index << " routes.";
00507 throw TypedFieldError( s.str() );
00508 }
00509 };
00510
00516 template< class OptionalArgType >
00517 struct TypedFieldCheck< void, OptionalArgType > {
00521 static void checkTemplateArguments() {
00522 TypesType< OptionalArgType >::checkTemplateArguments();
00523 }
00524
00533 static void checkFieldType( Field *f,
00534 int field_index,
00535 int type_index ) {
00536 if( field_index == type_index ) {
00537 try {
00538 TypesType<OptionalArgType>::checkType( f );
00539 } catch( ... ) {
00540 stringstream s;
00541 s << "Route " << field_index << " has type "
00542 << f->getTypeName() <<". Expecting "
00543 << OptionalArgType::classTypeName()
00544 << ".";
00545 throw H3D::TypedFieldError( s.str() );
00546 }
00547 } else {
00548 stringstream s;
00549 s << "Too many routes. Expecing a maximum of "
00550 << type_index << " routes.";
00551 throw H3D::TypedFieldError( s.str() );
00552 }
00553 }
00554 };
00555
00561 template< H3D_TYPES_TEMPLATE_LIST >
00562 struct TypedFieldCheck< void, H3D_TYPES_CLASS >{
00566 static void checkTemplateArguments() {
00567 H3D_TYPES_CLASS::checkTemplateArguments();
00568 }
00569
00578 static void checkFieldType( Field *f,
00579 int field_index,
00580 int type_index ) {
00581 int nr_types = H3D_TYPES_CLASS::numberTypes();
00582 if( field_index < type_index + nr_types ) {
00583 H3D_TYPES_CLASS::checkType( f,
00584 field_index - type_index );
00585 } else {
00586 stringstream s;
00587 s << "Too many routes. Expecing a maximum of "
00588 << type_index << " routes.";
00589 throw H3D::TypedFieldError( s.str() );
00590 }
00591 }
00592 };
00593
00599 template< class Type >
00600 struct TypedFieldCheck< void, AnyNumber< Type > >{
00604 static void checkTemplateArguments() {
00605 AnyNumber<Type>::checkTemplateArguments();
00606 }
00607
00616 static void checkFieldType( Field *f,
00617 int field_index,
00618 int type_index ) {
00619 try {
00620 AnyNumber< Type >::checkType( f, field_index - type_index );
00621 } catch( const InvalidType &e ) {
00622 stringstream s;
00623 s << "Route " << field_index << " has type "
00624 << e.value <<". Expecting "
00625 << e.message << ".";
00626 throw H3D::TypedFieldError( s.str() );
00627 }
00628 }
00629 };
00630 }
00631
00632 }
00633
00634 #endif