DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ObjectExtensions.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation for LCD
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
16 #include "DD4hep/InstanceCount.h"
17 #include "DD4hep/Primitives.h"
18 
19 // C/C++ include files
20 #include <stdexcept>
21 
22 using namespace DD4hep;
23 
24 namespace {
25  static int s_extensionID = 0;
26  ObjectExtensions::ExtensionMap* extensionContainer(const std::type_info& typ) {
27  static std::map<const std::type_info*, ObjectExtensions::ExtensionMap> s_map;
28  return &s_map[&typ];
29  }
30 }
31 
33 ObjectExtensions::ObjectExtensions(const std::type_info& parent_type) {
34  extensionMap = extensionContainer(parent_type);
36 }
37 
40  clear();
42 }
43 
46  extensions = source.extensions;
47  source.extensions.clear();
48 }
49 
51 void ObjectExtensions::clear(bool destroy) {
52  for (Extensions::iterator i = extensions.begin(); i != extensions.end(); ++i) {
53  void* ptr = (*i).second;
54  if (ptr) {
55  ExtensionMap::iterator j = extensionMap->find((*i).first);
56  if (j != extensionMap->end()) {
57  Entry& e = (*j).second;
58  if (destroy && e.destruct)
59  (*(e.destruct))(ptr);
60  }
61  }
62  }
63  extensions.clear();
64 }
65 
67 void ObjectExtensions::copyFrom(const Extensions& ext, void* arg) {
68  for (Extensions::const_iterator i = ext.begin(); i != ext.end(); ++i) {
69  const std::type_info* info = (*i).first;
70  ExtensionMap::const_iterator j = extensionMap->find(info);
71  const Entry& e = (*j).second;
72  extensions[info] = (*(e.copy))((*i).second, arg);
73  }
74 }
75 
77 void* ObjectExtensions::addExtension(void* ptr, const std::type_info& info, destruct_t dtor) {
78  return addExtension(ptr, info, 0, dtor);
79 }
80 
82 void* ObjectExtensions::addExtension(void* ptr, const std::type_info& info, copy_t ctor, destruct_t dtor) {
83  Extensions::iterator j = extensions.find(&info);
84  if (j == extensions.end()) {
85  ExtensionMap::iterator i = extensionMap->find(&info);
86  if (i == extensionMap->end()) {
87  Entry entry;
88  entry.destruct = dtor;
89  entry.copy = ctor;
90  entry.id = ++s_extensionID;
91  extensionMap->insert(make_pair(&info, entry));
92  i = extensionMap->find(&info);
93  }
94  return extensions[&info] = ptr;
95  }
96  throw std::runtime_error("DD4hep: addExtension: Object already has an extension of type:" + typeName(info) + ".");
97 }
98 
100 void* ObjectExtensions::removeExtension(const std::type_info& info, bool destroy) {
101  Extensions::iterator j = extensions.find(&info);
102  if (j != extensions.end()) {
103  void *ptr = (*j).second;
104  if ( destroy ) {
105  ExtensionMap::iterator i = extensionMap->find(&info);
106  if (i != extensionMap->end()) {
107  Entry& e = (*i).second;
108  (*e.destruct)((*j).second);
109  ptr = 0;
110  }
111  }
112  extensions.erase(j);
113  return ptr;
114  }
115  throw std::runtime_error("DD4hep: removeExtension: The object of type " + typeName(info) + " is not present.");
116 }
117 
119 void* ObjectExtensions::extension(const std::type_info& info) const {
120  Extensions::const_iterator j = extensions.find(&info);
121  if (j != extensions.end()) {
122  return (*j).second;
123  }
124  throw std::runtime_error("DD4hep: extension: Object has no extension of type:" + typeName(info) + ".");
125 }
126 
128 void* ObjectExtensions::extension(const std::type_info& info, bool alert) const {
129  Extensions::const_iterator j = extensions.find(&info);
130  if (j != extensions.end()) {
131  return (*j).second;
132  }
133  else if ( !alert )
134  return 0;
135  throw std::runtime_error("DD4hep: extension: Object has no extension of type:" + typeName(info) + ".");
136 }
137 
Defintiion of the extension entry.
void move(ObjectExtensions &copy)
Move extensions to target object.
int id
std::map< const std::type_info *, void * > Extensions
Definition of the extension type.
std::map< const std::type_info *, Entry > ExtensionMap
Extensions extensions
The extensions object.
static void decrement(T *)
Decrement count according to type information.
std::string typeName(const std::type_info &type)
ABI information about type names.
Definition: Primitives.cpp:186
void copyFrom(const Extensions &ext, void *arg)
Copy object extensions from another object. Hosting type must be identical!
copy_t copy
return e
Definition: Volumes.cpp:297
ObjectExtensions(const std::type_info &parent_type)
Default constructor.
destruct_t destruct
void clear(bool destroy=true)
Clear all extensions.
static void increment(T *)
Increment count according to type information.
Definition: InstanceCount.h:98
virtual ~ObjectExtensions()
Default destructor.
void * extension(const std::type_info &info, bool alert) const
Access an existing extension object from the detector element.
void * addExtension(void *ptr, const std::type_info &info, copy_t ctor, destruct_t dtor)
Add an extension object to the detector element.
void * removeExtension(const std::type_info &info, bool destroy)
Remove an existing extension object from the instance.
Implementation of an object supporting arbitrary user extensions.
void * addExtension(void *ptr, const std::type_info &info, destruct_t dtor)
Add an extension object to the detector element.
ExtensionMap * extensionMap
Pointer to the extension map.