diff --git a/CMakeLists.txt b/CMakeLists.txt
index 98bc98e..4c4cd13 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake)
-set(BLT_VERSION 5.3.7)
+set(BLT_VERSION 5.3.8)
set(BLT_TARGET BLT)
diff --git a/include/blt/std/variant.h b/include/blt/std/variant.h
new file mode 100644
index 0000000..4676c35
--- /dev/null
+++ b/include/blt/std/variant.h
@@ -0,0 +1,287 @@
+#pragma once
+/*
+ * Copyright (C) 2024 Brett Terpstra
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef BLT_STD_VARIANT_H
+#define BLT_STD_VARIANT_H
+
+#include
+#include
+#include
+
+namespace blt
+{
+ template
+ class variant_t
+ {
+ public:
+ using value_type = std::variant;
+ size_t variant_size = sizeof...(Types);
+
+ constexpr variant_t(): m_variant()
+ {
+ }
+
+ constexpr variant_t(const variant_t& variant) noexcept(std::is_nothrow_copy_constructible_v): m_variant(variant.m_variant)
+ {
+ }
+
+ constexpr variant_t(variant_t&& variant) noexcept(std::is_nothrow_move_constructible_v): m_variant(std::move(variant.m_variant))
+ {
+ }
+
+ explicit constexpr variant_t(const value_type& variant) noexcept(std::is_nothrow_copy_constructible_v): m_variant(variant)
+ {
+ }
+
+ explicit constexpr variant_t(value_type&& variant) noexcept(std::is_nothrow_move_constructible_v): m_variant(std::move(variant))
+ {
+ }
+
+ explicit constexpr variant_t(Types&&... args) noexcept(std::is_nothrow_constructible_v): m_variant(
+ std::forward(args)...)
+ {
+ }
+
+ template
+ explicit constexpr variant_t(std::in_place_type_t, C_Args&&... args): m_variant(std::in_place_type, std::forward(args)...)
+ {
+ }
+
+ template
+ constexpr explicit variant_t(std::in_place_type_t, std::initializer_list il, C_Args&&... args): m_variant(
+ std::in_place_type, il, std::forward(args)...)
+ {
+ }
+
+ template
+ explicit constexpr variant_t(std::in_place_index_t, C_Args&&... args): m_variant(std::in_place_index, std::forward(args)...)
+ {
+ }
+
+ template
+ constexpr explicit variant_t(std::in_place_index_t, std::initializer_list il, C_Args&&... args): m_variant(
+ std::in_place_index, il, std::forward(args)...)
+ {
+ }
+
+ template
+ T& emplace(Args&&... args)
+ {
+ return m_variant.template emplace(std::forward(args)...);
+ }
+
+ template
+ T& emplace(std::initializer_list il, Args&&... args)
+ {
+ return m_variant.template emplace(il, std::forward(args)...);
+ }
+
+ template
+ std::variant_alternative_t& emplace(Args&&... args)
+ {
+ return m_variant.template emplace(std::forward(args)...);
+ }
+
+ template
+ std::variant_alternative_t& emplace(std::initializer_list il, Args&&... args)
+ {
+ return m_variant.template emplace(il, std::forward(args)...);
+ }
+
+ [[nodiscard]] constexpr std::size_t index() const noexcept
+ {
+ return m_variant.index();
+ }
+
+ [[nodiscard]] constexpr bool valueless_by_exception() const noexcept
+ {
+ return m_variant.valueless_by_exception();
+ }
+
+ template
+ constexpr auto visit(T&& visitor) -> decltype(auto)
+ {
+ return std::visit(std::forward(visitor), m_variant);
+ }
+
+ template
+ [[nodiscard]] constexpr bool has_index() const noexcept
+ {
+ return m_variant.index() == I;
+ }
+
+ template
+ [[nodiscard]] constexpr bool has_type() const noexcept
+ {
+ return std::holds_alternative(m_variant);
+ }
+
+ template
+ [[nodiscard]] constexpr auto get() -> decltype(auto)
+ {
+ return std::get(m_variant);
+ }
+
+ template
+ [[nodiscard]] constexpr auto get() const -> decltype(auto)
+ {
+ return std::get(m_variant);
+ }
+
+ template
+ [[nodiscard]] constexpr auto get() -> decltype(auto)
+ {
+ return std::get(m_variant);
+ }
+
+ template
+ [[nodiscard]] constexpr auto get() const -> decltype(auto)
+ {
+ return std::get(m_variant);
+ }
+
+ template
+ constexpr std::add_pointer_t> get_if() noexcept
+ {
+ return std::get_if(m_variant);
+ }
+
+ template
+ constexpr std::add_pointer_t> get_if() noexcept
+ {
+ return std::get_if(m_variant);
+ }
+
+ template
+ constexpr std::add_pointer_t get_if() noexcept
+ {
+ return std::get_if(m_variant);
+ }
+
+ template
+ constexpr std::add_pointer_t get_if() noexcept
+ {
+ return std::get_if(m_variant);
+ }
+
+ template
+ constexpr T value_or(T&& t) const
+ {
+ if (has_type())
+ return get();
+ return std::forward(t);
+ }
+
+ template
+ constexpr std::variant_alternative_t value_or(const std::variant_alternative_t& t) const
+ {
+ if (has_type>())
+ return get();
+ return t;
+ }
+
+ template
+ constexpr std::variant_alternative_t value_or(std::variant_alternative_t&& t) const
+ {
+ if (has_type>())
+ return get();
+ return t;
+ }
+
+ template
+ constexpr const value_type& variant() const
+ {
+ return m_variant;
+ }
+
+ constexpr value_type& variant()
+ {
+ return m_variant;
+ }
+
+ [[nodiscard]] constexpr size_t size() const
+ {
+ return variant_size;
+ }
+
+ friend bool operator==(const variant_t& lhs, const variant_t& rhs)
+ {
+ return lhs.m_variant == rhs.m_variant;
+ }
+
+ friend bool operator!=(const variant_t& lhs, const variant_t& rhs)
+ {
+ return lhs.m_variant != rhs.m_variant;
+ }
+
+ friend bool operator<(const variant_t& lhs, const variant_t& rhs)
+ {
+ return lhs.m_variant < rhs.m_variant;
+ }
+
+ friend bool operator>(const variant_t& lhs, const variant_t& rhs)
+ {
+ return lhs.m_variant > rhs.m_variant;
+ }
+
+ friend bool operator<=(const variant_t& lhs, const variant_t& rhs)
+ {
+ return lhs.m_variant <= rhs.m_variant;
+ }
+
+ friend bool operator>=(const variant_t& lhs, const variant_t& rhs)
+ {
+ return lhs.m_variant >= rhs.m_variant;
+ }
+
+ private:
+ value_type m_variant;
+ };
+
+ namespace detail
+ {
+ template
+ class variant_is_base_of
+ {};
+
+ template
+ class variant_is_base_of>
+ {
+ public:
+ template
+ static constexpr bool value = std::conjunction_v...>;
+ };
+
+ template
+ class variant_is_base_of>
+ {
+ public:
+ template
+ static constexpr bool value = std::conjunction_v...>;
+ };
+
+ template
+ static constexpr bool variant_is_base_of_v = variant_is_base_of::value;
+ }
+
+ template
+ class variant_wrapper_t : public Subclasses...
+ {};
+}
+
+#endif //BLT_STD_VARIANT_H