TypedFieldCheck.h

Go to the documentation of this file.
00001 
00002 //    Copyright 2004, SenseGraphics AB
00003 //
00004 //    This file is part of H3D API.
00005 //
00006 //    H3D API is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    H3D API is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with H3D API; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 //
00020 //    A commercial license is also available. Please contact us at 
00021 //    www.sensegraphics.com for more information.
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       //  It is correct in this case since it is a normal type
00154       //  (all illegal types are handled as template specialisations ).
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       //  It is correct in this case since it is a normal types 
00263       //  (all illegal types are handled as template specialisations ).
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

Generated on Thu Aug 24 12:38:34 2006 for H3D API by  doxygen 1.4.5