From 967be9e750221ab2ab783f95df79bb26d290a45e Mon Sep 17 00:00:00 2001 From: Martial Simon Date: Mon, 15 Sep 2025 01:07:58 +0200 Subject: add: added projects --- tiger-compiler/lib/misc/variant.hh | 111 +++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 tiger-compiler/lib/misc/variant.hh (limited to 'tiger-compiler/lib/misc/variant.hh') diff --git a/tiger-compiler/lib/misc/variant.hh b/tiger-compiler/lib/misc/variant.hh new file mode 100644 index 0000000..71a8c1a --- /dev/null +++ b/tiger-compiler/lib/misc/variant.hh @@ -0,0 +1,111 @@ +/** + ** \file misc/variant.hh + ** \brief Interface of misc::variant. + ** + ** misc::variant is a wrapper over std::variant that adds + ** conversion operators to the original standard variant class. + ** misc::variant is used just like std::variant, and you + ** won't be disturbed when using it. + **/ + +#pragma once + +#include + +namespace misc +{ + // Defining some concepts sepecific to variants: + + // Type T can be converted into another type in Ts, + // used to set the variant's value. + template + concept ContainsTypeSet = + std::disjunction...>::value; + + // A type in Ts can be converted into T, used to get the variant's value. + template + concept ContainsTypeGet = + std::disjunction...>::value; + + /// Type V is a visitor on each Ts. + template + concept Visits = std::conjunction...>::value; + + /// A wrapper over std::variant supporting conversion operators. + /// + /// Constraints: + /// - No type may be const-qualified. + /// - Each type must be unique. + /// - The first type must be default constructible. + /// + /// Proper declaration form: + /// misc::variant + + template + class variant : public std::variant + { + public: + /// The type of this variant. + using self_type = variant; + /// Super type. + + using super_type = std::variant; + + /// Constructors. + /// \{ + variant() = default; + + template + requires ContainsTypeSet + variant(const U& rhs); + /// \} + + template + requires ContainsTypeSet + self_type& operator=(const U&); + + /// \brief Convert this variant to a value of type \a U. + /// + /// This conversion relies on std::get. In particular, if the + /// conversion fails, a std::bad_variant_access exception is thrown. + template + requires ContainsTypeGet + operator U&(); + + /// Likewise, const version. + template + requires ContainsTypeGet + operator const U&() const; + + /** \brief Visit variants of this class. + ** std::visit does not handle classes inheriting from std::variant, hence + ** these wrappers. + ** \{ */ + template + requires Visits + auto visit(V&& visitor) const; + + template + static auto visit(V&& visitor, Variants&&... vars); + /** \} */ + }; + + // Here add variadic template recursion on std::get + template + std::ostream& operator<<(std::ostream& os, const variant& obj); + + class PrintVisitor + { + public: + PrintVisitor(std::ostream& os) + : os_(os) + {} + + template std::ostream& operator()(const T& value) const; + + private: + std::ostream& os_; + }; +} // namespace misc + +#include -- cgit v1.2.3