You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

122 lines
3.6 KiB

#include "MString.h"
#include <variant>
#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<Vartype vt_> struct VartypeCarrier
{
static const Vartype vt = vt_;
};
using VartypeUnion =
std::variant<VartypeCarrier<Vartype::NONE>, VartypeCarrier<Vartype::U>, VartypeCarrier<Vartype::V>, VartypeCarrier<Vartype::TEMP>, VartypeCarrier<Vartype::SAL>,
VartypeCarrier<Vartype::CHL>, VartypeCarrier<Vartype::MLD>, VartypeCarrier<Vartype::SSH>, VartypeCarrier<Vartype::W>>;
template<class T, Vartype vt>
concept HasVar = requires(T t) {
{
t.template Read<vt>(0)(0, 0)
} -> std::convertible_to<real>;
{
t.template Read<vt>(std::vector<size_t>())(0, 0)
} -> std::convertible_to<real>;
};
} // namespace vartype
template<class DT, vartype::Vartype vt> static constexpr bool isDataSupported = vartype::HasVar<DT, vt>;
class VarType: public vartype::VartypeUnion
{
auto VT() const
{
return std::visit(
[](auto v) -> auto{ return decltype(v)::vt; }, *this);
}
public:
template<vartype::Vartype vt> VarType(vartype::VartypeCarrier<vt>&& vc): vartype::VartypeUnion(std::move(vc)) {}
VarType(MString str)
{
str.ToLower();
if(str == "u") *this = vartype::VartypeCarrier<vartype::Vartype::U>();
if(str == "v") *this = vartype::VartypeCarrier<vartype::Vartype::V>();
if(str == "t" || str == "temp" || str == "temperature") *this = vartype::VartypeCarrier<vartype::Vartype::TEMP>();
if(str == "s" || str == "sal" || str == "salinity") *this = vartype::VartypeCarrier<vartype::Vartype::SAL>();
if(str == "c" || str == "chl" || str == "chlorophyll") *this = vartype::VartypeCarrier<vartype::Vartype::CHL>();
if(str == "mld") *this = vartype::VartypeCarrier<vartype::Vartype::MLD>();
if(str == "ssh") *this = vartype::VartypeCarrier<vartype::Vartype::SSH>();
if(str == "w") *this = vartype::VartypeCarrier<vartype::Vartype::W>();
}
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";
}
MString ShortName() 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 "temp";
case(vartype::Vartype::SAL): return "sal";
case(vartype::Vartype::CHL): return "chl";
case(vartype::Vartype::MLD): return "mld";
case(vartype::Vartype::SSH): return "ssh";
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(); }
auto operator<=>(const VarType& vt) const { return VT() <=> vt.VT(); }
template<class Data> bool isSupported() const
{
return std::visit(
[](const auto v) -> bool
{
if constexpr(isDataSupported<Data, decltype(v)::vt>)
return true;
else
return false;
},
*this);
}
};
#endif