#include "MString.h" #include #if !defined(M__VARTYPE) #define M__VARTYPE using michlib::MString; namespace vartype { enum class Vartype { NONE, U, V, TEMP, SAL, CHL, MLD, SSH, W }; template struct VartypeCarrier { static const Vartype vt = vt_; }; using VartypeUnion = std::variant, VartypeCarrier, VartypeCarrier, VartypeCarrier, VartypeCarrier, VartypeCarrier, VartypeCarrier, VartypeCarrier, VartypeCarrier>; template concept HasVar = requires(T t) { { t.template Read(0)(0, 0) } -> std::convertible_to; { t.template Read(std::vector())(0, 0) } -> std::convertible_to; }; } // namespace vartype template static constexpr bool isDataSupported = vartype::HasVar; class VarType: public vartype::VartypeUnion { auto VT() const { return std::visit( [](auto v) -> auto{ return decltype(v)::vt; }, *this); } public: template VarType(vartype::VartypeCarrier&& vc): vartype::VartypeUnion(std::move(vc)) {} VarType(MString str) { str.ToLower(); if(str == "u") *this = vartype::VartypeCarrier(); if(str == "v") *this = vartype::VartypeCarrier(); if(str == "t" || str == "temp" || str == "temperature") *this = vartype::VartypeCarrier(); if(str == "s" || str == "sal" || str == "salinity") *this = vartype::VartypeCarrier(); if(str == "c" || str == "chl" || str == "chlorophyll") *this = vartype::VartypeCarrier(); if(str == "mld") *this = vartype::VartypeCarrier(); if(str == "ssh") *this = vartype::VartypeCarrier(); if(str == "w") *this = vartype::VartypeCarrier(); } MString Name() const { switch(VT()) { case(vartype::Vartype::NONE): return "none"; case(vartype::Vartype::U): return "U"; case(vartype::Vartype::V): return "V"; case(vartype::Vartype::TEMP): return "Temperature"; case(vartype::Vartype::SAL): return "Salinity"; case(vartype::Vartype::CHL): return "Chlorophyll"; case(vartype::Vartype::MLD): return "Mixed layer depth"; case(vartype::Vartype::SSH): return "Sea surface height"; case(vartype::Vartype::W): return "W"; } return "none"; } bool Ok() const { return VT() != vartype::Vartype::NONE; } explicit operator bool() const { return Ok(); } bool operator==(const VarType& vt) const { return VT() == vt.VT(); } bool operator!=(const VarType& vt) const { return VT() != vt.VT(); } template bool isSupported() const { return std::visit( [](const auto v) -> bool { if constexpr(isDataSupported) return true; else return false; }, *this); } }; #endif