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
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
|