Go to the documentation of this file.00001 #include "FWCore/Utilities/interface/ReflexTools.h"
00002 #include "FWCore/Utilities/interface/Algorithms.h"
00003
00004 #include "Api.h"
00005 #include "Reflex/Base.h"
00006 #include "Reflex/Member.h"
00007 #include "Reflex/TypeTemplate.h"
00008
00009 #include "boost/algorithm/string.hpp"
00010 #include "boost/thread/tss.hpp"
00011
00012 #include <algorithm>
00013 #include <sstream>
00014
00015 using Reflex::Base;
00016 using Reflex::FINAL;
00017 using Reflex::Member;
00018 using Reflex::Object;
00019 using Reflex::SCOPED;
00020 using Reflex::Type;
00021 using Reflex::TypeTemplate;
00022 using Reflex::Type_Iterator;
00023
00024 namespace edm {
00025
00026 Type get_final_type(Type t) {
00027 while(t.IsTypedef()) t = t.ToType();
00028 return t;
00029 }
00030
00031 bool
00032 find_nested_type_named(std::string const& nested_type,
00033 Type const& type_to_search,
00034 Type& found_type) {
00035
00036 for(Type_Iterator
00037 i = type_to_search.SubType_Begin(),
00038 e = type_to_search.SubType_End();
00039 i != e;
00040 ++i) {
00041 if(i->Name() == nested_type) {
00042 found_type = get_final_type(*i);
00043 return true;
00044 }
00045 }
00046 return false;
00047 }
00048
00049 bool
00050 is_RefVector(Reflex::Type const& possible_ref_vector,
00051 Reflex::Type& value_type) {
00052
00053 static TypeTemplate ref_vector_template_id(TypeTemplate::ByName("edm::RefVector", 3));
00054 static std::string member_type("member_type");
00055 TypeTemplate primary_template_id(possible_ref_vector.TemplateFamily());
00056 if(primary_template_id == ref_vector_template_id) {
00057 return find_nested_type_named(member_type, possible_ref_vector, value_type);
00058 }
00059 return false;
00060 }
00061
00062 bool
00063 is_PtrVector(Reflex::Type const& possible_ref_vector,
00064 Reflex::Type& value_type) {
00065
00066 static TypeTemplate ref_vector_template_id(TypeTemplate::ByName("edm::PtrVector", 1));
00067 static std::string member_type("member_type");
00068 static std::string val_type("value_type");
00069 TypeTemplate primary_template_id(possible_ref_vector.TemplateFamily());
00070 if(primary_template_id == ref_vector_template_id) {
00071 Reflex::Type ptrType;
00072 if(find_nested_type_named(val_type, possible_ref_vector, ptrType)) {
00073 return find_nested_type_named(val_type, ptrType, value_type);
00074 }
00075 }
00076 return false;
00077 }
00078
00079 bool
00080 is_RefToBaseVector(Reflex::Type const& possible_ref_vector,
00081 Reflex::Type& value_type) {
00082
00083 static TypeTemplate ref_vector_template_id(TypeTemplate::ByName("edm::RefToBaseVector", 1));
00084 static std::string member_type("member_type");
00085 TypeTemplate primary_template_id(possible_ref_vector.TemplateFamily());
00086 if(primary_template_id == ref_vector_template_id) {
00087 return find_nested_type_named(member_type, possible_ref_vector, value_type);
00088 }
00089 return false;
00090 }
00091
00092 namespace {
00093
00094 int const oneParamArraySize = 6;
00095 std::string const oneParam[oneParamArraySize] = {
00096 "vector",
00097 "basic_string",
00098 "set",
00099 "list",
00100 "deque",
00101 "multiset"
00102 };
00103 int const twoParamArraySize = 3;
00104 std::string const twoParam[twoParamArraySize] = {
00105 "map",
00106 "pair",
00107 "multimap"
00108 };
00109
00110
00111 bool
00112 hasCintDictionary(std::string const& name) {
00113 std::auto_ptr<G__ClassInfo> ci(new G__ClassInfo(name.c_str()));
00114 return(ci.get() && ci->IsLoaded());
00115 }
00116
00117
00118
00119
00120 void
00121 checkType(Type t, bool noComponents = false) {
00122
00123
00124
00125 static boost::thread_specific_ptr<StringSet> found_types;
00126 if(0 == found_types.get()) {
00127 found_types.reset(new StringSet);
00128 }
00129
00130
00131
00132
00133
00134 Type null;
00135 for(Type x = t.ToType(); x != null && x != t; t = x, x = t.ToType()) {}
00136
00137 std::string name = t.Name(SCOPED);
00138 boost::trim(name);
00139
00140 if(found_types->end() != found_types->find(name) || missingTypes().end() != missingTypes().find(name)) {
00141
00142 return;
00143 }
00144
00145 if(name.empty() || t.IsFundamental() || t.IsEnum()) {
00146 found_types->insert(name);
00147 return;
00148 }
00149
00150 if(!bool(t)) {
00151 if(hasCintDictionary(name)) {
00152 found_types->insert(name);
00153 } else {
00154 missingTypes().insert(name);
00155 }
00156 return;
00157 }
00158
00159 found_types->insert(name);
00160 if(noComponents) return;
00161
00162 if(name.find("std::") == 0) {
00163 if(t.IsTemplateInstance()) {
00164 std::string::size_type n = name.find('<');
00165 int cnt = 0;
00166 if(std::find(oneParam, oneParam + oneParamArraySize, name.substr(5, n - 5)) != oneParam + oneParamArraySize) {
00167 cnt = 1;
00168 } else if(std::find(twoParam, twoParam + twoParamArraySize, name.substr(5, n - 5)) != twoParam + twoParamArraySize) {
00169 cnt = 2;
00170 }
00171 for(int i = 0; i < cnt; ++i) {
00172 checkType(t.TemplateArgumentAt(i));
00173 }
00174 }
00175 } else {
00176 int mcnt = t.DataMemberSize();
00177 for(int i = 0; i < mcnt; ++i) {
00178 Member m = t.DataMemberAt(i);
00179 if(m.IsTransient() || m.IsStatic()) continue;
00180 checkType(m.TypeOf());
00181 }
00182 int cnt = t.BaseSize();
00183 for(int i = 0; i < cnt; ++i) {
00184 checkType(t.BaseAt(i).ToType());
00185 }
00186 }
00187 }
00188 }
00189
00190 StringSet& missingTypes() {
00191 static boost::thread_specific_ptr<StringSet> missingTypes_;
00192 if(0 == missingTypes_.get()) {
00193 missingTypes_.reset(new StringSet);
00194 }
00195 return *missingTypes_.get();
00196 }
00197
00198 void checkDictionaries(std::string const& name, bool noComponents) {
00199 Type null;
00200 Type t = Type::ByName(name);
00201 if(t == null) {
00202 missingTypes().insert(name);
00203 return;
00204 }
00205 checkType(Type::ByName(name), noComponents);
00206 }
00207
00208 void public_base_classes(Type const& type,
00209 std::vector<Type>& baseTypes) {
00210
00211 if(type.IsClass() || type.IsStruct()) {
00212
00213 int nBase = type.BaseSize();
00214 for(int i = 0; i < nBase; ++i) {
00215
00216 Base base = type.BaseAt(i);
00217 if(base.IsPublic()) {
00218
00219 Type baseType = type.BaseAt(i).ToType();
00220 if(bool(baseType)) {
00221
00222 while(baseType.IsTypedef() == true) {
00223 baseType = baseType.ToType();
00224 }
00225
00226
00227
00228 if(!search_all(baseTypes, baseType)) {
00229
00230 baseTypes.push_back(baseType);
00231 public_base_classes(baseType, baseTypes);
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 }
00254 }
00255 }
00256 }
00257 }
00258
00259 void const*
00260 reflex_pointer_adjust(void* raw,
00261 Type const& dynamicType,
00262 std::type_info const& toType) {
00263 Object obj(dynamicType, raw);
00264 return obj.CastObject(Type::ByTypeInfo(toType)).Address();
00265 }
00266 }