diff --git a/alib/src/std/variant.hpp b/alib/src/std/variant.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f9c3d641b8a3ffab4072936824d070b6fd4ff455
--- /dev/null
+++ b/alib/src/std/variant.hpp
@@ -0,0 +1,127 @@
+/**
+ *  https://gist.github.com/tibordp/6909880
+ *  Created on: Feb 28, 2014
+ * 	Author: Tibor Djurica Potpara
+ *      Modified: Jan Travnicek
+ */
+
+#include <iostream>
+#include <utility>
+#include <typeinfo>
+#include <type_traits>
+#include <string>
+ 
+template <size_t arg1, size_t ... others>
+struct static_max;
+ 
+template <size_t arg>
+struct static_max<arg>
+{
+	static const size_t value = arg;
+};
+ 
+template <size_t arg1, size_t arg2, size_t ... others>
+struct static_max<arg1, arg2, others...>
+{
+	static const size_t value = arg1 >= arg2 ? static_max<arg1, others...>::value :
+	static_max<arg2, others...>::value;
+};
+ 
+template<typename... Ts>
+struct variant_helper;
+ 
+template<typename F, typename... Ts>
+struct variant_helper<F, Ts...> {
+	inline static void destroy(size_t id, void * data) 
+	{
+		if (id == typeid(F).hash_code())
+			reinterpret_cast<F*>(data)->~F();
+		else
+			variant_helper<Ts...>::destroy(id, data);
+	}
+ 
+	inline static void move(size_t old_t, void * old_v, void * new_v)
+	{
+		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);       
+	}
+ 
+	inline static void copy(size_t old_t, const void * old_v, void * new_v)
+	{
+		if (old_t == typeid(F).hash_code())
+			new (new_v) F(*reinterpret_cast<const F*>(old_v));
+		else
+			variant_helper<Ts...>::copy(old_t, old_v, new_v);       
+	}   
+};
+ 
+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 void copy(size_t old_t, const void * old_v, void * new_v) { }
+};
+ 
+template<typename F, typename... Ts>
+struct variant {
+private: 
+	static const size_t data_size = static_max<sizeof(F), sizeof(Ts)...>::value;
+	static const size_t data_align = static_max<alignof(F), alignof(Ts)...>::value;
+ 
+	using data_t = typename std::aligned_storage<data_size, data_align>::type;
+ 
+	using helper_t = variant_helper<F, Ts...>;
+ 
+	size_t type_id;
+	data_t data;
+public: 
+	variant() : type_id(typeid(F).hash_code()) { new (&data) F();  }
+ 
+	variant(const variant<F, Ts...>& old) : type_id(old.type_id)
+	{
+		helper_t::copy(old.type_id, &old.data, &data);
+	}
+ 
+	variant(variant<F, Ts...>&& old) : type_id(old.type_id)
+	{
+		helper_t::move(old.type_id, &old.data, &data);
+	}
+ 
+	// Serves as both the move and the copy asignment operator.
+	variant<F, Ts...>& operator= (variant<F, Ts...> old)
+	{
+		std::swap(type_id, old.type_id);
+		std::swap(data, old.data);
+ 
+		return *this;
+	}
+ 
+	template<typename T>
+	void is() {
+		return (type_id == typeid(T).hash_code());
+	}
+ 
+	template<typename T, typename... Args>
+	void set(Args&&... args)
+	{
+		// 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();
+	}
+ 
+	template<typename T>
+	T& get()
+	{
+		// It is a dynamic_cast-like behaviour
+		if (type_id == typeid(T).hash_code())
+			return *reinterpret_cast<T*>(&data);
+		else
+			throw std::bad_cast();
+	}   
+ 
+	~variant() {
+		helper_t::destroy(type_id, &data);
+	}
+};