MarlinMT  0.1.0
Entry.h
Go to the documentation of this file.
1 #pragma once
2 
3 // -- std includes
4 #include <iostream>
5 #include <memory>
6 #include <tuple>
7 #include <typeinfo>
8 #include <variant>
9 
10 // -- Marlin includes
11 // #include "marlinmt/Exceptions.h"
12 
13 // -- MarlinBook includes
15 #include "marlinmt/book/Flags.h"
17 #include "marlinmt/book/Types.h"
18 
19 namespace marlinmt {
20  namespace book {
21 
26  template < typename T >
27  class EntrySingle : public EntryBase {
28  friend BookStore ;
29 
31  explicit EntrySingle( Context context )
32  : _context{std::move( context )} {}
33 
34  public:
35  static constexpr Flag_t Flag = Flags::Book::Single;
37  EntrySingle() = default ;
38 
41  return Handle( _context.mem, _context.mem->at< T >( 0 ) ) ;
42  }
43 
44  private:
47  } ;
48 
54  template < typename T >
55  class EntryMultiCopy : public EntryBase {
56  friend BookStore ;
57 
59  explicit EntryMultiCopy( Context context )
60  : _context{std::move( context )} {}
61 
62  public:
63  static constexpr Flag_t Flag = Flags::Book::MultiCopy;
65  EntryMultiCopy() = default ;
66 
72  Handle< T > handle( std::size_t idx ) {
73  return Handle( _context.mem, _context.mem->at< T >( idx ) ) ;
74  }
75 
76  private:
79  } ;
80 
86  template < typename T >
87  class EntryMultiShared : public EntryBase {
88  friend BookStore ;
89 
91  explicit EntryMultiShared( Context context )
92  : _context{std::move( context )} {}
93 
94  public:
95  static constexpr Flag_t Flag = Flags::Book::MultiShared;
97  EntryMultiShared() = default ;
98 
104  return Handle( _context.mem, _context.mem->at< T >( 0 ) ) ;
105  }
106 
107  private:
110  } ;
111 
112  template<typename Type>
113  using EntryTypes = std::tuple<
117  >;
118 
119  namespace details {
120 
124  class Entry {
125  friend BookStore ;
126 
128  Entry( std::shared_ptr< EntryBase > entry, EntryKey key )
129  : _key{std::move( key )}, _entry{std::move( entry )} {}
130 
132  void clear() {
133  _key = EntryKey{} ;
134  _entry.reset() ;
135  }
136 
137 
139  struct EntryHelper {
140  static void ThrowIfOutOfBound(const EntryKey& key, std::size_t idx) {
141  if(idx >= key.mInstances) {
142  auto itoa = [](std::size_t id){
143  return std::to_string(id);
144  };
146  (std::string("Try to access instances '") + itoa(idx)
147  + "', which is outside of [0;"
148  + itoa(key.mInstances-1) + "]"));
149  }
150  }
151 
152  enum struct Need { Void, Index, VoidIndex };
153 
154  template<typename R, typename ET, R(ET::*)(std::size_t)>
155  struct need_index {
156  static constexpr bool value = true;};
157 
158  template<typename R, typename ET, R(ET::*)(void)>
159  struct need_void {
160  static constexpr bool value = true;};
161 
162  template<typename T, typename TF>
163  struct Conclusion {
164  template<typename R, typename ET>
165  static constexpr std::true_type
167  {return {};}
168  template<typename, typename>
169  static constexpr std::false_type n_index(...)
170  {return {};}
171 
172  template<typename R, typename ET>
173  static constexpr std::true_type
175  template<typename, typename>
176  static constexpr std::false_type
177  n_void(...) {return{};}
178 
179  static constexpr Need needs() {
180  static_assert(
181  n_index<T,TF>(nullptr).value
182  || n_void<T,TF>(nullptr).value, "no valid handle");
183  if constexpr (
184  n_index<T,TF>(nullptr).value
185  && n_void<T,TF>(nullptr).value) {
186  return Need::VoidIndex;
187  } else if constexpr (
188  n_index<T,TF>(nullptr).value) {
189  return Need::Index;
190  } else {
191  return Need::Void;
192  }
193  }
194  };
195 
196  template<typename T, typename ET>
197  static constexpr Need handle_need_v =
198  Conclusion<Handle<T>,ET>::needs();
199 
200  template<typename T, std::size_t I = 0>
201  [[nodiscard]]
203  std::shared_ptr<EntryBase> entry,
204  const EntryKey& key,
205  std::size_t idx) {
206  using EntryType = std::tuple_element_t<I, EntryTypes<T>>;
207 
208  if (key.flags == EntryType::Flag) {
209  constexpr Need need = handle_need_v<T, EntryType>;
210  std::shared_ptr<EntryType> pEntry =
211  std::static_pointer_cast<EntryType>(entry);
212  if constexpr (need == Need::Index) {
213  ThrowIfOutOfBound(key, idx);
214  return pEntry->handle(idx);
215  } else if constexpr (need == Need::Void){
216  return pEntry->handle();
217  } else if constexpr (need == Need::VoidIndex) {
218  if (idx != -1) {
219  ThrowIfOutOfBound(key, idx);
220  return pEntry->handle(idx);
221  } else {
222  return pEntry->handle();
223  }
224  }else {
225  static_assert(I!=I, "no callable Handle function");
226  }
227  }
228 
229  if constexpr (I + 1 < (std::tuple_size_v<EntryTypes<T>>)) {
230  return handle<T, I + 1>(entry, key, idx);
231  } else {
233  "Entry has an invalid Flag combination! Can't create Handle!" ) ;
234  }
235  }
236  };
237 
238  public:
240  Entry() = default ;
241 
249  template < class T >
250  [[nodiscard]] Handle< T > handle( std::size_t idx = -1 ) const {
251  if ( std::type_index( typeid( T ) ) != _key.type ) {
252  MARLIN_BOOK_THROW( "Entry is not demanded type. Can't create Handle!" ) ;
253  }
254 
255  return EntryHelper::handle<T>(_entry, key(), idx);
256 
257  }
258 
260  [[nodiscard]] const EntryKey &key() const { return _key; }
261 
267  [[nodiscard]] bool valid() const { return _entry != nullptr; }
268 
269  private:
271  EntryKey _key{std::type_index( typeid( void ) )} ;
273  std::shared_ptr< EntryBase > _entry{nullptr} ;
274  } ;
275 
276  } // end namespace details
277  } // end namespace book
278 } // end namespace marlinmt
static Handle< T > handle(std::shared_ptr< EntryBase > entry, const EntryKey &key, std::size_t idx)
Definition: Entry.h:202
class which helps to access entry from the different EntryTypes
Definition: Entry.h:139
Data selection to identify and manage an Entry.
Definition: EntryData.h:21
Context _context
Context of the Entry. Containing needed references.
Definition: Entry.h:46
std::tuple< EntrySingle< Type >, EntryMultiCopy< Type >, EntryMultiShared< Type > > EntryTypes
Definition: Entry.h:117
static constexpr Flag_t Flag
Definition: Entry.h:35
static constexpr std::false_type n_index(...)
Definition: Entry.h:169
std::size_t mInstances
number of memory instances
Definition: EntryData.h:32
Flag_t flags
Status flags from Entry.
Definition: EntryData.h:36
static constexpr std::true_type n_index(need_index< R, ET, &ET::handle > *)
Definition: Entry.h:166
static void ThrowIfOutOfBound(const EntryKey &key, std::size_t idx)
Definition: Entry.h:140
entry for object to be used Multithreaded.
Definition: Entry.h:87
Handle< T > handle()
Creates a new Handle for the object.
Definition: Entry.h:40
EntrySingle()=default
default constructor
constexpr unsigned long long value(const Flag_t &flag)
Definition: Flags.h:106
#define MARLIN_BOOK_THROW(message)
Definition: Types.h:10
EntryMultiShared(Context context)
constructor
Definition: Entry.h:91
EntryMultiCopy(Context context)
constructor
Definition: Entry.h:59
void clear()
reduce Entry to default constructed version.
Definition: Entry.h:132
const EntryKey & key() const
access key data from entry.
Definition: Entry.h:260
Flag type for flags in marlinmt::book.
Definition: Flags.h:15
Handle< T > handle(std::size_t idx=-1) const
creates an handle for the entry.
Definition: Entry.h:250
constexpr Flag_t MultiShared(1U<< 1U)
create one instance witch concurrent access.
Handle< T > handle()
creates a new handle for the object.
Definition: Entry.h:103
Base type for Entries. To avoid void pointer.
Definition: EntryData.h:88
EntrySingle(Context context)
constructor
Definition: Entry.h:31
entry for object to be used Multithreaded.
Definition: Entry.h:55
std::shared_ptr< MemLayout > mem
reference to Memory object. For editing and reading data.
Definition: EntryData.h:83
minimal entry for Object.
Definition: Entry.h:27
constexpr Flag_t MultiCopy(1U<< 2U)
create multiple instances of booked object (if possible) to avoid sync points
bool valid() const
check if entry is valid.
Definition: Entry.h:267
vanilla Handle.
Definition: Handle.h:54
static constexpr std::true_type n_void(need_void< R, ET, &ET::handle > *)
Definition: Entry.h:174
Handle< T > handle(std::size_t idx)
creates a new handle for the object.
Definition: Entry.h:72
Entry(std::shared_ptr< EntryBase > entry, EntryKey key)
constructor
Definition: Entry.h:128
Data selection for the Entry to work properly.
Definition: EntryData.h:71
class to store and manage objects in BookStore.
Definition: Entry.h:124
static constexpr std::false_type n_void(...)
Definition: Entry.h:177
constexpr Flag_t Single(1U<< 0U)
vanilla object.