55 #include <type_traits>
58 #include "../general/util.h"
66 virtual const char*
what() const noexcept {
return "MUI Error [dynstorage.h]: Storage error, bad cast."; }
76 template<
typename T,
typename... Args>
struct get_typeid_;
77 template<
typename T,
typename Head,
typename... Tail>
struct get_typeid_<
T,Head,Tail...> {
78 typedef typename std::remove_reference<typename std::remove_cv<T>::type>::type type;
79 static constexpr std::int32_t value =
80 std::conditional<std::is_same<type,Head>::value,
81 std::integral_constant<std::int32_t,0>,
82 std::integral_constant<std::int32_t,1+get_typeid_<
T,Tail...>::value> >::type::value;
84 template<
typename T>
struct get_typeid_<
T> {
85 static constexpr std::int32_t value = 0;
89 template<std::int32_t i,
typename R,
typename... Args>
struct make_value_;
90 template<std::int32_t i,
typename R,
typename Head,
typename... Tail >
struct make_value_<i,R,Head,Tail...> {
92 static R
apply( std::int32_t which,
F f ) {
95 return f(std::move(head));
100 template<std::
int32_t i,
typename R>
struct make_value_<i,R> {
102 static R
apply(
int,
F ) {
throw bad_storage_id(
"MUI Error [dynstorage.h]: Storage error, bad type id."); }
106 template<
typename Head,
typename... Tail>
struct get_head_ {
typedef Head type; };
107 template<
typename... Types>
108 using get_head_t_ =
typename get_head_<Types...>::type;
111 template<id_t i,
typename R,
typename... Args>
struct apply_visitor_impl_;
112 template<id_t i,
typename R,
typename Head,
typename... Tail>
113 struct apply_visitor_impl_<i,R,Head,Tail...> {
115 static R
apply( id_t which,
void* content,
F& f ) {
116 if( i == which )
return f(*
static_cast<Head*
>(content));
120 static R
apply( id_t which,
const void* content,
F& f ) {
121 if( i == which )
return f(*
static_cast<const Head*
>(content));
125 static R applym( id_t which,
void* content,
F& f ) {
126 if( i == which )
return f(std::move(*
static_cast<Head*
>(content)));
127 else return apply_visitor_impl_<i+1,R,Tail...>::applym(which,content,f);
130 template<
id_t i,
typename R>
struct apply_visitor_impl_<i,R> {
132 static R
apply( id_t,
const void*,
F& ) {
throw bad_storage_id(
"MUI Error [dynstorage.h]: Storage error, bad id."); }
134 static R applym( id_t,
void*,
F& ) {
throw bad_storage_id(
"MUI Error [dynstorage.h]: Storage error, bad id."); }
136 template<
typename R,
typename... Types>
using applyer_ = apply_visitor_impl_<0,R,Types...>;
145 template<
typename... Types>
148 struct deleter_ {
template<
typename T>
void operator()(
T& t ){
delete std::addressof(t); } };
149 struct cloner_ {
template<
typename T>
void* operator()(
const T& t ){
return static_cast<void*
>(
new T(t)); } };
152 using Head_ = get_head_t_<Types...>;
157 storage(
const storage& rhs ) : which_(rhs.which_), content_(rhs.content_? rhs.clone_() : 0) {}
172 template<
typename ValueType>
174 : which_(get_typeid_<ValueType,Types...>::value),
175 content_(new ValueType(value)) {
176 static_assert(get_typeid_<ValueType,Types...>::value !=
bad_id,
177 "MUI Error [dynstorage.h]: Storage error, unsupported type. Please add type to type_list.");
179 template<
typename ValueType>
181 typename std::enable_if<!std::is_same<storage&,ValueType>::value>::type* = 0,
182 typename std::enable_if<!std::is_const<ValueType>::value>::type* = 0 )
183 : which_(get_typeid_<ValueType,Types...>::value),
184 content_(new typename std::decay<ValueType>::type(std::move(value))) {
185 static_assert(get_typeid_<ValueType,Types...>::value !=
bad_id,
186 "MUI Error [dynstorage.h]: Storage error, unsupported type. Please add type to type_list.");
189 template<
typename ValueType>
191 storage(std::forward<ValueType>(rhs)).swap(*
this);
204 bool empty() const noexcept {
return content_ == 0; }
205 explicit operator bool() const noexcept {
return !
empty(); }
210 template<
typename F,
typename R_=
typename std::result_of<F(const Head_&)>::type>
214 template<
typename F,
typename R_=
typename std::result_of<F(Head_&)>::type>
218 template<
typename F,
typename R_=
typename std::result_of<F(Head_&&)>::type>
220 return applyer_<R_,Types...>::applym(which_, content_, f);
228 template<
typename ValueType,
typename... Types2>
233 template<
typename... Args>
239 template<
typename ValueType,
typename... Args>
242 return obj && obj->
which() == get_typeid_<ValueType,Args...>::value ?
243 static_cast<ValueType*
>(obj->content_) : 0;
246 template<
typename ValueType,
typename... Args>
249 return storage_cast<ValueType>(
const_cast<storage<Args...
>*>(obj));
252 template<
typename ValueType,
typename... Args>
254 typedef typename std::remove_reference<ValueType>::type nonref;
255 nonref* result = storage_cast<nonref>(&obj);
258 typedef typename std::add_lvalue_reference<ValueType>::type ref_type;
259 return static_cast<ref_type
>(*result);
261 template<
typename ValueType,
typename... Args>
263 typedef typename std::remove_reference<ValueType>::type nonref;
264 return storage_cast<const nonref&>(
const_cast<storage<Args...
>&>(obj));
267 template<
typename ValueType,
typename... Args>
270 static_assert(std::is_rvalue_reference<ValueType&&>::value
271 || std::is_const<
typename std::remove_reference<ValueType>::type>::type,
272 "MUI Error [dynstorage.h]: This type of cast is not supported.");
273 return storage_cast<ValueType&&>(obj);
280 template<
typename T>
void operator()(
const T& t ){
ost << t; }
284 template<
typename... Args>
287 stream << st.
which();
293 template<
typename Storage>
294 struct deserializer {
295 template<
typename T> Storage operator()(
T&& t ){
297 return Storage(std::move(t));
302 template<
typename... Args>
306 typename type::id_t which;
308 st = (which == type::bad_id) ? type() :
istream & ist
Definition: dynstorage.h:299
ostream & ost
Definition: dynstorage.h:281
u u F
Definition: dim.h:351
istream & operator>>(istream &stream, smalluint &sml)
Definition: comm_tcp.h:103
ostream & operator<<(ostream &stream, const smalluint &sml)
Definition: comm_tcp.h:127
ValueType * storage_cast(storage< Args... > *obj)
Definition: dynstorage.h:240
void swap(storage< Args... > &lhs, storage< Args... > &rhs)
Definition: dynstorage.h:234
vexpr_apply1< E, OP, SCALAR, D > apply(vexpr< E, SCALAR, D > const &u, OP const &op)
Definition: point.h:392
Defines base stream class container_stream and associated functors.
Definition: dynstorage.h:65
virtual const char * what() const noexcept
Definition: dynstorage.h:66
Definition: dynstorage.h:62
bad_storage_id(const char *err)
Definition: dynstorage.h:63
Definition: dynstorage.h:146
friend ValueType * storage_cast(storage< Types2... > *)
storage(storage &&rhs) noexcept
Definition: dynstorage.h:158
storage & operator=(ValueType &&rhs)
Definition: dynstorage.h:190
std::int32_t id_t
Definition: dynstorage.h:155
~storage()
Definition: dynstorage.h:162
R_ apply_visitor(F f) &
Definition: dynstorage.h:215
storage(const ValueType &value)
Definition: dynstorage.h:173
static const id_t bad_id
Definition: dynstorage.h:207
storage & operator=(storage rhs)
Definition: dynstorage.h:167
storage(const storage &rhs)
Definition: dynstorage.h:157
void clear() noexcept
Definition: dynstorage.h:203
void swap(storage &rhs) noexcept
Definition: dynstorage.h:195
storage() noexcept
Definition: dynstorage.h:156
id_t which() const
Definition: dynstorage.h:208
storage(ValueType &&value, typename std::enable_if<!std::is_same< storage &, ValueType >::value >::type *=0, typename std::enable_if<!std::is_const< ValueType >::value >::type *=0)
Definition: dynstorage.h:180
R_ apply_visitorm(F f) &&
Definition: dynstorage.h:219
R_ apply_visitor(F f) const &
Definition: dynstorage.h:211
bool empty() const noexcept
Definition: dynstorage.h:204