00001 #ifndef DDD_DDOBJECT_H
00002 #define DDD_DDOBJECT_H
00003
00004 #include <string>
00005 #include <map>
00006 #include "Utilities/Loki/interface/TypeManip.h"
00007 #include "DetectorDescription/Core/interface/DDName.h"
00008 #include "DetectorDescription/Base/interface/Singleton.h"
00009 #include "DetectorDescription/Base/interface/Ptr.h"
00010 #include "DetectorDescription/Base/interface/DDException.h"
00011 #include "DetectorDescription/Core/interface/DDRegistry.h"
00012
00013
00014 template<class T>
00015 class DDObject
00016 {
00017 public:
00018 typedef Ptr<T> pointer;
00020 typedef DDRegistry<pointer> RegistryType;
00022 typedef typename RegistryType::iterator iterator;
00023
00024 typedef typename RegistryType::const_iterator const_iterator;
00025
00026 public:
00028 DDObject();
00029
00031 explicit DDObject(const DDName & name);
00032
00034 DDObject(const DDName &, T*);
00035
00037 explicit DDObject(DDName*);
00038
00040
00041
00043 const DDName & name() const;
00044
00045 const T* operator->() const;
00046
00047 T* operator->();
00048
00049 const T& operator*() const;
00050
00051 T& operator*();
00052
00053 operator bool() const
00054 {
00055 if (rep_ != registry().end()) {
00056 return bool(rep_->second);
00057 }
00058 throw DDException("unbound DDObject, typeid.name="+std::string(typeid(*rep_->second).name()));
00059 };
00060
00061 static iterator begin() { return registry().begin(); }
00062
00063 static iterator end() { return registry().end();}
00064
00065
00066 private:
00067
00068 void init();
00069
00070 void registerObject(const DDName & name, T* object);
00071 void registerAnoObject(const DDName & name, T* object);
00072
00074 static RegistryType & registry()
00075 {
00076 static RegistryType reg_;
00077 return reg_;
00078 };
00079
00081 static RegistryType & anoRegistry()
00082 {
00083 static RegistryType reg_;
00084 return reg_;
00085 }
00086
00088 typename RegistryType::iterator rep_;
00089
00090 };
00091
00092
00093 template<class T>
00094 DDObject<T>::DDObject()
00095 : rep_(registry().end())
00096 { }
00097
00098
00099 template<class T>
00100 DDObject<T>::DDObject(const DDName & name)
00101 {
00102 registerObject(name,(T*)0);
00103 }
00104
00105
00106 template<class T>
00107 DDObject<T>::DDObject(const DDName & name, T* object)
00108 {
00109 registerObject(name,object);
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 template<class T>
00124 DDObject<T>::DDObject(DDName* object)
00125 {
00126
00127
00128 registerObject(*object,static_cast<T*>(object));
00129 }
00130
00131
00132 template<class T>
00133 void DDObject<T>::registerObject(const DDName & name, T* object)
00134 {
00135 std::pair<typename RegistryType::iterator,bool> result
00136 = registry().insert(typename RegistryType::value_type(name,pointer(object)));
00137 if (!result.second) {
00138 result.first->second = pointer(object);
00139 }
00140 rep_ = result.first;
00141 }
00142
00143
00144 template<class T>
00145 void DDObject<T>::registerAnoObject(const DDName & name, T* object)
00146 {
00147 std::pair<typename RegistryType::iterator,bool> result
00148 = anoRegistry().insert(typename RegistryType::value_type(name,pointer(object)));
00149 if (!result.second) {
00150 result.first->second = pointer(object);
00151 }
00152 rep_ = result.first;
00153 }
00154
00155 template<class T>
00156 const DDName & DDObject<T>::name() const
00157 {
00158
00159 return rep_->first;
00160 }
00161
00162
00163 template<class T>
00164 const T& DDObject<T>::operator*() const
00165 {
00166 return *(rep_->second);
00167 }
00168
00169
00170 template<class T>
00171 T& DDObject<T>::operator*()
00172 {
00173 return *(rep_->second);
00174 }
00175
00176
00177 template<class T>
00178 const T* DDObject<T>::operator->() const
00179 {
00180 return &(*rep_->second);
00181 }
00182
00183
00184 template<class T>
00185 T* DDObject<T>::operator->()
00186 {
00187 return &(*rep_->second);
00188 }
00189
00190
00191 #endif // DDD_DDOBJECT_H