Go to the documentation of this file.
14 #include <unordered_map>
27 return h ==
typeid(T).hash_code();
30 template<
typename T,
typename U,
typename... Args>
39 return name == type_name<T>();
42 template<
typename T,
typename U,
typename... Args>
45 return is_valid_name<T>(name) ||
is_valid_name<U, Args...>(name);
55 template<
typename C,
typename RetT,
typename... Args>
58 using fn_t = std::function<RetT(Args...)>;
62 template<
typename C,
typename RetT,
typename... Args>
65 using fn_t = std::function<RetT(Args...)>;
77 using decay_t =
typename std::decay<T>::type;
78 static constexpr
bool is_arithmetic = std::is_arithmetic<decay_t>::value;
79 using type =
typename std::conditional<is_arithmetic, decay_t, T>::type;
83 template<
typename T,
typename =
void>
90 struct Allocator<T, typename T::eigen_aligned_operator_new_marker_type> :
public Eigen::aligned_allocator<T>
147 inline bool has(
const std::string &
name)
const noexcept {
return datas_.find(
name) != datas_.end(); }
152 inline std::vector<std::string>
keys() const noexcept
154 std::vector<std::string> out;
155 out.reserve(datas_.size());
156 for(
const auto & d : datas_) { out.push_back(d.first); }
173 return const_cast<T &
>(get_<T>(
name));
180 return get_<T>(
name);
193 auto it = datas_.find(
name);
194 if(it != datas_.end()) { data = safe_cast<T>(it->second,
name); }
207 const T &
get(
const std::string &
name,
const T & defaultValue)
const
209 auto it = datas_.find(
name);
210 if(it != datas_.end()) {
return safe_cast<T>(it->second,
name); }
241 template<
typename T,
typename... ArgsT,
typename... Args>
242 T &
make(
const std::string &
name, Args &&... args)
244 auto & data = datas_[
name];
246 data.allocate<T>(name_,
name);
247 new(data.buffer.get()) T(std::forward<Args>(args)...);
248 return data.setup<T, ArgsT...>();
265 return make<fn_t>(
name, fn_t(fn));
276 template<
typename T,
typename... ArgsT,
typename... Args>
279 auto & data = datas_[
name];
281 data.allocate<T>(name_,
name);
282 new(data.buffer.get()) T{std::forward<Args>(args)...};
283 return data.setup<T, ArgsT...>();
303 template<
typename RetT,
304 typename... FuncArgsT,
306 typename std::enable_if<
sizeof...(FuncArgsT) ==
sizeof...(ArgsT)
307 && !std::is_same<std::tuple<FuncArgsT...>, std::tuple<ArgsT...>>::value,
309 RetT
call(
const std::string &
name, ArgsT &&... args)
const
311 return safe_call<RetT, FuncArgsT...>(
name, std::forward<ArgsT>(args)...);
332 template<
typename RetT = void,
typename... ArgsT>
333 RetT
call(
const std::string &
name, ArgsT &&... args)
const
335 return safe_call<RetT, typename internal::args_t<ArgsT>::type...>(
name, std::forward<ArgsT>(args)...);
344 auto it = datas_.find(
name);
345 if(it == datas_.end())
347 log::error(
"[{}] Failed to remove element \"{}\" (element does not exist)", name_,
name);
356 inline void clear() noexcept { datas_.clear(); }
361 inline const std::string &
name() const noexcept {
return name_; }
374 Data(
const Data &) =
delete;
376 Data(Data &&) =
default;
380 std::unique_ptr<uint8_t[]> buffer;
382 std::string (*type)();
384 bool (*same)(std::size_t);
386 bool (*same_name)(
const std::string &);
388 void (*destroy)(Data &);
392 if(buffer) { destroy(*
this); }
396 void allocate(
const std::string & name_,
const std::string &
name)
399 buffer.reset(
reinterpret_cast<uint8_t *
>(internal::Allocator<T>().allocate(1)));
402 template<
typename T,
typename... ArgsT>
405 this->type = &type_name<T>;
408 this->destroy = [](Data &
self)
410 T * p =
reinterpret_cast<T *
>(
self.buffer.release());
412 internal::Allocator<T>().deallocate(p, 1);
414 return *(
reinterpret_cast<T *
>(buffer.get()));
419 const T & safe_cast(
const Data & data,
const std::string &
name)
const
421 if(!data.same(
typeid(T).hash_code()) && !data.same_name(type_name<T>()))
424 "[{} Object for key \"{}\" does not have the same type as the stored type. Stored {} but requested {}.",
425 name_,
name, data.type(), type_name<T>());
427 return *(
reinterpret_cast<T *
>(data.buffer.get()));
430 template<
typename RetT,
typename... FuncArgsT,
typename... ArgsT>
431 RetT safe_call(
const std::string &
name, ArgsT &&... args)
const
433 const auto & data = get_data(
name);
434 using fn_t = std::function<RetT(FuncArgsT...)>;
435 if(!data.same(
typeid(fn_t).hash_code()) && !data.same_name(type_name<fn_t>()))
438 "requested one. Stored {} but requested {}",
439 name_,
name, data.type(), type_name<fn_t>());
441 auto & fn = *(
reinterpret_cast<fn_t *
>(data.buffer.get()));
442 return fn(std::forward<ArgsT>(args)...);
446 const T & get_(
const std::string &
name)
const
448 return safe_cast<T>(get_data(
name),
name);
451 inline const Data & get_data(
const std::string &
name)
const
453 const auto it = datas_.find(
name);
459 std::unordered_map<std::string, Data> datas_;
460 std::string name_ =
"DataStore";
RetT call(const std::string &name, ArgsT &&... args) const
Calls a function that was registered in the datastore and returns this call result.
Definition: DataStore.h:309
bool has(const std::string &name) const noexcept
Checks whether an object is in the datastore.
Definition: DataStore.h:147
void clear() noexcept
Remove all entries in the datastore.
Definition: DataStore.h:356
bool is_valid_name(const std::string &name)
Definition: DataStore.h:37
std::function< RetT(Args...)> fn_t
Definition: DataStore.h:65
T & make_initializer(const std::string &name, Args &&... args)
Creates an object on the datastore using list initialization and returns a reference to it.
Definition: DataStore.h:277
typename std::decay< T >::type decay_t
Definition: DataStore.h:77
auto make_call(const std::string &name, T fn) -> typename internal::lambda_traits< T >::fn_t &
Creates an object on the datastore and returns a reference to it.
Definition: DataStore.h:262
const T & get(const std::string &name) const
const variant of get
Definition: DataStore.h:178
Generic data store.
Definition: DataStore.h:132
std::function< RetT(Args...)> fn_t
Definition: DataStore.h:58
typename std::conditional< is_arithmetic, decay_t, T >::type type
Definition: DataStore.h:79
T & make(const std::string &name, Args &&... args)
Creates an object on the datastore and returns a reference to it.
Definition: DataStore.h:242
static constexpr bool is_arithmetic
Definition: DataStore.h:78
std::vector< std::string > keys() const noexcept
Returns all objects in the datastore.
Definition: DataStore.h:152
Definition: DataStore.h:50
void assign(const std::string &name, const T &data)
Copies an object to an existing datastore object.
Definition: DataStore.h:223
Definition: DataStore.h:75
T & get(const std::string &name)
Get a reference to an object on the datastore.
Definition: DataStore.h:171
RetT call(const std::string &name, ArgsT &&... args) const
Calls a function that was registered in the datastore and returns this call result.
Definition: DataStore.h:333
void error_and_throw(Args &&... args)
Definition: logging.h:47
DataStore & operator=(const DataStore &)=delete
void get(const std::string &name, T &data)
Assign value from the datastore if it exists, leave value unchanged otherwise.
Definition: DataStore.h:191
void remove(const std::string &name) noexcept
Removes an object from the datastore.
Definition: DataStore.h:342
void name(const std::string &name) noexcept
Sets this datastore's name.
Definition: DataStore.h:368
void error(Args &&... args)
Definition: logging.h:63
const std::string & name() const noexcept
Name of this datastore.
Definition: DataStore.h:361
Definition: DataStore.h:84
const T & get(const std::string &name, const T &defaultValue) const
Gets a value from the datastore if it exists or a default value otherwise.
Definition: DataStore.h:207
bool is_valid_hash(std::size_t h)
Definition: DataStore.h:25