Go to the documentation of this file.00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "CondCore/ORA/interface/Reference.h"
00003 #include "CondCore/ORA/interface/NamedRef.h"
00004 #include "FWCore/PluginManager/interface/PluginCapabilities.h"
00005 #include "ClassUtils.h"
00006
00007 #include <cxxabi.h>
00008
00009 #include "Reflex/Object.h"
00010 #include "Reflex/Base.h"
00011
00012 ora::RflxDeleter::RflxDeleter( const Reflex::Type& type ):
00013 m_type( type ){
00014 }
00015
00016 ora::RflxDeleter::RflxDeleter( const RflxDeleter& rhs ):
00017 m_type( rhs.m_type ){
00018 }
00019
00020 ora::RflxDeleter::~RflxDeleter(){
00021 }
00022
00023 void ora::RflxDeleter::operator()( void* ptr ){
00024 m_type.Destruct( ptr );
00025 }
00026
00027 void ora::ClassUtils::loadDictionary( const std::string& className ){
00028 static std::string const prefix("LCGReflex/");
00029 edmplugin::PluginCapabilities::get()->load(prefix + className);
00030 }
00031
00032 void* ora::ClassUtils::upCast( const Reflex::Type& type,
00033 void* ptr,
00034 const Reflex::Type& castType ){
00035 void* ret = 0;
00036 if( type == castType ){
00037 ret = ptr;
00038 } else if( type.HasBase( castType )){
00039 Reflex::Object theObj( type, ptr );
00040 ret = theObj.CastObject( castType ).Address();
00041 }
00042 return ret;
00043 }
00044
00045 bool ora::ClassUtils::isType( const Reflex::Type& type,
00046 const Reflex::Type& baseType ){
00047 bool ret = false;
00048 if( type == baseType || type.HasBase( baseType )){
00049 ret = true;
00050 }
00051 return ret;
00052 }
00053
00054 bool ora::ClassUtils::checkMappedType( const Reflex::Type& type,
00055 const std::string& mappedTypeName ){
00056 if( isTypeString( type ) ){
00057 return (mappedTypeName=="std::basic_string<char>" || mappedTypeName=="basic_string<char>" || mappedTypeName=="std::string" || mappedTypeName=="string");
00058 } else if ( type.IsEnum() ){
00059 return mappedTypeName=="int";
00060 } else if ( isTypeOraVector( type ) ){
00061 return isTypeNameOraVector( mappedTypeName );
00062 } else {
00063 return type.Name(Reflex::SCOPED)==mappedTypeName;
00064 }
00065 }
00066
00067 bool ora::ClassUtils::findBaseType( Reflex::Type& type, Reflex::Type& baseType, Reflex::OffsetFunction& func ){
00068 bool found = false;
00069 for ( unsigned int i=0;i<type.BaseSize() && !found; i++){
00070 Reflex::Base base = type.BaseAt(i);
00071 Reflex::Type bt = resolvedType( base.ToType() );
00072 if( bt == baseType ){
00073 func = base.OffsetFP();
00074 found = true;
00075 } else {
00076 found = findBaseType( bt, baseType, func );
00077 }
00078 }
00079 return found;
00080 }
00081
00082 std::string ora::ClassUtils::demangledName( const std::type_info& typeInfo ){
00083 int status = 0;
00084 std::string ret("");
00085 char* realname = abi::__cxa_demangle( typeInfo.name(), 0, 0, &status);
00086 if( status == 0 && realname ){
00087 ret = realname;
00088 free(realname);
00089 }
00090 return ret;
00091 }
00092
00093 Reflex::Type ora::ClassUtils::lookupDictionary( const std::type_info& typeInfo, bool throwFlag ){
00094 Reflex::Type type = Reflex::Type::ByTypeInfo( typeInfo );
00095 if( typeInfo == typeid(std::string) ){
00096
00097 type = Reflex::Type::ByName("std::string");
00098 }
00099 if( !type ){
00100 loadDictionary( demangledName(typeInfo) );
00101 type = Reflex::Type::ByTypeInfo( typeInfo );
00102 }
00103 if( !type && throwFlag ){
00104 throwException( "Class \""+demangledName(typeInfo)+"\" has not been found in the dictionary.",
00105 "ClassUtils::lookupDictionary" );
00106 }
00107 return type;
00108 }
00109
00110 Reflex::Type ora::ClassUtils::lookupDictionary( const std::string& className, bool throwFlag ){
00111 Reflex::Type type = Reflex::Type::ByName( className );
00112 if( className == "std::basic_string<char>" ){
00113
00114 type = Reflex::Type::ByName("std::string");
00115 }
00116 if( !type ){
00117 loadDictionary( className );
00118 type = Reflex::Type::ByName( className );
00119 }
00120 if( !type && throwFlag ){
00121 throwException( "Class \""+className+"\" has not been found in the dictionary.",
00122 "ClassUtils::lookupDictionary" );
00123 }
00124 return type;
00125 }
00126
00127 void* ora::ClassUtils::constructObject( const Reflex::Type& typ ){
00128 void* ptr = 0;
00129 if( typ.Name(Reflex::SCOPED)=="std::string"){
00130 ptr = new std::string("");
00131 } else {
00132 ptr = typ.Construct().Address();
00133 }
00134 return ptr;
00135 }
00136
00137 bool ora::ClassUtils::isTypeString(const Reflex::Type& typ){
00138 std::string name = typ.Name(Reflex::SCOPED|Reflex::FINAL);
00139 return ( name == "std::string" ||
00140 name == "std::basic_string<char>" );
00141 }
00142
00143 bool ora::ClassUtils::isTypePrimitive(const Reflex::Type& typ){
00144 return ( typ.IsFundamental() || typ.IsEnum() || isTypeString( typ ) );
00145 }
00146
00147 bool ora::ClassUtils::isTypeContainer(const Reflex::Type& typ){
00148 Reflex::TypeTemplate templ = typ.TemplateFamily();
00149 if (! templ) {
00150 return false;
00151 } else {
00152 std::string contName = templ.Name(Reflex::SCOPED|Reflex::FINAL);
00153 if( contName == "std::vector" ||
00154 contName == "std::list" ||
00155 contName == "std::deque" ||
00156 contName == "std::stack" ||
00157 contName == "std::set" ||
00158 contName == "std::multiset" ||
00159 contName == "__gnu_cxx::hash_set" ||
00160 contName == "__gnu_cxx::hash_multiset" ||
00161 contName == "std::map" ||
00162 contName == "std::multimap" ||
00163 contName == "__gnu_cxx::hash_map" ||
00164 contName == "__gnu_cxx::hash_multimap" ||
00165 contName == "ora::PVector" ||
00166 contName == "ora::QueryableVector" ){
00167 return true;
00168 }
00169 }
00170 return false;
00171 }
00172
00173 bool ora::ClassUtils::isTypeKeyedContainer(const Reflex::Type& typ){
00174 Reflex::TypeTemplate tt = typ.TemplateFamily();
00175 if (! tt) {
00176 return false;
00177 } else {
00178 std::string contName = tt.Name(Reflex::SCOPED|Reflex::FINAL);
00179 if( contName == "std::map" ||
00180 contName == "std::multimap" ||
00181 contName == "std::set" ||
00182 contName == "std::multiset" ||
00183 contName == "__gnu_cxx::hash_set" ||
00184 contName == "__gnu_cxx::hash_multiset" ||
00185 contName == "__gnu_cxx::hash_map" ||
00186 contName == "__gnu_cxx::hash_multimap" ){
00187 return true;
00188 }
00189 }
00190 return false;
00191 }
00192
00193 bool ora::ClassUtils::isTypeNonKeyedContainer(const Reflex::Type& typ){
00194 Reflex::TypeTemplate templ = typ.TemplateFamily();
00195 if (! templ) {
00196 return false;
00197 } else {
00198 std::string contName = templ.Name(Reflex::SCOPED|Reflex::FINAL);
00199 if( contName == "std::vector" ||
00200 contName == "std::list" ||
00201 contName == "std::deque" ||
00202 contName == "std::stack" ||
00203 contName == "ora::PVector" ||
00204 contName == "ora::QueryableVector" ){
00205 return true;
00206 }
00207 }
00208 return false;
00209 }
00210
00211 bool ora::ClassUtils::isTypeAssociativeContainer(const Reflex::Type& typ){
00212 Reflex::TypeTemplate tt = typ.TemplateFamily();
00213 if (! tt) {
00214 return false;
00215 } else {
00216 std::string contName = tt.Name(Reflex::SCOPED|Reflex::FINAL);
00217 if( contName == "std::map" ||
00218 contName == "std::multimap" ||
00219 contName == "__gnu_cxx::hash_map" ||
00220 contName == "__gnu_cxx::hash_multimap" ){
00221 return true;
00222 }
00223 }
00224 return false;
00225 }
00226
00227 bool ora::ClassUtils::isTypeNonAssociativeContainer(const Reflex::Type& typ){
00228 Reflex::TypeTemplate tt = typ.TemplateFamily();
00229 if (! tt) {
00230 return false;
00231 } else {
00232 std::string contName = tt.Name(Reflex::SCOPED|Reflex::FINAL);
00233 if( contName == "std::vector" ||
00234 contName == "std::list" ||
00235 contName == "std::deque" ||
00236 contName == "std::stack" ||
00237 contName == "std::set" ||
00238 contName == "std::multiset" ||
00239 contName == "__gnu_cxx::hash_set" ||
00240 contName == "__gnu_cxx::hash_multiset" ||
00241 contName == "ora::PVector" ||
00242 contName == "ora::QueryableVector"){
00243 return true;
00244 }
00245 }
00246 return false;
00247 }
00248
00249
00250 bool ora::ClassUtils::isTypeOraPointer( const Reflex::Type& typ){
00251 Reflex::TypeTemplate templ = typ.TemplateFamily();
00252 if (! templ) {
00253 return false;
00254 } else {
00255 std::string contName = templ.Name(Reflex::SCOPED|Reflex::FINAL);
00256 if( contName == "ora::Ptr" ){
00257 return true;
00258 }
00259 }
00260 return false;
00261 }
00262
00263 bool ora::ClassUtils::isTypeOraReference( const Reflex::Type& typ){
00264 return typ.HasBase(Reflex::Type::ByTypeInfo(typeid(ora::Reference)));
00265 }
00266
00267 bool ora::ClassUtils::isTypeNamedReference( const Reflex::Type& typ){
00268 return typ.HasBase(Reflex::Type::ByTypeInfo(typeid(ora::NamedReference)));
00269 }
00270
00271 bool ora::ClassUtils::isTypeUniqueReference( const Reflex::Type& typ){
00272 Reflex::TypeTemplate templ = typ.TemplateFamily();
00273 if (! templ) {
00274 return false;
00275 } else {
00276 std::string contName = templ.Name(Reflex::SCOPED|Reflex::FINAL);
00277 if( contName == "ora::UniqueRef" ){
00278 return true;
00279 }
00280 }
00281 return false;
00282 }
00283
00284 bool ora::ClassUtils::isTypePVector( const Reflex::Type& typ){
00285 Reflex::TypeTemplate templ = typ.TemplateFamily();
00286 if (! templ) {
00287 return false;
00288 } else {
00289 std::string contName = templ.Name(Reflex::SCOPED|Reflex::FINAL);
00290 if( contName == "ora::PVector" ){
00291 return true;
00292 }
00293 }
00294 return false;
00295 }
00296
00297 bool ora::ClassUtils::isTypeQueryableVector( const Reflex::Type& typ){
00298 Reflex::TypeTemplate templ = typ.TemplateFamily();
00299 if (! templ) {
00300 return false;
00301 } else {
00302 std::string contName = templ.Name(Reflex::SCOPED|Reflex::FINAL);
00303 if( contName == "ora::QueryableVector" ){
00304 return true;
00305 }
00306 }
00307 return false;
00308 }
00309
00310 bool ora::ClassUtils::isTypeOraVector( const Reflex::Type& typ){
00311 if( isTypePVector( typ ) || isTypeQueryableVector( typ ) ){
00312 return true;
00313 }
00314 return false;
00315 }
00316
00317 bool ora::ClassUtils::isTypeNameOraVector( const std::string& typeName ){
00318 size_t idx = typeName.find('<');
00319 if( idx != std::string::npos ){
00320 std::string tname = typeName.substr( 0, idx );
00321 return (tname == "ora::PVector" || tname == "ora::QueryableVector" || tname == "pool::PVector" );
00322 }
00323 return false;
00324 }
00325
00326 bool ora::ClassUtils::isTypeObject( const Reflex::Type& typ){
00327 Reflex::Type resType = ClassUtils::resolvedType( typ );
00328 if( isTypePrimitive( resType ) ) {
00329
00330 return false;
00331 } else {
00332 if( resType.IsArray() ) return false;
00333 if( isTypeContainer( resType ) ) return false;
00334 if( isTypeOraPointer( resType ) ) return false;
00335 if( isTypeUniqueReference( resType ) ) return false;
00336 if( isTypeOraVector( resType ) ) return false;
00337 }
00338 return true;
00339 }
00340
00341 Reflex::Type ora::ClassUtils::containerValueType(const Reflex::Type& typ){
00342 Reflex::Type valueType;
00343
00344 size_t subTypeSize = typ.SubTypeSize();
00345 size_t i=0;
00346 while(i<subTypeSize){
00347 Reflex::Type sti = typ.SubTypeAt(i);
00348 if(sti.Name()=="value_type") {
00349 valueType = sti;
00350 break;
00351 }
00352 i++;
00353 }
00354 return valueType;
00355 }
00356
00357 Reflex::Type ora::ClassUtils::containerKeyType(const Reflex::Type& typ){
00358 Reflex::Type keyType;
00359
00360 size_t subTypeSize = typ.SubTypeSize();
00361 size_t i=0;
00362 while(i<subTypeSize){
00363 Reflex::Type sti = typ.SubTypeAt(i);
00364 if(sti.Name()=="key_type") {
00365 keyType = sti;
00366 break;
00367 }
00368 i++;
00369 }
00370 return keyType;
00371 }
00372
00373 Reflex::Type ora::ClassUtils::containerDataType(const Reflex::Type& typ){
00374 Reflex::Type dataType;
00375
00376 size_t subTypeSize = typ.SubTypeSize();
00377 size_t i=0;
00378 while(i<subTypeSize){
00379 Reflex::Type sti = typ.SubTypeAt(i);
00380 if(sti.Name()=="mapped_type") {
00381 dataType = sti;
00382 break;
00383 }
00384 i++;
00385 }
00386 return dataType;
00387 }
00388
00389 Reflex::Type ora::ClassUtils::containerSubType(const Reflex::Type& typ, const std::string& subTypeName){
00390 Reflex::Type subType;
00391 size_t subTypeSize = typ.SubTypeSize();
00392 size_t i=0;
00393 while(i<subTypeSize){
00394 Reflex::Type sti = typ.SubTypeAt(i);
00395 if(sti.Name()==subTypeName) {
00396 subType = sti;
00397 break;
00398 }
00399 i++;
00400 }
00401 return resolvedType(subType);
00402 }
00403
00404 Reflex::Type ora::ClassUtils::resolvedType(const Reflex::Type& typ){
00405 Reflex::Type resolvedType = typ;
00406 while(resolvedType.IsTypedef()){
00407 resolvedType = resolvedType.ToType();
00408 }
00409 return resolvedType;
00410 }