diff options
Diffstat (limited to 'c++/codec-netcdf/netcdf.tmpl.h')
-rw-r--r-- | c++/codec-netcdf/netcdf.tmpl.h | 156 |
1 files changed, 139 insertions, 17 deletions
diff --git a/c++/codec-netcdf/netcdf.tmpl.h b/c++/codec-netcdf/netcdf.tmpl.h index f3b36b8..00bfbf4 100644 --- a/c++/codec-netcdf/netcdf.tmpl.h +++ b/c++/codec-netcdf/netcdf.tmpl.h @@ -48,6 +48,125 @@ struct netcdf_is_group<schema::Struct<schema::Member<T,Lits>...>> { }; template<typename Schema, typename ToEncode> +struct netcdf_encode; + +template<typename T, size_t N, typename ToEncode> +struct netcdf_encode<schema::Primitive<T,N>, ToEncode> { + using Schema = schema::Primitive<T,N>; + + static error_or<void> encode(const data<Schema, ToEncode>& from, int ncid, int ncvarid){ + int rc{}; + + typename native_data_type<Schema>::type val = from.get(); + + rc = nc_put_var(ncid, ncvarid, &val); + if(rc != NC_NOERR) { + return make_error<err::critical>(); + } + + return void_t{}; + } + + static error_or<void> encode_meta(const data<Schema, ToEncode>& from, int ncid, int ncvarid){ + (void) from; + (void) ncid; + (void) ncvarid; + return void_t{}; + } +}; + +template<typename... T, string_literal... Lits, typename ToEncode> +struct netcdf_encode<schema::Struct<schema::Member<T,Lits>...>, ToEncode> { + using Schema = schema::Struct<schema::Member<T,Lits>...>; + + template<std::size_t i> + static error_or<void> encode_member(const data<Schema, ToEncode>& from, int ncid){ + using Type = typename parameter_pack_type<i,T...>::type; + constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group<Type>::value){ + return make_error<err::not_implemented>(); + }else{ + int nc_varid{}; + int rc {}; + rc = nc_inq_varid(ncid, Literal.data.data(), &nc_varid); + if(rc != NC_NOERR) { + return make_error<err::critical>(); + } + auto eov = netcdf_encode<Type, ToEncode>::encode(from.template get<Literal>(), ncid, nc_varid); + if(eov.is_error()){ + return eov; + } + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = encode_member<i+1>(from, ncid); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + static error_or<void> encode(const data<Schema, ToEncode>& from, int ncid){ + if constexpr (sizeof...(T) > 0){ + auto eov = encode_member<0>(from, ncid); + return eov; + } + + return void_t{}; + } + + template<std::size_t i> + static error_or<void> encode_meta_member(const data<Schema, ToEncode>& from, int ncid){ + using Type = typename parameter_pack_type<i,T...>::type; + constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group<Type>::value){ + return make_error<err::not_implemented>(); + }else{ + int nc_varid{}; + int rc {}; + rc = nc_def_var(ncid, Literal.data.data(), netcdf_primitive_id<Type>::value, 0, nullptr, &nc_varid); + if(rc != NC_NOERR) { + return make_error<err::critical>(); + } + auto eov = netcdf_encode<Type, ToEncode>::encode_meta(from.template get<Literal>(), ncid, nc_varid); + if(eov.is_error()){ + return eov; + } + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = encode_meta_member<i+1>(from, ncid); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + static error_or<void> encode_meta(const data<Schema, ToEncode>& from, int ncid){ + if constexpr (sizeof...(T) > 0){ + auto eov = encode_meta_member<0>(from, ncid); + return eov; + } + + return void_t{}; + } +}; + +template<typename Schema, typename ToDecode> struct netcdf_decode; template<typename T, size_t N, typename ToDecode> @@ -160,24 +279,27 @@ struct netcdf_decode<schema::Struct<schema::Member<T,Lits>...>, ToDecode> { * We have to ask for the internal id of the netcdf structure */ if constexpr (netcdf_is_group<Type>::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<err::critical>(); - } - auto eov = netcdf_decode<Type, ToDecode>::decode(to.template get<Literal>(), nc_group_id); - if(eov.is_error()){ - return eov; - } + int nc_group_id{}; + int rc {}; + rc = nc_inq_ncid(from, Literal.data.data(), &nc_group_id); + if(rc != NC_NOERR) { + return make_error<err::critical>(); + } + auto eov = netcdf_decode<Type, ToDecode>::decode(to.template get<Literal>(), 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<err::critical>(); - } - auto eov = netcdf_decode<Type, ToDecode>::decode(to.template get<Literal>(), from, nc_varid); + int nc_varid{}; + int rc {}; + rc = nc_inq_varid(from, Literal.data.data(), &nc_varid); + if(rc != NC_NOERR) { + return make_error<err::critical>(); + } + auto eov = netcdf_decode<Type, ToDecode>::decode(to.template get<Literal>(), from, nc_varid); + if(eov.is_error()){ + return eov; + } } } |