TudorLang/include/Tools.hpp
2025-07-12 10:56:58 +08:00

81 lines
2.1 KiB
C++

#pragma once
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <string>
#include <utility>
#include <variant>
#include <vector>
namespace ztl{
template<class ...Ts>
void logger(Ts&&...v){
#ifndef NDEBUG
std::cout<<"log[";
(std::cout<<...<<v);
std::cout<<"]\n";
#endif
}
template<class T>
std::string get_type_detail(){
return __PRETTY_FUNCTION__;
}
template<class T>
std::string get_T_name(){
std::string type_detail = get_type_detail<T>();
// 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<class ...Ts>
struct overloaded:Ts...{using Ts::operator()...;};
template<class ...Ts>
overloaded(Ts...)->overloaded<Ts...>;
template<class ...Ts, class ...Fs>
auto match(std::variant<Ts...>& v, Fs&&... func) {
return std::visit(ztl::overloaded{std::forward<Fs>(func)...}, v);
}
template<class ...Ts, class ...Fs>
auto match(const std::variant<Ts...>& v, Fs&&... func) {
return std::visit(ztl::overloaded{std::forward<Fs>(func)...}, v);
}
template<class ...Ts, class ...Fs>
auto match(std::variant<Ts...>&& v, Fs&&... func) {
return std::visit(ztl::overloaded{std::forward<Fs>(func)...}, std::move(v));
}
struct Err:std::string{};
// template<class T>
// struct Ok{
// T data;
// };
template<class T>
struct Result:std::variant<T,Err>{
T unwrap(){
return match<T>(*this,[](const T&t){
return t;
},[](const Err &e){
throw std::runtime_error(e);
T t;
return t;
});
}
};
}