#pragma once #include #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; }); } }; inline Result get_argv(size_t idx){ if(idx>=__argc){ return Result(Err("argv's index out of range")); }else{ return Result(std::string(__argv[idx])); } } inline Result get_string_from_file(const std::string &file_path){ std::ifstream file(file_path); if (!file) { return Result(Err("Could not open file: " + file_path)); } std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); return Result(content); } }