#pragma once #include #include #include namespace jvalidate::detail { template class out; constexpr struct discard_out_t { } discard_out; template class out { private: T * ref_ = nullptr; public: out() = default; out(discard_out_t) {} out(T & ref) : ref_(&ref) {} explicit operator bool() const { return ref_; } template requires std::is_constructible_v void operator=(U && val) { if (ref_) { *ref_ = std::forward(val); } return *this; } }; template requires(std::is_same_v>) class inout { private: std::variant ref_; public: inout(T && value) : ref_(std::move(value)) {} inout(T & ref) : ref_(&ref) {} operator T const &() const { struct { T const & operator()(T const & in) const { return in; } T const & operator()(T * in) const { return *in; } } visitor; return std::visit(visitor, ref_); } template requires std::is_constructible_v T const & operator=(U && val) { struct { U && val; void operator()(T & in) const { in = std::forward(val); } void operator()(T * in) const { *in = std::forward(val); } } visitor{std::forward(val)}; std::visit(visitor, ref_); return static_cast(*this); } }; }