Warning, /include/DD4hep/detail/Handle.inl is written in an unsupported language. File is not indexed.
0001 //==========================================================================
0002 // AIDA Detector description implementation
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author : M.Frank
0011 //
0012 //==========================================================================
0013
0014 // Framework include files
0015 #include <DD4hep/Handle.h>
0016
0017 /// Namespace for the AIDA detector description toolkit
0018 namespace dd4hep {
0019
0020 /// Helper routine called when unrelated types are assigned.
0021 template <typename T> void Handle<T>::bad_assignment(const std::type_info& from, const std::type_info& to)
0022 {
0023 invalidHandleAssignmentError(from,to);
0024 }
0025
0026 /// Assign a new named object. Note: object references must be managed by the user
0027 template <typename T> void Handle<T>::assign(T* n, const std::string& nam, const std::string& tit) {
0028 this->m_element = n;
0029 if (!nam.empty())
0030 n->SetName(nam.c_str());
0031 if (!tit.empty())
0032 n->SetTitle(tit.c_str());
0033 }
0034
0035 /// Access the object name (or "" if not supported by the object)
0036 template <typename T> const char* Handle<T>::name() const {
0037 return this->m_element ? this->m_element->GetName() : "";
0038 }
0039
0040 /// Checked object access. Throws invalid handle runtime exception
0041 /** Very compact way to check the validity of a handle with exception thrown.
0042 */
0043 template <typename T> T* Handle<T>::access() const {
0044 if ( this->m_element ) return this->m_element;
0045 invalidHandleError(typeid(T));
0046 return 0; // We have thrown an exception before - does not harm!
0047 }
0048 /// Destroy the underlying object (be careful here: things are not reference counted)!
0049 template <typename T> void Handle<T>::destroy() {
0050 if ( this->m_element ) {
0051 delete this->m_element;
0052 this->m_element = 0;
0053 }
0054 }
0055 } /* End namespace dd4hep */
0056
0057
0058 #ifdef DD4HEP_USE_SAFE_CAST
0059
0060 #define DD4HEP_SAFE_CAST_IMPLEMENTATION(FROM, TO) \
0061 namespace dd4hep { namespace detail { \
0062 template <> template <> TO* safe_cast<TO>::cast<FROM>(FROM* p) \
0063 { return dynamic_cast<TO*>(p); } \
0064 template <> template <> TO* safe_cast<TO>::cast<FROM>(const FROM* p) \
0065 { return const_cast<TO*>(dynamic_cast<const TO*>(p)); } \
0066 template <> template <> TO* safe_cast<TO>::cast_non_null<FROM>(FROM* p) { \
0067 TO* ptr = dynamic_cast<TO*>(p); \
0068 if ( ptr ) return ptr; \
0069 invalidHandleAssignmentError(typeid(FROM),typeid(TO)); \
0070 return ptr; \
0071 } \
0072 template <> template <> TO* safe_cast<TO>::cast_non_null<FROM>(const FROM* p) { \
0073 return safe_cast<TO>::cast_non_null<FROM>(const_cast<FROM*>(p)); \
0074 } \
0075 }}
0076
0077 // Predefined simple cast map
0078 #define DD4HEP_IMPLEMENT_SAFE_CAST(FROM,TO) \
0079 DD4HEP_SAFE_CAST_IMPLEMENTATION(FROM,TO) \
0080 DD4HEP_SAFE_CAST_IMPLEMENTATION(TO,FROM)
0081
0082 // Predefined cast map including standard object types
0083 #define DD4HEP_IMPLEMENT_SAFE_NAMED_CAST(FROM) \
0084 DD4HEP_IMPLEMENT_SAFE_CAST(FROM,TObject) \
0085 DD4HEP_IMPLEMENT_SAFE_CAST(FROM,NamedObject) \
0086 DD4HEP_IMPLEMENT_SAFE_CAST(FROM,TNamed) \
0087 DD4HEP_SAFE_CAST_IMPLEMENTATION(FROM,FROM)
0088
0089 #else
0090
0091 #define DD4HEP_SAFE_CAST_IMPLEMENTATION(FROM, TO) \
0092 namespace dd4hep { namespace detail { \
0093 template <> template <> FROM* safe_cast<FROM>::cast(FROM* p) \
0094 { return dynamic_cast<FROM*>(p); } \
0095 template <> template <> FROM* safe_cast<FROM>::cast_non_null(FROM* p) { \
0096 FROM* ptr = const_cast<FROM*>(dynamic_cast<const FROM*>(p)); \
0097 if ( !ptr ) invalidHandleError(typeid(FROM)); \
0098 return ptr; \
0099 } \
0100 }}
0101 // Predefined simple cast map
0102 #define DD4HEP_IMPLEMENT_SAFE_CAST(FROM,TO) DD4HEP_SAFE_CAST_IMPLEMENTATION(FROM,FROM)
0103
0104 // Predefined cast map including standard object types
0105 #define DD4HEP_IMPLEMENT_SAFE_NAMED_CAST(FROM) DD4HEP_SAFE_CAST_IMPLEMENTATION(FROM,FROM)
0106
0107 #endif
0108
0109 // Utility for counting the number of args in the __VA_ARGS__ pack:
0110 #define DD4HEP_HANDLE_PP_NARGS(...) DD4HEP_HANDLE_PP_NARGS2(__VA_ARGS__, DD4HEP_HANDLE_PP_NARGS_COUNT())
0111 #define DD4HEP_HANDLE_PP_NARGS2(...) DD4HEP_HANDLE_PP_NARGS_IMPL(__VA_ARGS__)
0112 #define DD4HEP_HANDLE_PP_NARGS_IMPL(x1, x2, x3, x4, x5, x6, x7, x8, x9, N, ...) N
0113 #define DD4HEP_HANDLE_PP_NARGS_COUNT() 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ERROR
0114
0115 // Macros to delegate to concrete, defined-arity implementations:
0116 #define DD4HEP_HANDLE_VAR_ARG(count, ...) DD4HEP_HANDLE_VAR_ARG_IMPL (count, __VA_ARGS__)
0117 #define DD4HEP_HANDLE_VAR_ARG_IMPL(count, ...) DD4HEP_HANDLE_VAR_ARG_ ## count (__VA_ARGS__)
0118
0119 #define DD4HEP_HANDLE_VAR_ARG_1(CODE,x1) DD4HEP_TEMPLATE_HANDLE(CODE,x1)
0120 #define DD4HEP_HANDLE_VAR_ARG_2(CODE,x1,x2) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x2) DD4HEP_HANDLE_VAR_ARG_1(CODE,x1)
0121 #define DD4HEP_HANDLE_VAR_ARG_3(CODE,x1,x2,x3) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x3) DD4HEP_HANDLE_VAR_ARG_2(CODE,x1,x2)
0122 #define DD4HEP_HANDLE_VAR_ARG_4(CODE,x1,x2,x3,x4) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x4) DD4HEP_HANDLE_VAR_ARG_3(CODE,x1,x2,x3)
0123 #define DD4HEP_HANDLE_VAR_ARG_5(CODE,x1,x2,x3,x4,x5) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x5) DD4HEP_HANDLE_VAR_ARG_4(CODE,x1,x2,x3,x4)
0124 #define DD4HEP_HANDLE_VAR_ARG_6(CODE,x1,x2,x3,x4,x5,x6) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x6) DD4HEP_HANDLE_VAR_ARG_5(CODE,x1,x2,x3,x4,x5)
0125 #define DD4HEP_HANDLE_VAR_ARG_7(CODE,x1,x2,x3,x4,x5,x6,x7) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x7) DD4HEP_HANDLE_VAR_ARG_6(CODE,x1,x2,x3,x4,x5,x6)
0126 #define DD4HEP_HANDLE_VAR_ARG_8(CODE,x1,x2,x3,x4,x5,x6,x7,x8) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x8) DD4HEP_HANDLE_VAR_ARG_7(CODE,x1,x2,x3,x4,x5,x6,x7)
0127 #define DD4HEP_HANDLE_VAR_ARG_9(CODE,x1,x2,x3,x4,x5,x6,x7,x8,x9) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x9) DD4HEP_HANDLE_VAR_ARG_8(CODE,x1,x2,x3,x4,x5,x6,x7,x8)
0128 #define DD4HEP_HANDLE_VAR_ARG_10(CODE,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) DD4HEP_IMPLEMENT_SAFE_CAST(x1,x10) DD4HEP_HANDLE_VAR_ARG_9(CODE,x1,x2,x3,x4,x5,x6,x7,x8,x9)
0129
0130
0131 #define DD4HEP_TEMPLATE_HANDLE(CODE,X) DD4HEP_TEMPLATE_HANDLE_CODE_##CODE(X) template class dd4hep::Handle<X>
0132 #define DD4HEP_TEMPLATE_HANDLE_CODE_NONE(X)
0133 #define DD4HEP_TEMPLATE_HANDLE_CODE_CAST_ONLY(X) DD4HEP_IMPLEMENT_SAFE_NAMED_CAST(X)
0134 #define DD4HEP_TEMPLATE_HANDLE_CODE_NAMED(X) \
0135 namespace dd4hep { \
0136 template <> const char* Handle<X>::name() const \
0137 { return this->m_element ? this->m_element->name.c_str() : ""; } \
0138 template <> void \
0139 Handle<X>::assign(X* p, const std::string& n, const std::string& t){\
0140 this->m_element = p; \
0141 p->name = n; \
0142 p->type = t; \
0143 }} \
0144 DD4HEP_IMPLEMENT_SAFE_NAMED_CAST(X)
0145
0146 #define DD4HEP_TEMPLATE_HANDLE_CODE_UNNAMED(X) \
0147 namespace dd4hep { \
0148 template <> void \
0149 Handle<X>::assign(X* n, const std::string&, const std::string&) \
0150 { this->m_element = n;} \
0151 template <> const char* Handle<X>::name() const { return ""; } \
0152 } \
0153 DD4HEP_IMPLEMENT_SAFE_NAMED_CAST(X)
0154
0155 #define DD4HEP_TEMPLATE_HANDLE_CODE_RAW(X) \
0156 namespace dd4hep { \
0157 template <> void \
0158 Handle<X>::assign(X* n, const std::string&, const std::string&) \
0159 { this->m_element = n;} \
0160 template <> const char* Handle<X>::name() const { return ""; } \
0161 } \
0162 DD4HEP_SAFE_CAST_IMPLEMENTATION(X,X)
0163
0164 // Delegation macro; this is the only macro you need to call from elsewhere:
0165 #define DD4HEP_INSTANTIATE_HANDLE_CODE(CODE,...) DD4HEP_HANDLE_VAR_ARG(DD4HEP_HANDLE_PP_NARGS(__VA_ARGS__),CODE,__VA_ARGS__)
0166 #define DD4HEP_INSTANTIATE_HANDLE(...) DD4HEP_INSTANTIATE_HANDLE_CODE(CAST_ONLY,__VA_ARGS__)
0167 #define DD4HEP_INSTANTIATE_SHAPE_HANDLE(...) DD4HEP_INSTANTIATE_HANDLE_CODE(CAST_ONLY,__VA_ARGS__,TGeoShape,TGeoBBox)
0168 #define DD4HEP_INSTANTIATE_HANDLE_RAW(...) DD4HEP_INSTANTIATE_HANDLE_CODE(RAW,__VA_ARGS__)
0169 #define DD4HEP_INSTANTIATE_HANDLE_NAMED(...) DD4HEP_INSTANTIATE_HANDLE_CODE(NAMED,__VA_ARGS__)
0170 #define DD4HEP_INSTANTIATE_HANDLE_UNNAMED(...) DD4HEP_INSTANTIATE_HANDLE_CODE(UNNAMED,__VA_ARGS__)
0171
0172 #define DD4HEP_CONCAT_MACROS(name, serial) name##_##serial
0173 #define DD4HEP_SEGMENTATION_HANDLE_IMPLEMENTATION(serial,name,...) \
0174 namespace { \
0175 typedef dd4hep::SegmentationWrapper<name> DD4HEP_CONCAT_MACROS(Wrapper,serial); } \
0176 DD4HEP_INSTANTIATE_HANDLE_CODE(UNNAMED,DD4HEP_CONCAT_MACROS(Wrapper,serial),__VA_ARGS__)
0177
0178 #define DD4HEP_INSTANTIATE_SEGMENTATION_HANDLE(...) \
0179 DD4HEP_SEGMENTATION_HANDLE_IMPLEMENTATION(__LINE__,__VA_ARGS__,dd4hep::SegmentationObject)