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.

97 lines
2.6 KiB

2 years ago
#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
};
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>>;
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>();
}
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";
}
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<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