#pragma once #include #include #include #include #include #include #include namespace ztl{ template void logger(Ts&&...v){ #ifndef NDEBUG std::cout<<"log["; (std::cout<<...< std::string get_type_detail(){ return __PRETTY_FUNCTION__; } template std::string get_T_name(){ std::string type_detail = get_type_detail(); // logger(type_detail); size_t start = type_detail.find("T = "); if(start == std::string::npos) { throw std::runtime_error("Failed to get type name"); } size_t end = type_detail.find(';', start); if(end == std::string::npos) { end = type_detail.size()-1; } // logger(type_detail.substr(start + 4, end - start - 4)); return type_detail.substr(start + 4, end - start - 4); } template struct overloaded:Ts...{using Ts::operator()...;}; template overloaded(Ts...)->overloaded; template auto match(std::variant& v, Fs&&... func) { return std::visit(ztl::overloaded{std::forward(func)...}, v); } template auto match(const std::variant& v, Fs&&... func) { return std::visit(ztl::overloaded{std::forward(func)...}, v); } template auto match(std::variant&& v, Fs&&... func) { return std::visit(ztl::overloaded{std::forward(func)...}, std::move(v)); } struct Err:std::string{}; // template // struct Ok{ // T data; // }; template struct Result:std::variant{ T unwrap(){ return match(*this,[](const T&t){ return t; },[](const Err &e){ throw std::runtime_error(e); T t; return t; }); } }; }