#pragma once #include "nczarrmulti.h" #include using NCZarrBase = std::variant; #define DEFFUNC(NAME) \ auto NAME() const \ { \ return V([](const auto& arg) { return arg.NAME(); }); \ } #define DEFFUNC1(NAME) \ auto NAME(const MString& v) const \ { \ return V([&v = std::as_const(v)](const auto& arg) { return arg.NAME(v); }); \ } #define DEFFUNC2(NAME) \ auto NAME(const MString& v1, const MString& v2) const \ { \ return V([&v1 = std::as_const(v1), &v2 = std::as_const(v2)](const auto& arg) { return arg.NAME(v1, v2); }); \ } class NCZarr: private NCZarrBase, private DimReqDef { template auto V(Visitor&& visitor) const { return std::visit(std::forward(visitor), *static_cast(this)); } public: explicit operator bool() const { return V([](const auto& arg) { return static_cast(arg); }); } DEFFUNC1(NDim) DEFFUNC(NAtt) DEFFUNC1(NAtt) DEFFUNC(AttNames) DEFFUNC1(AttNames) DEFFUNC(VarNames) DEFFUNC1(VarT) DEFFUNC1(VarFill) DEFFUNC1(DimNames) DEFFUNC2(DimSize) DEFFUNC2(AttT) DEFFUNC2(AttInt) DEFFUNC2(AttUInt) DEFFUNC2(AttReal) DEFFUNC2(AttString) DEFFUNC2(AttBool) DEFFUNC1(AttT) DEFFUNC1(AttInt) DEFFUNC1(AttUInt) DEFFUNC1(AttReal) DEFFUNC1(AttString) DEFFUNC1(AttBool) DEFFUNC2(HasDim) DEFFUNC1(HasVar) DEFFUNC1(HasAtt) DEFFUNC2(HasAtt) template Error Read(const MString& vname, Data& data, Transform transform, const char* request) const { return V([&vname = std::as_const(vname), &data = data, &transform = transform, request = request](const auto& arg) { return arg.Read(vname, data, transform, request); }); } template Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1) const { return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1](const auto& arg) { return arg.Read(vname, data, transform, std::move(req1)); }); } template Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2) const { return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1, &req2 = req2](const auto& arg) { return arg.Read(vname, data, transform, std::move(req1), std::move(req2)); }); } template Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3) const { return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1, &req2 = req2, &req3 = req3](const auto& arg) { return arg.Read(vname, data, transform, std::move(req1), std::move(req2), std::move(req3)); }); } template Error Read(const MString& vname, Data& data, Transform transform, DimReq&& req1, DimReq&& req2, DimReq&& req3, DimReq&& req4) const { return V([&vname = std::as_const(vname), &data = data, &transform = transform, &req1 = req1, &req2 = req2, &req3 = req3, &req4 = req4](const auto& arg) { return arg.Read(vname, data, transform, std::move(req1), std::move(req2), std::move(req3), std::move(req4)); }); } template Error Read(const MString& vname, Data& data, Transform transform) const { return V([&vname = std::as_const(vname), &data = data, &transform = transform](const auto& arg) { return arg.Read(vname, data, transform); }); } template Error Read(const MString& vname, Data& data, Transform transform, const std::vector& reqs) const { return V([&vname = std::as_const(vname), &data = data, &transform = transform, &reqs = std::as_const(reqs)](const auto& arg) { return arg.Read(vname, data, transform, reqs); }); } template Error Read(const MString& vname, Data& data, Transform transform, const MString& request) const { return V([&vname = std::as_const(vname), &data = data, &transform = transform, &request = std::as_const(request)](const auto& arg) { return arg.Read(vname, data, transform, request); }); } template Error Read(const MString& vname, std::vector& out) const { return V([&vname = std::as_const(vname), &out = out](const auto& arg) { return arg.Read(vname, out); }); } Error OpenNC(const MString& filename) { auto pv = static_cast(this); *pv = NCZarrBase(NCSimple()); auto p = std::get_if(pv); if(p == nullptr) return Error("NCZarr::OpenNC", "Impossible error!"); return p->Open(filename); } Error OpenZarr(const MString& product, const MString& dataset, bool time = true) { auto pv = static_cast(this); *pv = NCZarrBase(Zarr()); auto p = std::get_if(pv); if(p == nullptr) return Error("NCZarr::OpenNC", "Impossible error!"); return p->Open(product, dataset, time); } Error OpenMultiNC(const std::vector& names) { if(names.size() == 0) return Error("NCZarr::OpenMultiNC", "no names"); if(names.size() == 1) return OpenNC(names[0]); auto pv = static_cast(this); *pv = NCZarrBase(NCMulti()); auto p = std::get_if(pv); if(p == nullptr) return Error("NCZarr::OpenMultiNC", "Impossible error!"); return p->Open(names); } Error OpenMultiZarr(const MString& product, const std::vector& dsets, bool time = true) { if(dsets.size() == 0) return Error("NCZarr::OpenMultiZarr", "no datasets"); if(dsets.size() == 1) return OpenZarr(product, dsets[0], time); auto pv = static_cast(this); *pv = NCZarrBase(ZarrMulti()); auto p = std::get_if(pv); if(p == nullptr) return Error("NCZarr::OpenMultiZarr", "Impossible error!"); return p->Open(product, dsets, time); } }; #undef DEFFUNC #undef DEFFUNC1 #undef DEFFUNC2