Go to the documentation of this file.00001 #ifndef CondCore_ORA_RecordDetails_H
00002 #define CondCore_ORA_RecordDetails_H
00003 #include"AnyData.h"
00004
00005 #include <typeinfo>
00006 #include <vector>
00007 #include <algorithm>
00008 #include <boost/type_traits/is_pointer.hpp>
00009
00010 #include "CoralBase/Blob.h"
00011
00012 namespace ora {
00013
00014 struct TypeHandler {
00015 std::type_info const * type;
00016 virtual bool isPointer() const=0;
00017 virtual ~TypeHandler(){}
00018 virtual void const * address(const AnyData & ad) const=0;
00019
00020 virtual void set(AnyData & ad, void * p) const=0;
00021 virtual void const * get(const AnyData & ad) const=0;
00022 virtual void create(AnyData & ad) const=0;
00023 virtual void destroy(AnyData & ad) const=0;
00024
00025 };
00026
00027 struct NullTypeHandler : public TypeHandler{
00028 NullTypeHandler(std::type_info const& t) { type=&t;}
00029 virtual bool isPointer() const { return false;}
00030 virtual void const * address(const AnyData &) const{return 0;}
00031 virtual void set(AnyData &, void*) const{};
00032 virtual void const * get(const AnyData &) const{return 0;};
00033 virtual void create(AnyData &) const{};
00034 virtual void destroy(AnyData &) const{};
00035
00036 };
00037
00038 struct VoidStarHandler : public TypeHandler{
00039 VoidStarHandler() { type= &typeid(void*);}
00040 virtual bool isPointer() const { return true;}
00041 virtual void const * address(const AnyData & ad) const{return ad.p;}
00042 virtual void set(AnyData &ad, void*p) const{ad.p = p;};
00043 virtual void const * get(const AnyData &ad) const{return ad.p;};
00044 virtual void create(AnyData &) const{};
00045 virtual void destroy(AnyData &) const{};
00046
00047 };
00048
00049 template<typename T> struct SimpleTypeHandler : public TypeHandler {
00050 SimpleTypeHandler() { type = &typeid(T);}
00051 virtual bool isPointer() const { return false;}
00052 virtual void const * address(const AnyData & ad) const { return get(ad);}
00053
00054 virtual void set(AnyData & ad, void * p) const { ad.data<T>() = *reinterpret_cast<T*>(p);}
00055 virtual void const * get(const AnyData & ad) const { return &ad.data<T>();}
00056 virtual void create(AnyData & ad) const{}
00057 virtual void destroy(AnyData & ad) const{}
00058
00059 };
00060
00061 template<typename T> struct AnyTypeHandler : public TypeHandler {
00062 AnyTypeHandler() { type = &typeid(T);}
00063 inline static bool inplace() { return sizeof(T) < 9;}
00064 virtual bool isPointer() const { return boost::is_pointer<T>::value;}
00065
00066
00067 virtual void const * address(const AnyData & ad) const {
00068 if (isPointer())
00069 return ad.p;
00070 else
00071 return get(ad);
00072 }
00073
00074
00075 virtual void set(AnyData & ad, void * p) const {
00076 if (inplace())
00077 *reinterpret_cast<T*>(ad.address()) = *reinterpret_cast<T*>(p);
00078 else
00079 *reinterpret_cast<T*>(ad.p) = *reinterpret_cast<T*>(p);
00080 }
00081
00082 virtual void const * get(const AnyData & ad) const {
00083 if (inplace())
00084 return ad.address();
00085 else
00086 return ad.p;
00087 }
00088 virtual void create(AnyData & ad) const{
00089 if (inplace())
00090 new(ad.address()) T();
00091 else
00092 ad.p = new T();
00093 }
00094 virtual void destroy(AnyData & ad) const{
00095 if (inplace())
00096 reinterpret_cast<T*>(ad.address())->~T();
00097 else
00098 delete reinterpret_cast<T*>(ad.p);
00099 }
00100 };
00101
00102 struct AllKnowTypeHandlers {
00103 AllKnowTypeHandlers();
00104
00105 VoidStarHandler vs;
00106
00107 AnyTypeHandler<bool> b;
00108 AnyTypeHandler<char> c;
00109 AnyTypeHandler<unsigned char> uc;
00110 AnyTypeHandler<short> s;
00111 AnyTypeHandler<unsigned short> us;
00112 AnyTypeHandler<int> i;
00113 AnyTypeHandler<unsigned int> ui;
00114 AnyTypeHandler<long> l;
00115 AnyTypeHandler<long long> ll;
00116 AnyTypeHandler<unsigned long long> ul;
00117 AnyTypeHandler<float> f;
00118 AnyTypeHandler<double> d;
00119
00120 AnyTypeHandler<long double> ld;
00121 AnyTypeHandler<std::string> ss;
00122
00123 AnyTypeHandler<bool*> bp;
00124 AnyTypeHandler<char*> cp;
00125 AnyTypeHandler<unsigned char*> ucp;
00126 AnyTypeHandler<short*> sp;
00127 AnyTypeHandler<unsigned short*> usp;
00128 AnyTypeHandler<int*> ip;
00129 AnyTypeHandler<unsigned int*> uip;
00130 AnyTypeHandler<long long*> lp;
00131 AnyTypeHandler<unsigned long long*> ulp;
00132 AnyTypeHandler<float*> fp;
00133 AnyTypeHandler<double*> dp;
00134
00135 AnyTypeHandler<long double*> ldp;
00136 AnyTypeHandler<std::string*> ssp;
00137
00138 AnyTypeHandler<coral::Blob> cb;
00139
00140 std::vector<TypeHandler const *> all;
00141 typedef std::vector<TypeHandler const *>::const_iterator CI;
00142 TypeHandler const * operator()(std::type_info const & type) const;
00143 };
00144
00145 struct CompareTypeHandler {
00146 bool operator()(TypeHandler const * rh, TypeHandler const * lh) {
00147 return rh->type < lh->type;
00148 }
00149 };
00150
00151 AllKnowTypeHandlers::AllKnowTypeHandlers() {
00152 all.push_back(&vs);
00153
00154 all.push_back(&b);
00155 all.push_back(&c);
00156 all.push_back(&uc);
00157 all.push_back(&s);
00158 all.push_back(&us);
00159 all.push_back(&i);
00160 all.push_back(&ui);
00161 all.push_back(&l);
00162 all.push_back(&ll);
00163 all.push_back(&ul);
00164 all.push_back(&f);
00165 all.push_back(&d);
00166 all.push_back(&ld);
00167 all.push_back(&ss);
00168
00169 all.push_back(&bp);
00170 all.push_back(&cp);
00171 all.push_back(&ucp);
00172 all.push_back(&sp);
00173 all.push_back(&usp);
00174 all.push_back(&ip);
00175 all.push_back(&uip);
00176 all.push_back(&lp);
00177 all.push_back(&ulp);
00178 all.push_back(&fp);
00179 all.push_back(&dp);
00180 all.push_back(&ldp);
00181 all.push_back(&ssp);
00182
00183 all.push_back(&cb);
00184 std::sort(all.begin(),all.end(),CompareTypeHandler());
00185 }
00186
00187 TypeHandler const * AllKnowTypeHandlers::operator()(std::type_info const & type) const {
00188 NullTypeHandler h(type);
00189 std::pair<CI,CI> range = std::equal_range(all.begin(),all.end(),&h,CompareTypeHandler());
00190 return (range.first==range.second) ? (TypeHandler const *)(0) : *range.first;
00191 }
00192
00193
00194 }
00195 #endif // CondCore_ORA_RecordDEtails_H