diff --git a/include/AVISO.h b/include/AVISO.h index ed166c8..ec2f85a 100644 --- a/include/AVISO.h +++ b/include/AVISO.h @@ -15,6 +15,8 @@ class AVISOData: public LayeredData Type type = TYPE_UNKNOWN; public: + static constexpr const char* name = "AVISO"; + AVISOData() = default; MString DataTitle() const diff --git a/include/AVISOLOCAL.h b/include/AVISOLOCAL.h index 31f3c5a..2978b17 100644 --- a/include/AVISOLOCAL.h +++ b/include/AVISOLOCAL.h @@ -25,6 +25,8 @@ class AVISOLOCALData: public NCFuncs }; public: + static constexpr const char* name = "AVISOLOCAL"; + using Data = Simple2DData; AVISOLOCALData() = default; diff --git a/include/BINFILE.h b/include/BINFILE.h index 7dc0c0c..42f145e 100644 --- a/include/BINFILE.h +++ b/include/BINFILE.h @@ -16,6 +16,8 @@ class BINFILEData std::unique_ptr data; public: + static constexpr const char* name = "BINFILE"; + using Data = Simple2DData; BINFILEData() = default; diff --git a/include/HYCOM.h b/include/HYCOM.h index ab6c6fe..87194af 100644 --- a/include/HYCOM.h +++ b/include/HYCOM.h @@ -14,6 +14,8 @@ class HYCOMData: public LayeredData Type type = TYPE_UNKNOWN; public: + static constexpr const char* name = "HYCOM"; + HYCOMData() = default; MString DataTitle() const diff --git a/include/MODISBINLOCAL.h b/include/MODISBINLOCAL.h index a84bdb2..04e5590 100644 --- a/include/MODISBINLOCAL.h +++ b/include/MODISBINLOCAL.h @@ -1,21 +1,21 @@ #pragma once +#include "DataAdapters/ncfilealt.h" #include "ParseArgs.h" #include "basedata.h" #include "mdatetime.h" #include "mregex.h" -#include "DataAdapters/ncfilealt.h" #include #include #include +using michlib::Ceil; +using michlib::Floor; using michlib::GPL; using michlib::MDateTime; +using michlib::pointer_cast; using michlib::RegExp; using michlib::uint2; using michlib::uint4; -using michlib::Floor; -using michlib::Ceil; -using michlib::pointer_cast; class MODISBINLOCALData { @@ -32,6 +32,8 @@ class MODISBINLOCALData }; public: + static constexpr const char* name = "MODISBINLOCAL"; + using Data = UngriddedData; MString Info() const; diff --git a/include/NEMO.h b/include/NEMO.h index 5f94c51..fa30761 100644 --- a/include/NEMO.h +++ b/include/NEMO.h @@ -14,6 +14,8 @@ class NEMOData: public LayeredData Type type = TYPE_UNKNOWN; public: + static constexpr const char* name = "NEMO"; + NEMOData() = default; MString DataTitle() const diff --git a/include/NEMOBIO.h b/include/NEMOBIO.h index 37d1e72..53573aa 100644 --- a/include/NEMOBIO.h +++ b/include/NEMOBIO.h @@ -13,6 +13,8 @@ class NEMOBIOData: public LayeredData Type type = TYPE_UNKNOWN; public: + static constexpr const char* name = "NEMOBIO"; + NEMOBIOData() = default; MString DataTitle() const diff --git a/include/actions.h b/include/actions.h index 4829601..cb1fa58 100644 --- a/include/actions.h +++ b/include/actions.h @@ -3,7 +3,7 @@ #include "mdatetime.h" #include "mregex.h" #include "uvdata.h" -#include +#include "varhelpers.h" using michlib::BFileW; using michlib::MDateTime; @@ -18,7 +18,26 @@ enum class ActionID GENINTFILE }; -template struct ActionCarrier +template struct ActionName; + +template<> struct ActionName +{ + static constexpr const char* name = "info"; +}; +template<> struct ActionName +{ + static constexpr const char* name = "tsc"; +}; +template<> struct ActionName +{ + static constexpr const char* name = "uv"; +}; +template<> struct ActionName +{ + static constexpr const char* name = "genintfile"; +}; + +template struct ActionCarrier: public ActionName { constexpr static ActionID action = id; }; @@ -57,16 +76,8 @@ class Action: public ActionVariants MString Init(const CLArgs& args) { MString act = args.contains("action") ? args.at("action") : "info"; - if(act == "info") - *this = ActionVariants(ActionCarrier()); - else if(act == "tsc") - *this = ActionVariants(ActionCarrier()); - else if(act == "uv") - *this = ActionVariants(ActionCarrier()); - else if(act == "genintfile") - *this = ActionVariants(ActionCarrier()); - else - return "Unknown action: " + act; + bool res = internal::InitV(*this, act); + if(!res) return "Unknown action: " + act; return ""; } }; diff --git a/include/data.h b/include/data.h index 2e6d9f2..22acd4b 100644 --- a/include/data.h +++ b/include/data.h @@ -6,7 +6,7 @@ #include "MODISBINLOCAL.h" #include "NEMO.h" #include "NEMOBIO.h" -#include +#include "varhelpers.h" using DataVariants = std::variant; class Data: public DataVariants diff --git a/include/varhelpers.h b/include/varhelpers.h new file mode 100644 index 0000000..dfa46fb --- /dev/null +++ b/include/varhelpers.h @@ -0,0 +1,20 @@ +#pragma once +#include + +namespace internal +{ +template bool InitV1(std::variant& v, const michlib::MString& n) +{ + if(T1::name != n) + { + if constexpr(sizeof...(T) > 0) + return InitV1(v, n); + else + return false; + } + v = T1(); + return true; +} + +template bool InitV(std::variant& v, const michlib::MString& n) { return InitV1(v, n); } +} // namespace internal diff --git a/src/data.cpp b/src/data.cpp index 5a8c799..11bde1f 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -5,56 +5,10 @@ MString Data::Init(const CLArgs& args) { MString src = args.contains("source") ? args.at("source") : ""; if(!src.Exist()) return "No source specified"; - if(src == "NEMO") - { - NEMOData data; - auto res = data.Open(args); - if(res.Exist()) return "Can't open source " + src + ":\n" + res; - *this = Data(std::move(data)); - } - else if(src == "NEMOBIO") - { - NEMOBIOData data; - auto res = data.Open(args); - if(res.Exist()) return "Can't open source " + src + ":\n" + res; - *this = Data(std::move(data)); - } - else if(src == "AVISO") - { - AVISOData data; - auto res = data.Open(args); - if(res.Exist()) return "Can't open source " + src + ":\n" + res; - *this = Data(std::move(data)); - } - else if(src == "AVISOLOCAL") - { - AVISOLOCALData data; - auto res = data.Open(args); - if(res.Exist()) return "Can't open source " + src + ":\n" + res; - *this = Data(std::move(data)); - } - else if(src == "HYCOM") - { - HYCOMData data; - auto res = data.Open(args); - if(res.Exist()) return "Can't open source " + src + ":\n" + res; - *this = Data(std::move(data)); - } - else if(src == "BINFILE") - { - BINFILEData data; - auto res = data.Open(args); - if(res.Exist()) return "Can't open source " + src + ":\n" + res; - *this = Data(std::move(data)); - } - else if(src == "MODISBINLOCAL") - { - MODISBINLOCALData data; - auto res = data.Open(args); - if(res.Exist()) return "Can't open source " + src + ":\n" + res; - *this = Data(std::move(data)); - } - else - return "Unknown source: " + src; + + bool res = internal::InitV(*this, src); + if(!res) return "Unknown source: " + src; + auto resop = std::visit([&args = std::as_const(args)](auto& data) -> auto { return data.Open(args); }, *this); + if(resop.Exist()) return "Can't open source " + src + ":\n" + resop; return ""; }