From 8dad985328e2183b224300aa992951131956fdb3 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Tue, 23 Jan 2024 13:12:11 +0100 Subject: core,codec-json,codec-minecraft,codec-netcdf,codec,io-tls,io,io_codec,window,window-opengl: Renamed file endings and changed includes --- modules/codec-netcdf/c++/netcdf.tmpl.hpp | 348 +++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 modules/codec-netcdf/c++/netcdf.tmpl.hpp (limited to 'modules/codec-netcdf/c++/netcdf.tmpl.hpp') diff --git a/modules/codec-netcdf/c++/netcdf.tmpl.hpp b/modules/codec-netcdf/c++/netcdf.tmpl.hpp new file mode 100644 index 0000000..bf257e4 --- /dev/null +++ b/modules/codec-netcdf/c++/netcdf.tmpl.hpp @@ -0,0 +1,348 @@ +#pragma once + +namespace saw { +namespace impl { +template +struct netcdf_primitive_id { + static_assert(always_false, "Not a primitive id"); +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_INT; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_UINT; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_INT64; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_UINT64; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_FLOAT; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_DOUBLE; +}; + +template +struct netcdf_is_group { + static constexpr bool value = false; +}; + +template +struct netcdf_is_group...>> { + static constexpr bool value = true; +}; + +template +struct netcdf_encode; + +template +struct netcdf_encode, ToEncode> { + using Schema = schema::Primitive; + + static error_or encode(const data& from, int ncid, int ncvarid){ + int rc{}; + + typename native_data_type::type val = from.get(); + + rc = nc_put_var(ncid, ncvarid, &val); + if(rc != NC_NOERR) { + return make_error(); + } + + return void_t{}; + } + + static error_or encode_meta(const data& from, int ncid, int ncvarid){ + (void) from; + (void) ncid; + (void) ncvarid; + return void_t{}; + } +}; + +template +struct netcdf_encode, ToEncode> { + using Schema = schema::Array; + + template + static error_or encode_level(data& from, int ncid, int ncvarid){ + + return make_error(); + } + + static error_or encode(data& from, int ncid, int ncvarid){ + + return make_error(); + } + + static error_or encode_meta(const data& from, int ncid, int ncvarid){ + + return make_error(); + } +}; + +template +struct netcdf_encode...>, ToEncode> { + using Schema = schema::Struct...>; + + template + static error_or encode_member(const data& from, int ncid){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group::value){ + return make_error(); + }else{ + int nc_varid{}; + int rc {}; + rc = nc_inq_varid(ncid, Literal.data.data(), &nc_varid); + if(rc != NC_NOERR) { + return make_error(); + } + auto eov = netcdf_encode::encode(from.template get(), ncid, nc_varid); + if(eov.is_error()){ + return eov; + } + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = encode_member(from, ncid); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + static error_or encode(const data& from, int ncid){ + if constexpr (sizeof...(T) > 0){ + auto eov = encode_member<0>(from, ncid); + return eov; + } + + return void_t{}; + } + + template + static error_or encode_meta_member(const data& from, int ncid){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group::value){ + return make_error(); + }else{ + int nc_varid{}; + int rc {}; + rc = nc_def_var(ncid, Literal.data.data(), netcdf_primitive_id::value, 0, nullptr, &nc_varid); + if(rc != NC_NOERR) { + return make_error(); + } + auto eov = netcdf_encode::encode_meta(from.template get(), ncid, nc_varid); + if(eov.is_error()){ + return eov; + } + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = encode_meta_member(from, ncid); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + static error_or encode_meta(const data& from, int ncid){ + if constexpr (sizeof...(T) > 0){ + auto eov = encode_meta_member<0>(from, ncid); + return eov; + } + + return void_t{}; + } +}; + +template +struct netcdf_decode; + +template +struct netcdf_decode, ToDecode> { + using Schema = schema::Primitive; + + static error_or decode(data& to, int from, int nc_varid){ + int rc{}; + + nc_type nc_vartype{}; + int nc_dimnum{}; + std::array nc_dimids; + + rc = nc_inq_var(from, nc_varid, nullptr, &nc_vartype, &nc_dimnum, &nc_dimids[0], nullptr); + if(rc != NC_NOERR){ + return make_error(); + } + if(nc_vartype != netcdf_primitive_id>::value){ + return make_error(); + } + if(nc_dimnum != 0){ + return make_error(); + } + + typename native_data_type>::type val{}; + rc = nc_get_var(from, nc_varid, &val); + if(rc != NC_NOERR){ + return make_error(); + } + + to.set(val); + + return void_t {}; + } +}; + +template +struct netcdf_decode, ToDecode> { + using Schema = schema::Array; + + template + static error_or decode_level(data& to, int from, int nc_varid, std::array& index, const std::array& count){ + if constexpr ( Level == Dim ){ + int rc{}; + typename native_data_type::type val; + rc = nc_get_vara(from, nc_varid, index.data(), count.data(), &val); + if(rc != NC_NOERR){ + return make_error(); + } + to.at(index).set(val); + }else{ + const std::size_t dim_size = to.get_dim_size(Level); + for(index[Level] = 0; index[Level] < dim_size; ++index[Level]){ + auto eov = decode_level(to, from, nc_varid, index, count); + if(eov.is_error()){ + return eov; + } + } + } + + return void_t{}; + } + + static error_or decode(data& to, int from, int nc_varid){ + int rc{}; + + nc_type nc_vartype{}; + + int nc_dimnum{}; + std::array nc_dimids; + + rc = nc_inq_var(from, nc_varid, nullptr, &nc_vartype, &nc_dimnum, &nc_dimids[0], nullptr); + if(rc != NC_NOERR){ + return make_error(); + } + if(nc_vartype != netcdf_primitive_id::value){ + return make_error(); + } + if(nc_dimnum != Dim){ + return make_error(); + } + + std::array dims; + std::array count; + for(std::size_t i = 0; i < Dim; ++i){ + rc = nc_inq_dim(from, nc_dimids[i], nullptr, &dims[i]); + if(rc != NC_NOERR){ + return make_error(); + } + count[i] = 1; + } + + to = {dims}; + std::array index; + + return decode_level<0>(to, from, nc_varid, index, count); + } +}; + +template +struct netcdf_decode...>, ToDecode> { + using Schema = schema::Struct...>; + + template + static error_or decode_member(data& to, int from){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group::value){ + int nc_group_id{}; + int rc {}; + rc = nc_inq_ncid(from, Literal.data.data(), &nc_group_id); + if(rc != NC_NOERR) { + return make_error(); + } + auto eov = netcdf_decode::decode(to.template get(), nc_group_id); + if(eov.is_error()){ + return eov; + } + }else{ + int nc_varid{}; + int rc {}; + rc = nc_inq_varid(from, Literal.data.data(), &nc_varid); + if(rc != NC_NOERR) { + return make_error(); + } + auto eov = netcdf_decode::decode(to.template get(), from, nc_varid); + if(eov.is_error()){ + return eov; + } + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = decode_member(to, from); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + + static error_or decode(data& to, int from){ + if constexpr (sizeof...(T) > 0){ + auto eov = decode_member<0>(to, from); + return eov; + } + + return void_t{}; + } +}; +} +} -- cgit v1.2.3