1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
#pragma once
namespace saw {
namespace impl {
template<typename Schema>
struct netcdf_is_group {
static constexpr bool value = false;
};
template<typename... T, string_literal... Lits>
struct netcdf_is_group<schema::Struct<schema::Member<T,Lits>...>> {
static constexpr bool value = true;
};
template<typename Schema, typename RootSchema, typename ToEncode>
struct netcdf_decode;
template<typename RootSchema, typename ToDecode>
struct netcdf_decode<schema::Int32, RootSchema, ToDecode> {
using Schema = schema::Int32;
static error_or<void> decode(data<Schema, ToDecode>& to, int from, int nc_varid){
int rc{};
nc_type nc_vartype{};
int nc_dimnum{};
std::array<int,NC_MAX_VAR_DIMS> 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<err::critical>();
}
if(nc_vartype != NC_INT){
return make_error<err::critical>();
}
if(nc_dimnum != 0){
return make_error<err::critical>();
}
int32_t val{};
rc = nc_get_var_int(from, nc_varid, &val);
if(rc != NC_NOERR){
return make_error<err::critical>();
}
to.set(val);
return void_t {};
}
};
template<typename... T, string_literal... Lits, typename RootSchema, typename ToDecode>
struct netcdf_decode<schema::Struct<schema::Member<T,Lits>...>, RootSchema, ToDecode> {
using Schema = schema::Struct<schema::Member<T,Lits>...>;
template<std::size_t i>
static error_or<void> decode_member(data<Schema,ToDecode>& to, int from){
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){
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, RootSchema, 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, RootSchema, ToDecode>::decode(to.template get<Literal>(), from, nc_varid);
}
}
if constexpr ((i+1) < sizeof...(T)){
auto eov = decode_member<i+1>(from, to, ncid);
if(eov.is_error()){
return eov;
}
}
return void_t{};
}
static error_or<void> decode(data<Schema, ToDecode>& to, int from){
if constexpr (sizeof...(T) > 0){
auto eov = decode_member<0>(to, from);
return eov;
}
return void_t{};
}
};
}
}
|