Last active
August 1, 2024 08:18
-
-
Save Mr-Andersen/cd5f9d8740e03b3a779bd49da281652d to your computer and use it in GitHub Desktop.
Revisions
-
Mr-Andersen revised this gist
Sep 25, 2023 . No changes.There are no files selected for viewing
-
Mr-Andersen revised this gist
Sep 25, 2023 . No changes.There are no files selected for viewing
-
Mr-Andersen revised this gist
Sep 25, 2023 . No changes.There are no files selected for viewing
-
Mr-Andersen revised this gist
Sep 25, 2023 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -69,7 +69,7 @@ class Variant { } template<typename T> bool is() const { return this->curr_type == index_type<T, Ts...>::value; } -
Andrew Andersen created this gist
Jul 29, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,99 @@ #include <iostream> // get_type<i, Ts...>::type -> Ts[i] (Compile error of i >= length(Ts)) template<size_t i, typename T, typename... Ts> struct get_type { typedef typename get_type<i - 1, Ts...>::type type; }; template<typename T, typename... Ts> struct get_type<0, T, Ts...> { typedef T type; }; // Ts[index_type<A, Ts...>::value] == A (Compilation error if A not in Ts) template<typename A, typename T, typename... Ts> struct index_type { static const size_t value = index_type<A, Ts...>::value + 1; }; template<typename A, typename... Ts> struct index_type<A, A, Ts...> { static const size_t value = 0; }; template<typename T> constexpr T max(const T& a, const T& b) { return a > b ? a : b; } // max_size<Ts...>::value template<typename T, typename... Ts> struct max_size { static const size_t value = max(sizeof(T), max_size<Ts...>::value); }; template<typename T> struct max_size<T> { static const size_t value = sizeof(T); }; template<typename... Ts> class Variant { size_t curr_type; char data[max_size<Ts...>::value]; public: Variant(): curr_type(), data() {} template<typename T> Variant(const T& x): curr_type(index_type<T, Ts...>::value) { auto ptr = reinterpret_cast<const char*>(&x); std::copy(ptr, ptr + sizeof(T), this->data); } template<typename T> const T& operator=(const T& x) { this->curr_type = index_type<T, Ts...>::value; auto ptr = reinterpret_cast<const char*>(&x); std::copy(ptr, ptr + sizeof(T), this->data); return x; } template<typename T> bool is() { return this->curr_type == index_type<T, Ts...>::value; } template<typename T> T& as() { if (!this->is<T>()) throw std::runtime_error("Requested type is not contained"); return *reinterpret_cast<T*>(this->data); } template<typename T> bool into(T& x) { if (!this->is<T>()) return false; x = *reinterpret_cast<T*>(this->data); return true; } }; int main() { Variant<short unsigned int, long int [3]> v; v = (long int [3]) {10, -123, 345}; if (v.is<long int [3]>()) { std::cout << v.as<long int [3]>()[0] << std::endl; } }