Skip to content
Snippets Groups Projects
Commit cba6f2ee authored by Jan Trávníček's avatar Jan Trávníček
Browse files

working variant type

parent af479664
No related branches found
No related tags found
No related merge requests found
#ifndef TYPE_TRAITS_HPP_
#define TYPE_TRAITS_HPP_
#include <type_traits>
namespace std {
template <typename T>
struct is_base_of<T, T> {
static const bool value = true;
};
template <typename T, typename... Ts>
struct is_base_of_any;
template <typename T, typename F>
struct is_base_of_any<T, F>
{
static const bool value = is_base_of<T, F>::value;
};
template <typename T, typename F, typename... Ts>
struct is_base_of_any<T, F, Ts...>
{
static const bool value = is_base_of<T, F>::value || is_base_of_any<T, Ts...>::value;
};
}
#endif
......@@ -5,10 +5,13 @@
* Modified: Jan Travnicek
*/
 
#ifndef VATIANT_HPP_
#define VATIANT_HPP_
#include <iostream>
#include <utility>
#include <typeinfo>
#include <type_traits>
#include "type_traits.hpp"
#include <string>
 
template <size_t arg1, size_t ... others>
......@@ -42,10 +45,11 @@ struct variant_helper<F, Ts...> {
 
inline static void move(size_t old_t, void * old_v, void * new_v)
{
if (old_t == typeid(F).hash_code())
if (old_t == typeid(F).hash_code()) {
new (new_v) F(std::move(*reinterpret_cast<F*>(old_v)));
else
variant_helper<Ts...>::move(old_t, old_v, new_v);
return true;
} else
return variant_helper<Ts...>::move(old_t, old_v, new_v);
}
 
inline static void copy(size_t old_t, const void * old_v, void * new_v)
......@@ -79,7 +83,7 @@ struct variant_helper<F, Ts...> {
 
template<> struct variant_helper<> {
inline static void destroy(size_t id, void * data) { }
inline static void move(size_t old_t, void * old_v, void * new_v) { }
inline static bool move(size_t old_t, void * old_v, void * new_v) { return false; }
inline static void copy(size_t old_t, const void * old_v, void * new_v) { }
inline static bool compareEq(size_t this_t, const void * this_v, size_t other_t, const void * other_v) { return true; }
inline static bool compareLess(size_t this_t, const void * this_v, size_t other_t, const void * other_v) { return false; }
......@@ -147,15 +151,28 @@ public:
return (type_id == typeid(T).hash_code());
}
template<typename T, typename... Args>
void set(Args&&... args)
template<typename T>
void set(T&& value)
{
// First we destroy the current contents
helper_t::destroy(type_id, &data);
new (&data) T(std::forward<Args>(args)...);
type_id = typeid(T).hash_code();
if(std::is_base_of_any<T, F, Ts...>::value) {
helper_t::destroy(type_id, &data);
new (&data) T(value);
type_id = typeid(T).hash_code();
} else
throw std::bad_cast();
}
template<typename T>
void set(T& value)
{
if(std::is_base_of_any<T, F, Ts...>::value) {
helper_t::destroy(type_id, &data);
new (&data) T(value);
type_id = typeid(T).hash_code();
} else
throw std::bad_cast();
}
template<typename T>
T& get()
{
......@@ -170,3 +187,5 @@ public:
helper_t::destroy(type_id, &data);
}
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment