simple thread
data.hpp
1 //SPDX-License-Identifier: LicenseRef-Apache-License-2.0
2 //Author: Blayne Dennis
3 
4 #ifndef __SIMPLE_THREADING_DATA__
5 #define __SIMPLE_THREADING_DATA__
6 
7 #include <memory>
8 #include <typeinfo>
9 #include <type_traits>
10 
11 #include "utility.hpp"
12 
13 namespace st { // simple thread
14 
24 struct data {
25  // default type_info helper struct when unallocated
26  struct unset { };
27 
29  data() :
30  m_type_info(&typeid(unset)),
31  m_data_ptr(data_pointer_t(nullptr, data::no_delete))
32  { }
33 
35  data(data&& rhs) :
36  m_type_info(rhs.m_type_info),
37  m_data_ptr(std::move(rhs.m_data_ptr))
38  { }
39 
40  virtual ~data() {}
41 
48  template <typename T, typename... As>
49  static data make(As&&... as) {
50  return data(detail::hint<typename std::remove_reference<T>::type>(), std::forward<As>(as)...);
51  }
52 
54  inline data& operator=(data&& rhs) {
55  m_type_info = rhs.m_type_info;
56  m_data_ptr = std::move(rhs.m_data_ptr);
57  return *this;
58  }
59 
61  data(const data& rhs) = delete;
62  data& operator=(const data& rhs) = delete;
63 
67  inline operator bool() const {
68  return m_data_ptr.data_pointer_t::operator bool();
69  }
70 
76  inline const std::type_info& type_info() const {
77  return *m_type_info;
78  }
79 
84  template <typename T>
85  bool is() const {
86  return m_data_ptr && *m_type_info == typeid(T);
87  }
88 
92  inline void* get() {
93  return m_data_ptr.get();
94  }
95 
106  template <typename T>
107  T& cast_to() {
108  return *((detail::base<T>*)(get()));
109  }
110 
117  template <typename T>
118  bool copy_to(T& t) {
119  if(is<T>()) {
120  t = cast_to<T>();
121  return true;
122  } else {
123  return false;
124  }
125  }
126 
133  template <typename T>
134  bool move_to(T& t) {
135  if(is<T>()) {
136  std::swap(t, cast_to<T>());
137  return true;
138  } else {
139  return false;
140  }
141  }
142 
143 private:
144  typedef void(*deleter_t)(void*);
145  typedef std::unique_ptr<void,deleter_t> data_pointer_t;
146  typedef void*(*allocator_t)(void*);
147 
148  template <typename T, typename... As>
149  data(detail::hint<T> h, As&&... as) :
150  m_type_info(&typeid(T)),
151  m_data_ptr(allocate<T>(std::forward<As>(as)...),data::deleter<T>)
152  { }
153 
154  template <typename T, typename... As>
155  static void* allocate(As&&... as) {
156  return (void*)(new detail::base<T>(std::forward<As>(as)...));
157  }
158 
159  template <typename T>
160  static void deleter(void* p) {
161  delete (detail::base<T>*)p;
162  }
163 
164  static inline void no_delete(void* p) { }
165 
166  const std::type_info* m_type_info; // type code
167  data_pointer_t m_data_ptr; // stored data
168 };
169 
170 }
171 
172 #endif
Definition: data.hpp:26
type erased data container
Definition: data.hpp:24
data(const data &rhs)=delete
no lvalue constructor or copy
data()
default constructor
Definition: data.hpp:29
data(data &&rhs)
rvalue constructor
Definition: data.hpp:35
bool copy_to(T &t)
copy the data payload to argument t
Definition: data.hpp:118
bool is() const
determine at runtime whether the type erased data type code matches the templated type code.
Definition: data.hpp:85
const std::type_info & type_info() const
Definition: data.hpp:76
bool move_to(T &t)
rvalue swap the data payload to argument t
Definition: data.hpp:134
T & cast_to()
cast message data payload to templated type reference
Definition: data.hpp:107
data & operator=(data &&rhs)
rvalue copy
Definition: data.hpp:54
void * get()
Definition: data.hpp:92
static data make(As &&... as)
construct a data payload using explicit template typing instead of by deduction
Definition: data.hpp:49