MarlinMT  0.1.0
Extensions.h
Go to the documentation of this file.
1 #pragma once
2 
3 // -- std headers
4 #include <memory>
5 #include <map>
6 #include <typeindex>
7 
8 // -- marlinmt headers
9 #include <marlinmt/Exceptions.h>
10 
11 namespace marlinmt {
12 
13  class Extension {
14  public:
15  Extension() = delete ;
16  Extension( const Extension & ) = delete ;
17  Extension &operator =( const Extension & ) = delete ;
18  ~Extension() = default ;
19 
20  public:
21  template <typename T>
22  inline Extension( T *obj, bool isOwned ) :
23  _isOwned(isOwned) ,
24  _typeidx(typeid(T)) {
25  if( _isOwned ) {
26  _object = std::shared_ptr<T>( obj ) ;
27  }
28  else {
29  _object = std::shared_ptr<T>( obj, [](T *){ /* nop */ } ) ;
30  }
31  }
32 
33  template <typename T>
34  inline const T *object() const {
35  return static_cast<const T*>(_object.get()) ;
36  }
37 
38  template <typename T>
39  inline T *object() {
40  return static_cast<T*>(_object.get()) ;
41  }
42 
43  template <typename T>
44  inline std::shared_ptr<const T> shared() const {
45  return std::static_pointer_cast<const T>(_object) ;
46  }
47 
48  template <typename T>
49  inline std::shared_ptr<T> shared() {
50  return std::static_pointer_cast<T>(_object);
51  }
52 
53  inline bool isOwned() const {
54  return _isOwned ;
55  }
56 
57  inline const std::type_index &type() const {
58  return _typeidx ;
59  }
60 
61  private:
62  bool _isOwned {} ;
63  std::type_index _typeidx ;
64  std::shared_ptr<void> _object {} ;
65  };
66 
71  class Extensions {
72  public:
73  using ExtensionMap = std::map<std::size_t, std::shared_ptr<Extension>> ;
74 
75  public:
76  Extensions() = default ;
77  ~Extensions() = default ;
78  Extensions(const Extensions &) = delete ;
79  Extensions &operator=(const Extensions &) = delete ;
80  Extensions(Extensions &&) = default ;
81  Extensions &operator=(Extensions &&) = default ;
82 
83  template <typename K>
84  inline bool exits() const {
85  return ( _extensions.find( std::type_index(typeid(K)).hash_code() ) != _extensions.end() ) ;
86  }
87 
88  template <typename K, typename T>
89  inline void add( T *ptr, bool isOwned = true ) {
90  std::type_index typeidx( typeid(K) ) ;
91  auto iter = _extensions.find( typeidx.hash_code() ) ;
92  if( iter != _extensions.end() ) {
93  MARLINMT_THROW( "Extension of type " + std::string(typeidx.name()) + " already present" ) ;
94  }
95  auto ext = std::make_shared<Extension>( ptr, isOwned ) ;
96  _extensions.insert( { typeidx.hash_code(), ext } ) ;
97  }
98 
99  template <typename K, typename T, typename ...Args>
100  inline T* create( bool isOwned, Args ...args ) {
101  std::type_index typeidx( typeid(K) ) ;
102  auto iter = _extensions.find( typeidx.hash_code() ) ;
103  if( iter != _extensions.end() ) {
104  MARLINMT_THROW( "Extension of type " + std::string(typeidx.name()) + " already present" ) ;
105  }
106  auto ext = std::make_shared<Extension>( new T( args... ), isOwned ) ;
107  _extensions.insert( { typeidx.hash_code(), ext } ) ;
108  return ext->template object<T>() ;
109  }
110 
111  template <typename K, typename T>
112  inline T *get() {
113  std::type_index typeidx( typeid(K) ) ;
114  auto iter = _extensions.find( typeidx.hash_code() ) ;
115  if( iter == _extensions.end() ) {
116  MARLINMT_THROW( "Extension of type " + std::string(typeidx.name()) + " doesn't exists" ) ;
117  }
118  return iter->second->object<T>() ;
119  }
120 
121  template <typename K, typename T>
122  inline const T *get() const {
123  std::type_index typeidx( typeid(K) ) ;
124  auto iter = _extensions.find( typeidx.hash_code() ) ;
125  if( iter == _extensions.end() ) {
126  MARLINMT_THROW( "Extension of type " + std::string(typeidx.name()) + " doesn't exists" ) ;
127  }
128  return iter->second->object<T>() ;
129  }
130 
131  template <typename K>
132  inline void remove() {
133  std::type_index typeidx( typeid(K) ) ;
134  auto iter = _extensions.find( typeidx.hash_code() ) ;
135  if( iter == _extensions.end() ) {
136  MARLINMT_THROW( "Extension of type " + std::string(typeidx.name()) + " doesn't exists" ) ;
137  }
138  _extensions.erase( iter ) ;
139  }
140 
141  private:
143  ExtensionMap _extensions {} ;
144  };
145 
146 }
Extension & operator=(const Extension &)=delete
void add(T *ptr, bool isOwned=true)
Definition: Extensions.h:89
const T * object() const
Definition: Extensions.h:34
Extensions class.
Definition: Extensions.h:71
bool isOwned() const
Definition: Extensions.h:53
std::shared_ptr< void > _object
Definition: Extensions.h:64
std::shared_ptr< T > shared()
Definition: Extensions.h:49
const std::type_index & type() const
Definition: Extensions.h:57
#define MARLINMT_THROW(message)
Definition: Exceptions.h:8
T * create(bool isOwned, Args ...args)
Definition: Extensions.h:100
std::type_index _typeidx
Definition: Extensions.h:63
std::shared_ptr< const T > shared() const
Definition: Extensions.h:44
bool exits() const
Definition: Extensions.h:84
Extension(T *obj, bool isOwned)
Definition: Extensions.h:22
std::map< std::size_t, std::shared_ptr< Extension > > ExtensionMap
Definition: Extensions.h:73