61 static constexpr nc_type
id = NC_INT64;
65struct Type<unsigned long long> {
66 static constexpr nc_type
id = NC_UINT64;
70#define NETCDFPP_IMPL_TYPE(internal, lib) \
72 struct SystemType<lib> { \
73 using type = internal; \
76 struct Type<internal> { \
77 static constexpr nc_type id = lib; \
78 static constexpr bool is_atomic = true; \
94template<
typename T,
typename Function>
149 throw std::runtime_error(
"Unsupported type");
163 explicit Exception(
int r, std::string s) : std::runtime_error(std::move(s)), ret(r) {}
182constexpr bool is_user_type(nc_type type) {
return type >= NC_FIRSTUSERTYPEID; }
186 return v.empty() ? nullptr : &v[0];
191 return v.empty() ? nullptr : &v[0];
195 std::vector<std::string> res;
196 res.reserve(buf.size());
197 std::copy(std::begin(buf), std::end(buf), std::back_inserter(res));
205 std::vector<std::string> res;
207 std::copy(buf, buf + len, std::back_inserter(res));
208 nc_free_string(len, buf);
213 std::vector<const char*> buf(v.size());
214 std::transform(std::begin(v), std::end(v), std::begin(buf), [](
const std::string& s) {
return s.c_str(); });
225 std::string res =
name;
226 const std::shared_ptr<Path>* current = &
parent;
228 res.insert(0, (*current)->name + ((*current)->parent ?
"/" :
":"));
229 current = &(*current)->parent;
240 static constexpr const char* name =
"Attribute";
245 static constexpr const char* name =
"Dimension";
250 static constexpr const char* name =
"File";
255 static constexpr const char* name =
"Group";
260 static constexpr const char* name =
"UserType";
265 static constexpr const char* name =
"Variable";
271 explicit Object(std::shared_ptr<Path> path_p) :
path(std::move(path_p)) {}
274 if (NC_ISSYSERR(ret)) {
275 return std::strerror(ret);
277 return nc_strerror(ret);
283 if (ret != NC_NOERR) {
289 const std::string&
name()
const {
return path->name; }
303 std::shared_ptr<detail::Path> path;
305 void raise_error()
const {
306 throw Exception(NC_ENOTFOUND, std::string(
detail::ClassName<
typename std::remove_const<T>::type>::name) +
" not found: " + path->get_full_path());
310 explicit Maybe(std::shared_ptr<detail::Path> path_p) : path(std::move(path_p)) {}
321 inline bool valid()
const {
return path->id >= 0; }
324 inline operator bool()
const {
return valid(); }
334 explicit Attribute(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
337 if (
path->parent->is_group) {
338 return path->parent->id;
340 return path->parent->parent->id;
345 if (
path->parent->is_group) {
348 return path->parent->id;
353 int get_internal(
int ncid_p,
int othid_p,
const char* name_p, T* v)
const {
355 return nc_get_att(ncid_p, othid_p, name_p, v);
359 int set_internal(
int ncid_p,
int othid_p,
const char* name_p, std::size_t len,
const T* v);
370 std::vector<T>
get()
const {
371 static_assert(!std::is_same<char*, T>::value && !std::is_same<const char*, T>::value,
"Use get_string() for reading string attributes");
373 check(nc_inq_attlen(ncid(), othid(),
path->name.c_str(), &len));
374 std::vector<T> res(len);
385 check(nc_inq_attlen(ncid(), othid(),
path->name.c_str(), &len));
386 std::vector<char> buf(len + 1);
388 check(nc_get_att_text(ncid(), othid(),
path->name.c_str(), &buf[0]));
389 return std::string(&buf[0]);
413 check(nc_rename_att(ncid(), othid(),
path->name.c_str(),
name.c_str()));
419 void set(
const std::vector<T>& v) {
420 static_assert(
Type<T>::is_atomic,
"For user type attributes use Attribute::set(const std::vector<T>& v, const UserType& type)");
433 typename std::enable_if<std::is_same<std::string, T>::value,
void>
::type set(T v) {
434 check(set_internal(ncid(), othid(),
path->name.c_str(), v.length() + 1, v.c_str()));
438 typename std::enable_if<std::is_same<const char*, T>::value || std::is_same<char*, T>::value,
void>
::type set(T v) {
439 check(set_internal(ncid(), othid(),
path->name.c_str(), std::strlen(v) + 1, v));
443 typename std::enable_if<!std::is_same<std::string, T>::value && !std::is_same<const char*, T>::value && !std::is_same<char*, T>::value,
void>
::type set(
445 static_assert(
Type<T>::is_atomic,
"For user type attributes use Attribute::set(T v, const UserType& type)");
446 check(set_internal<T>(ncid(), othid(),
path->name.c_str(), 1, &v));
452 check(nc_inq_attlen(ncid(), othid(),
path->name.c_str(), &len));
459 check(nc_inq_atttype(ncid(), othid(),
path->name.c_str(), &res));
465 char name[NC_MAX_NAME + 1];
473 if (name_l !=
name) {
474 throw Exception(NC_EVARMETA,
"Unexpected type '" + name_l +
"': " +
path->get_full_path());
490 mutable std::size_t size_m = 0;
491 mutable bool size_read =
false;
493 explicit Dimension(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
508 check(nc_inq_unlimdims(
path->parent->id, &len,
nullptr));
512 std::vector<int> ids(len);
514 return std::find(std::begin(ids), std::end(ids),
path->id) != std::end(ids);
536 explicit Group(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
580 res.copy_from(g, variable_values);
635 const auto ret = nc_inq_attid(
path->id, NC_GLOBAL, res->name.c_str(), &res->id);
636 if (ret != NC_ENOTATT) {
646 std::vector<Attribute> res;
648 char name[NC_MAX_NAME + 1];
649 for (
int id = 0;
id < count; ++
id) {
678 for (
const auto& it : g.
groups()) {
691 const auto ret = nc_inq_dimid(
path->id, res->name.c_str(), &res->id);
692 if (ret != NC_EBADDIM) {
706 std::vector<int> ids(count);
709 char name[NC_MAX_NAME + 1];
710 std::vector<Dimension> res;
712 std::transform(std::begin(ids), std::end(ids), std::back_inserter(res), [&](
int id) {
722 const auto ret = nc_inq_grp_ncid(
path->id, res->name.c_str(), &res->id);
723 if (ret != NC_ENOGRP) {
732 check(nc_inq_grps(
path->id, &count,
nullptr));
737 std::vector<int> ids(count);
740 char name[NC_MAX_NAME + 1];
741 std::vector<Group> res;
743 std::transform(std::begin(ids), std::end(ids), std::back_inserter(res), [&](
int id) {
767 const auto ret = nc_inq_typeid(
path->id, res->name.c_str(), &res->id);
768 if (ret != NC_EBADTYPE) {
783 const auto ret = nc_inq_varid(
path->id, res->name.c_str(), &res->id);
784 if (ret != NC_ENOTVAR) {
800 File() :
Group(std::make_shared<detail::Path>(detail::Path{
"", -1, true, nullptr})) {}
806 File(std::string filename,
char mode) :
File() {
open(std::move(filename), mode); }
809 File(
const char* filename,
char mode) :
File(std::string(filename), mode) {}
815 void open(std::string filename,
char mode) {
817 path->name = std::move(filename);
826 check(nc_create(
path->name.c_str(), NC_NETCDF4 | NC_CLOBBER, &
path->id));
829 throw std::runtime_error(
"Unknown file mode");
868 mutable bool fields_read =
false;
869 mutable std::size_t size_m = 0;
870 mutable nc_type basetype_m = 0;
871 mutable std::size_t fieldscount_m = 0;
872 mutable int typeclass_m = 0;
874 explicit UserType(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
876 void read_fields()
const {
877 check(nc_inq_user_type(
path->parent->id,
path->id,
nullptr, &size_m, &basetype_m, &fieldscount_m, &typeclass_m));
895 check(nc_insert_array_compound(
path->parent->id,
path->id,
name.c_str(), offset,
Type<
typename std::remove_all_extents<T>::type>
::id, dim_sizes.size(),
909 std::vector<CompoundField> res;
912 char name[NC_MAX_NAME + 1];
913 for (
int i = 0; i < static_cast<int>(
fieldscount()); ++i) {
914 check(nc_inq_compound_fieldndims(
path->parent->id,
path->id, i, &dims_count));
919 res.emplace_back(std::move(f));
927 std::vector<std::pair<std::string, T>> res;
929 char name[NC_MAX_NAME + 1];
933 res.emplace_back(
name, v);
951 return fieldscount_m;
959 return fieldscount_m;
997 explicit Variable(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
999 std::vector<int> dimension_ids()
const {
1004 std::vector<int> ids(count);
1009 static std::string
type_name(
int ncid_p, nc_type type_p) {
1010 char name[NC_MAX_NAME + 1];
1011 if (nc_inq_type(ncid_p, type_p,
name,
nullptr) != NC_NOERR) {
1017 static bool same_type_for_copy(
int this_ncid, nc_type this_type,
int oth_ncid, nc_type oth_type) {
1020 if (this_is_user != oth_is_user) {
1023 if (!this_is_user) {
1024 return this_type == oth_type;
1029 std::size_t
size(
const std::size_t* ,
const std::size_t* count)
const {
1031 check(nc_inq_varndims(
path->parent->id,
path->id, &dims_count));
1033 std::size_t res = 1;
1034 for (
int i = 0; i < dims_count; ++i) {
1054 const auto ret = nc_inq_attid(
path->parent->id,
path->id, res->name.c_str(), &res->id);
1055 if (ret != NC_ENOTATT) {
1065 std::vector<Attribute> res;
1067 char name[NC_MAX_NAME + 1];
1068 for (
int id = 0;
id < count; ++
id) {
1078 if (dims.size() != names.size()) {
1081 for (std::size_t i = 0; i < names.size(); ++i) {
1082 if (dims[i].
name() != names[i]) {
1092 throw Exception(NC_EVARMETA,
"Unexpected dimensions: " +
path->get_full_path());
1106 const auto this_type =
type();
1107 const auto oth_type = v.
type();
1108 if (!same_type_for_copy(
path->parent->id, this_type, v.
path->parent->id, oth_type)) {
1109 throw Exception(NC_EVARMETA,
"Variable types do not match: " +
path->get_full_path() +
" and " + v.
path->get_full_path());
1112 std::size_t this_type_len;
1113 check(nc_inq_type(
path->parent->id, this_type,
nullptr, &this_type_len));
1114 std::size_t oth_type_len;
1115 check(nc_inq_type(v.
path->parent->id, oth_type,
nullptr, &oth_type_len));
1117 if (this_type_len != oth_type_len) {
1118 throw Exception(NC_EVARMETA,
"Variable type sizes do not match: " +
path->get_full_path() +
" and " + v.
path->get_full_path());
1121 const auto this_sizes =
sizes();
1122 const auto oth_sizes = v.
sizes();
1123 if (this_sizes.size() != oth_sizes.size()) {
1124 throw Exception(NC_EVARMETA,
"Variable dimension counts do not match: " +
path->get_full_path() +
" and " + v.
path->get_full_path());
1126 for (std::size_t i = 0; i < oth_sizes.size(); ++i) {
1127 if (this_sizes[i] != 0
1128 && this_sizes[i] != oth_sizes[i]) {
1129 throw Exception(NC_EVARMETA,
"Variable sizes do not match: " +
path->get_full_path() +
" and " + v.
path->get_full_path());
1133 std::vector<std::size_t> index(this_sizes.size(), 0);
1135 std::vector<char> buf(this_type_len * v.size());
1136 if (this_sizes.empty()) {
1154 const auto ids = dimension_ids();
1155 char name[NC_MAX_NAME + 1];
1156 std::vector<Dimension> res;
1157 res.reserve(ids.size());
1158 std::transform(std::begin(ids), std::end(ids), std::back_inserter(res), [&](
int id) {
1170 if (mode == NC_CONTIGUOUS) {
1178 if (chunks.empty()) {
1179 check(nc_def_var_chunking(
path->parent->id,
path->id, NC_CONTIGUOUS,
nullptr));
1193 check(nc_inq_var_deflate(
path->parent->id,
path->id, &shuffle_filter, &deflate_filter, &deflate_level));
1194 return std::make_pair(shuffle_filter, deflate_filter ? deflate_level : -1);
1199 check(nc_def_var_deflate(
path->parent->id,
path->id, shuffle_filter, deflate_level < 0 ? 0 : 1, deflate_level));
1215 check(nc_inq_var_fletcher32(
path->parent->id,
path->id, &res));
1216 return res == NC_FLETCHER32;
1222 template<
typename T>
1227 check(nc_inq_var_fill(
path->parent->id,
path->id, &no_fill, &res));
1228 return std::make_pair(!no_fill, res);
1231 template<
typename T>
1250 std::vector<std::size_t>
sizes()
const {
1251 std::vector<std::size_t> res;
1252 const auto dims = dimension_ids();
1253 res.reserve(dims.size());
1254 std::transform(std::begin(dims), std::end(dims), std::back_inserter(res), [
this](
int id) {
1256 check(nc_inq_dimlen(
path->parent->id,
id, &tmp));
1264 std::size_t res = 1;
1266 for (
const auto id : dimension_ids()) {
1267 check(nc_inq_dimlen(
path->parent->id,
id, &tmp));
1275 std::size_t
size(
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count)
const {
1276 return size(&start[0], &count[0]);
1281 if (size_p !=
size()) {
1282 throw Exception(NC_EVARMETA,
"Unexpected variable size: " +
path->get_full_path());
1287 template<
typename T>
1290 std::vector<T> res(
size());
1297 template<
typename T>
1299 T
get(
const std::size_t* index)
const {
1304 template<
typename T>
1306 std::vector<T>
get(
const std::size_t* start,
const std::size_t* count)
const {
1307 std::vector<T> res(
size(start, count));
1314 template<
typename T>
1316 std::vector<T>
get(
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride)
const {
1317 std::vector<T> res(
size(start, count));
1325 template<
typename T,
int N>
1327 T
get(
const std::array<std::size_t, N>& index)
const {
1328 return get<T>(&index[0]);
1330 template<
typename T,
int N>
1332 std::vector<T>
get(
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count)
const {
1333 return get<T>(&start[0], &count[0]);
1335 template<
typename T,
int N>
1337 std::vector<T>
get(
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count,
const std::array<std::ptrdiff_t, N>& stride)
const {
1338 return get<T>(&start[0], &count[0], &stride[0]);
1341 template<
typename T>
1344 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1347 template<
typename T>
1349 void read(T* v,
const std::size_t* index)
const {
1350 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1353 template<
typename T>
1355 void read(T* v,
const std::size_t* start,
const std::size_t* count)
const {
1356 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1357 check(nc_get_vara(
path->parent->id,
path->id, start, count, v));
1359 template<
typename T>
1361 void read(T* v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride)
const {
1362 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1363 check(nc_get_vars(
path->parent->id,
path->id, start, count, stride, v));
1365 template<
typename T>
1367 void read(T* v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride,
const std::ptrdiff_t* imap)
const {
1368 static_assert(std::is_same<void, T>::value,
"NetCDF supports mapped access only for atomic types");
1369 check(nc_get_varm(
path->parent->id,
path->id, start, count, stride, imap, v));
1372 template<
typename T,
int N>
1374 void read(T* v,
const std::array<std::size_t, N>& index)
const {
1377 template<
typename T,
int N>
1379 void read(T* v,
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count)
const {
1380 read(v, &start[0], &count[0]);
1382 template<
typename T,
int N>
1384 void read(T* v,
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count,
const std::array<std::ptrdiff_t, N>& stride)
const {
1385 read(v, &start[0], &count[0], &stride[0]);
1387 template<
typename T,
int N>
1390 const std::array<std::size_t, N>& start,
1391 const std::array<std::size_t, N>& count,
1392 const std::array<std::ptrdiff_t, N>& stride,
1393 const std::array<std::ptrdiff_t, N>& imap)
const {
1394 read(v, &start[0], &count[0], &stride[0], &imap[0]);
1397 template<
typename T>
1399 void set(
const std::vector<T>& v) {
1402 template<
typename T>
1404 typename std::enable_if<Type<T>::is_atomic || std::is_same<const char*, T>::value || std::is_same<char*, T>::value,
void>
::type set(
1405 T v,
const std::size_t* index) {
1408 template<
typename T>
1410 typename std::enable_if<!Type<T>::is_atomic && !std::is_same<const char*, T>::value && !std::is_same<char*, T>::value,
void>
::type set(
1411 const T& v,
const std::size_t* index) {
1414 template<
typename T>
1416 void set(
const std::vector<T>& v,
const std::size_t* start,
const std::size_t* count) {
1419 template<
typename T>
1421 void set(
const std::vector<T>& v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride) {
1424 template<
typename T>
1426 void set(
const std::vector<T>& v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride,
const std::ptrdiff_t* imap) {
1430 template<
typename T,
int N>
1432 void set(
const T v,
const std::array<std::size_t, N>& index) {
1435 template<
typename T,
int N>
1437 void set(
const std::vector<T>& v,
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count) {
1438 set(v, &start[0], &count[0]);
1440 template<
typename T,
int N>
1442 void set(
const std::vector<T>& v,
1443 const std::array<std::size_t, N>& start,
1444 const std::array<std::size_t, N>& count,
1445 const std::array<std::ptrdiff_t, N>& stride) {
1446 set(v, &start[0], &count[0], &stride[0]);
1448 template<
typename T,
int N>
1450 void set(
const std::vector<T>& v,
1451 const std::array<std::size_t, N>& start,
1452 const std::array<std::size_t, N>& count,
1453 const std::array<std::ptrdiff_t, N>& stride,
1454 const std::array<std::ptrdiff_t, N>& imap) {
1455 set(v, &start[0], &count[0], &stride[0], &imap[0]);
1458 template<
typename T>
1461 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1464 template<
typename T>
1466 void write(
const T* v,
const std::size_t* index) {
1467 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1470 template<
typename T>
1472 void write(
const T* v,
const std::size_t* start,
const std::size_t* count) {
1473 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1474 check(nc_put_vara(
path->parent->id,
path->id, start, count, v));
1476 template<
typename T>
1478 void write(
const T* v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride) {
1479 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1480 check(nc_put_vars(
path->parent->id,
path->id, start, count, stride, v));
1482 template<
typename T>
1484 void write(
const T* v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride,
const std::ptrdiff_t* imap) {
1485 static_assert(std::is_same<void, T>::value,
"NetCDF supports mapped access only for atomic types");
1486 check(nc_put_varm(
path->parent->id,
path->id, start, count, stride, imap, v));
1489 template<
typename T,
int N>
1491 void write(
const T* v,
const std::array<std::size_t, N>& index) {
1492 write(v, &index[0]);
1494 template<
typename T,
int N>
1496 void write(
const T* v,
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count) {
1497 write(v, &start[0], &count[0]);
1499 template<
typename T,
int N>
1501 void write(
const T* v,
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count,
const std::array<std::ptrdiff_t, N>& stride) {
1502 write(v, &start[0], &count[0], &stride[0]);
1504 template<
typename T,
int N>
1507 const std::array<std::size_t, N>& start,
1508 const std::array<std::size_t, N>& count,
1509 const std::array<std::ptrdiff_t, N>& stride,
1510 const std::array<std::ptrdiff_t, N>& imap) {
1511 write(v, &start[0], &count[0], &stride[0], &imap[0]);
1523 char name[NC_MAX_NAME + 1];
1531 if (name_l !=
name) {
1532 throw Exception(NC_EVARMETA,
"Unexpected type '" + name_l +
"': " +
path->get_full_path());
1537 template<
typename T>
1540 const auto user_type_l =
user_type().require();
1541 if (user_type_l.typeclass() != NC_COMPOUND) {
1542 throw Exception(NC_EVARMETA,
"Type '" + user_type_l.name() +
"' is not a compound: " +
path->get_full_path());
1544 if (user_type_l.bytes_size() !=
sizeof(T) || user_type_l.fieldscount() != fieldscount) {
1545 throw Exception(NC_EVARMETA,
"Unexpected size for type '" + user_type_l.name() +
"': " +
path->get_full_path());
1552 const auto id =
type();
1553 char name[NC_MAX_NAME + 1];
1558 res->name =
path->name +
" not of user type";
1565 auto type_l = a.
type();
1566 std::size_t type_len;
1567 char name[NC_MAX_NAME + 1];
1568 check(nc_inq_type(a.ncid(), type_l,
name, &type_len));
1571 const auto this_type = ([
this,
name]() {
1577 type_l = this_type.id();
1578 if (this_type.bytes_size() != type_len) {
1579 throw Exception(NC_EATTMETA,
"Attribute type sizes do not match: " +
path->get_full_path() +
" and " + a.
path->get_full_path());
1583 const auto oth_size = a.
size();
1584 std::vector<char> buf(type_len * oth_size);
1594 check(nc_inq_attlen(ncid(), othid(),
path->name.c_str(), &len));
1598 char** buf =
static_cast<char**
>(std::malloc(len *
sizeof(
char*)));
1599 check(nc_get_att_string(ncid(), othid(),
path->name.c_str(), buf));
1627 check(nc_put_att(ncid(), othid(),
path->name.c_str(),
type.id(), 1, &v));
1631 const auto id =
type();
1632 char name[NC_MAX_NAME + 1];
1637 res->name =
path->name +
" not of user type";
1646 check(nc_def_compound(
path->id, bytes_size,
name.c_str(), &
id));
1656 static_assert(std::is_enum<T>::value,
"should be an enum class");
1667 check(nc_def_opaque(
path->id, bytes_size,
name.c_str(), &
id));
1690 char name[NC_MAX_NAME + 1];
1691 for (
int i = 0; i < static_cast<int>(t.
fieldscount()); ++i) {
1692 check(nc_inq_enum_member(t.
path->parent->id, t.
id(), i,
name, &buf[0]));
1700 if (field.dimensions.empty()) {
1701 check(nc_insert_compound(
path->id, res.id(), field.name.c_str(), field.offset, field.type));
1703 check(nc_insert_array_compound(
path->id, res.id(), field.name.c_str(), field.offset, field.type,
static_cast<int>(field.dimensions.size()),
1710 throw Exception(0,
"Invalid user type class: " + t.
path->get_full_path());
1746 return add_variable<T>(d.
name(), {d});
1755 std::vector<int> dimids(dims.size());
1756 std::transform(std::begin(dims), std::end(dims), std::begin(dimids), [](
const Dimension& d) {
return d.
path->id; });
1760 std::vector<int> dimids(dims.size());
1761 std::transform(std::begin(dims), std::end(dims), std::begin(dimids), [
this](
const std::string& s) {
return dimension(s).require().path->id; });
1777inline Variable Group::add_variable<std::string>(std::string name,
const std::vector<int>& dims) {
1781inline Variable Group::add_variable<std::string>(std::string name,
const std::vector<Dimension>& dims) {
1785inline Variable Group::add_variable<std::string>(std::string name,
const std::vector<std::string>& dims) {
1790 std::vector<std::string> dims;
1791 dims.reserve(orig_dims.size());
1792 std::transform(std::begin(orig_dims), std::end(orig_dims), std::back_inserter(dims), [](
const Dimension& d) {
return d.
name(); });
1793 auto type = v.
type();
1798 res.copy_attributes(v);
1801 res.set_compression(comp.first, comp.second);
1805 res.set_checksum_enabled(
true);
1813 check(nc_inq_var_fill(v.
path->parent->id, v.
path->id, &no_fill,
nullptr));
1815 check(nc_def_var_fill(res.path->parent->id, res.path->id, 1,
nullptr));
1827 check(nc_inq_typeids(
path->id, &count,
nullptr));
1832 std::vector<int> ids(count);
1835 char name[NC_MAX_NAME + 1];
1836 std::vector<UserType> res;
1837 for (
const auto id : ids) {
1848 check(nc_inq_varids(
path->id, &count,
nullptr));
1853 std::vector<int> ids(count);
1856 char name[NC_MAX_NAME + 1];
1857 std::vector<Variable> res;
1859 std::transform(std::begin(ids), std::end(ids), std::back_inserter(res), [&](
int id) {
1868 std::vector<char*> buf(
size());
1878 check(nc_get_var1_string(
path->parent->id,
path->id, index, &buf));
1879 std::string res(buf);
1880 nc_free_string(1, &buf);
1884inline std::vector<std::string>
Variable::get(
const std::size_t* start,
const std::size_t* count)
const {
1885 std::vector<char*> buf(
size(start, count));
1893inline std::vector<std::string>
Variable::get(
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride)
const {
1894 std::vector<char*> buf(
size(start, count));
1909 const char* t = v.c_str();
1910 check(nc_put_var1_string(
path->parent->id,
path->id, index, &t));
1914 check(nc_put_var1_string(
path->parent->id,
path->id, index, &v));
1917inline void Variable::set(
const std::vector<std::string>& v,
const std::size_t* start,
const std::size_t* count) {
1922inline void Variable::set(
const std::vector<std::string>& v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride) {
1928 const std::vector<std::string>& v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride,
const std::ptrdiff_t* imap) {
1933#define NETCDFPP_IMPL_ATTRIBUTE_GET(type, name) \
1935 inline int Attribute::get_internal(int ncid_p, int othid_p, const char* name_p, type* v) const { \
1936 return nc_get_att##name(ncid_p, othid_p, name_p, v); \
1939#define NETCDFPP_IMPL_ATTRIBUTE_SET(type, name) \
1941 inline int Attribute::set_internal(int ncid_p, int othid_p, const char* name_p, std::size_t len, const type* v) { \
1942 return nc_put_att##name(ncid_p, othid_p, name_p, Type<type>::id, len, v); \
1945#define NETCDFPP_IMPL_VARIABLE_READ(type, name) \
1947 inline void Variable::read(type* v) const { \
1948 check(nc_get_var##name(path->parent->id, path->id, v)); \
1951 inline void Variable::read(type* v, const std::size_t* index) const { \
1952 check(nc_get_var1##name(path->parent->id, path->id, index, v)); \
1955 inline void Variable::read(type* v, const std::size_t* start, const std::size_t* count) const { \
1956 check(nc_get_vara##name(path->parent->id, path->id, start, count, v)); \
1959 inline void Variable::read(type* v, const std::size_t* start, const std::size_t* count, const std::ptrdiff_t* stride) const { \
1960 check(nc_get_vars##name(path->parent->id, path->id, start, count, stride, v)); \
1963 inline void Variable::read(type* v, const std::size_t* start, const std::size_t* count, const std::ptrdiff_t* stride, const std::ptrdiff_t* imap) const { \
1964 check(nc_get_varm##name(path->parent->id, path->id, start, count, stride, imap, v)); \
1967#define NETCDFPP_IMPL_VARIABLE_WRITE(type, name) \
1969 inline void Variable::write(const type* v) { \
1970 check(nc_put_var##name(path->parent->id, path->id, v)); \
1973 inline void Variable::write(const type* v, const std::size_t* index) { \
1974 check(nc_put_var1##name(path->parent->id, path->id, index, v)); \
1977 inline void Variable::write(const type* v, const std::size_t* start, const std::size_t* count) { \
1978 check(nc_put_vara##name(path->parent->id, path->id, start, count, v)); \
1981 inline void Variable::write(const type* v, const std::size_t* start, const std::size_t* count, const std::ptrdiff_t* stride) { \
1982 check(nc_put_vars##name(path->parent->id, path->id, start, count, stride, v)); \
1985 inline void Variable::write(const type* v, const std::size_t* start, const std::size_t* count, const std::ptrdiff_t* stride, const std::ptrdiff_t* imap) { \
1986 check(nc_put_varm##name(path->parent->id, path->id, start, count, stride, imap, v)); \
1989#define NETCDFPP_IMPL_ALL(type, name) \
1990 NETCDFPP_IMPL_ATTRIBUTE_GET(type, name) \
1991 NETCDFPP_IMPL_ATTRIBUTE_SET(type, name) \
1992 NETCDFPP_IMPL_VARIABLE_READ(type, name) \
1993 NETCDFPP_IMPL_VARIABLE_WRITE(type, name)
1999inline int Attribute::set_internal(
int ncid_p,
int othid_p,
const char* name_p, std::size_t len,
const char* v) {
2000 return nc_put_att_text(ncid_p, othid_p, name_p, len, v);
NetCDF attribute attached to a group or variable.
Definition netcdfpp.h:328
void set(const std::vector< T > &v)
Writes a vector of atomic values to the attribute.
Definition netcdfpp.h:419
std::vector< T > get() const
Reads the attribute as a vector of values.
Definition netcdfpp.h:370
void copy_values(const Attribute &a)
Copies the value and type metadata from another attribute.
Definition netcdfpp.h:1564
Attribute require_type(const std::string &name) const
Returns this attribute or throws if its NetCDF type name differs.
Definition netcdfpp.h:471
std::size_t size() const
Returns the number of values stored in the attribute.
Definition netcdfpp.h:450
Maybe< Variable > parent_variable() const
Returns the parent variable for variable attributes.
Definition netcdfpp.h:404
std::string type_name() const
Returns the NetCDF type name of the attribute.
Definition netcdfpp.h:464
Maybe< UserType > user_type() const
Returns the user-defined type for this attribute, if it has one.
Definition netcdfpp.h:1630
std::enable_if< std::is_same< std::string, T >::value, void >::type set(T v)
Writes a string attribute.
Definition netcdfpp.h:433
std::enable_if< std::is_same< constchar *, T >::value||std::is_same< char *, T >::value, void >::type set(T v)
Writes a string attribute from a C string.
Definition netcdfpp.h:438
std::string get_string() const
Reads a classic NetCDF text attribute as a C++ string.
Definition netcdfpp.h:383
std::enable_if<!std::is_same< std::string, T >::value &&!std::is_same< constchar *, T >::value &&!std::is_same< char *, T >::value, void >::type set(T v)
Writes one atomic value to the attribute.
Definition netcdfpp.h:443
nc_type type() const
Returns the NetCDF type id of the attribute.
Definition netcdfpp.h:457
Maybe< Group > parent_group() const
Returns the parent group for group attributes.
Definition netcdfpp.h:396
void rename(std::string name)
Renames the attribute in place.
Definition netcdfpp.h:412
bool is_group_attribute() const
Returns true when this attribute is attached to a group rather than a variable.
Definition netcdfpp.h:393
NetCDF dimension.
Definition netcdfpp.h:484
friend class Group
Definition netcdfpp.h:485
std::size_t size() const
Returns the current dimension length.
Definition netcdfpp.h:497
void rename(std::string name)
Renames the dimension in place.
Definition netcdfpp.h:521
bool is_unlimited() const
Returns true when the dimension is unlimited.
Definition netcdfpp.h:506
Group parent() const
Returns the parent group.
Definition netcdfpp.h:1642
Exception thrown when a NetCDF-C call fails.
Definition netcdfpp.h:157
Exception(int r, std::string s)
Creates an exception with the NetCDF return code and a complete message.
Definition netcdfpp.h:163
int return_code() const
Returns the NetCDF-C return code that caused the exception.
Definition netcdfpp.h:166
NetCDF file handle and root group.
Definition netcdfpp.h:797
File(const char *filename, char mode)
Opens or creates a file.
Definition netcdfpp.h:809
File()
Creates a closed file handle.
Definition netcdfpp.h:800
void close()
Closes the file if it is open.
Definition netcdfpp.h:834
File(std::string filename, char mode)
Opens or creates a file.
Definition netcdfpp.h:806
void sync() const
Flushes buffered changes to disk.
Definition netcdfpp.h:845
bool is_open() const
Returns true when this object owns an open NetCDF file id.
Definition netcdfpp.h:842
~File()
Closes the file if it is open.
Definition netcdfpp.h:812
void open(std::string filename, char mode)
Opens or creates a file, closing any currently open file first.
Definition netcdfpp.h:815
NetCDF group, including the root group represented by File.
Definition netcdfpp.h:528
std::vector< Dimension > dimensions() const
Returns all dimensions visible in this group.
Definition netcdfpp.h:699
Variable add_dimension_variable(std::string name)
Defines an unlimited dimension and a variable with the same name.
Definition netcdfpp.h:1737
Attribute add_attribute(std::string name)
Defines an attribute handle. The attribute is created when a value is written.
Definition netcdfpp.h:540
Group(std::shared_ptr< detail::Path > path_p)
Definition netcdfpp.h:536
std::vector< Variable > variables() const
Returns all variables in this group.
Definition netcdfpp.h:1846
UserType add_user_type(const UserType &t)
Copies a user-defined type into this group.
Definition netcdfpp.h:1681
void copy_attributes(const Group &g)
Copies all group attributes from another group.
Definition netcdfpp.h:657
Variable add_variable(std::string name, const UserType &type, const std::vector< int > &dims)
Defines a variable using a user-defined type and dimension ids.
Definition netcdfpp.h:1726
Dimension add_dimension(std::string name, std::size_t len)
Defines a fixed-size dimension.
Definition netcdfpp.h:553
Attribute add_attribute(const Attribute &a)
Copies an attribute into this group.
Definition netcdfpp.h:543
UserType add_type_opaque(std::string name, std::size_t bytes_size)
Defines an opaque user type.
Definition netcdfpp.h:1665
UserType add_type_compound(std::string name, std::size_t bytes_size)
Defines a compound user type with an explicit byte size.
Definition netcdfpp.h:1644
UserType add_type_vlen(std::string name, nc_type basetype)
Defines a variable-length user type with an explicit NetCDF base type.
Definition netcdfpp.h:1675
UserType add_type_enum(std::string name, nc_type basetype)
Defines an enum user type with an explicit NetCDF base type.
Definition netcdfpp.h:1659
Maybe< Dimension > dimension(std::string name) const
Looks up a dimension by name.
Definition netcdfpp.h:689
std::vector< Group > groups() const
Returns all direct child groups.
Definition netcdfpp.h:730
void copy_dimensions(const Group &g)
Copies all dimensions from another group.
Definition netcdfpp.h:663
void copy_groups(const Group &g, bool variable_values=false)
Copies child groups from another group.
Definition netcdfpp.h:677
void copy_variables(const Group &g, bool variable_values=false)
Copies variables from another group.
Definition netcdfpp.h:1720
void copy_user_types(const Group &g)
Copies user-defined types from another group.
Definition netcdfpp.h:1714
Maybe< UserType > user_type(std::string name) const
Looks up a user-defined type by name.
Definition netcdfpp.h:765
void copy_from(const Group &g, bool variable_values=false)
Copies attributes, dimensions, user types, variables, and child groups.
Definition netcdfpp.h:669
void rename(std::string name)
Renames the group in place.
Definition netcdfpp.h:751
friend class Variable
Definition netcdfpp.h:533
Maybe< Group > parent() const
Returns the parent group, if this is not the root group.
Definition netcdfpp.h:757
Group add_group(const Group &g, bool variable_values=false)
Copies a group into this group.
Definition netcdfpp.h:578
friend class Dimension
Definition netcdfpp.h:530
friend class Attribute
Definition netcdfpp.h:529
Maybe< Variable > variable(std::string name) const
Looks up a variable by name.
Definition netcdfpp.h:781
Maybe< Group > group(std::string name) const
Looks up a child group by name.
Definition netcdfpp.h:720
Maybe< Attribute > attribute(std::string name) const
Looks up a group attribute by name.
Definition netcdfpp.h:633
friend class UserType
Definition netcdfpp.h:532
Dimension add_dimension(std::string name)
Defines an unlimited dimension.
Definition netcdfpp.h:550
Dimension add_dimension(const Dimension &d)
Copies a dimension into this group.
Definition netcdfpp.h:559
Group add_group(std::string name)
Defines a child group.
Definition netcdfpp.h:572
friend class Maybe< Group >
Definition netcdfpp.h:531
std::vector< Attribute > attributes() const
Returns all group attributes.
Definition netcdfpp.h:643
std::vector< UserType > user_types() const
Returns all user-defined types in this group.
Definition netcdfpp.h:1825
Optional result returned by object lookup functions.
Definition netcdfpp.h:301
bool valid() const
Returns true when the lookup found an object.
Definition netcdfpp.h:321
T require() const
Returns the object or throws netCDF::Exception if the lookup failed.
Definition netcdfpp.h:313
Maybe(std::shared_ptr< detail::Path > path_p)
Definition netcdfpp.h:310
NetCDF user-defined type.
Definition netcdfpp.h:849
Group parent() const
Returns the parent group.
Definition netcdfpp.h:883
std::size_t memberscount() const
Returns the number of members in an enum type.
Definition netcdfpp.h:955
nc_type basetype() const
Returns the base NetCDF type of enum and variable-length types.
Definition netcdfpp.h:939
friend class Group
Definition netcdfpp.h:850
UserType add_compound_field(const std::string &name, std::size_t offset)
Adds a scalar field to a compound type.
Definition netcdfpp.h:887
std::vector< CompoundField > compound_fields() const
Returns compound field metadata.
Definition netcdfpp.h:908
std::size_t bytes_size() const
Returns the byte size of the user-defined type.
Definition netcdfpp.h:963
int typeclass() const
Returns NC_VLEN, NC_OPAQUE, NC_ENUM, or NC_COMPOUND.
Definition netcdfpp.h:971
UserType add_compound_field_array(const std::string &name, std::size_t offset, const std::vector< int > &dim_sizes)
Adds an array field to a compound type.
Definition netcdfpp.h:894
std::vector< std::pair< std::string, T > > enum_members() const
Returns enum members as name/value pairs.
Definition netcdfpp.h:926
std::size_t fieldscount() const
Returns the number of fields in a compound type.
Definition netcdfpp.h:947
UserType add_enum_member(const std::string &name, T v)
Adds an enum member.
Definition netcdfpp.h:902
friend class testing::TestUserType
Definition netcdfpp.h:852
NetCDF variable.
Definition netcdfpp.h:992
void set(const std::vector< T > &v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count)
Writes a fixed-rank hyperslab from a vector.
Definition netcdfpp.h:1437
void unset_fill()
Disables fill for this variable.
Definition netcdfpp.h:1238
void read(T *v, const std::size_t *start, const std::size_t *count) const
Reads a hyperslab into caller-provided storage.
Definition netcdfpp.h:1355
void read(T *v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count, const std::array< std::ptrdiff_t, N > &stride) const
Reads a fixed-rank strided hyperslab into caller-provided storage.
Definition netcdfpp.h:1384
Attribute add_attribute(std::string name)
Defines an attribute handle. The attribute is created when a value is written.
Definition netcdfpp.h:1042
void set(const std::vector< T > &v)
Writes the whole variable from a vector.
Definition netcdfpp.h:1399
std::vector< T > get(const std::size_t *start, const std::size_t *count) const
Reads a hyperslab by raw NetCDF start/count pointers.
Definition netcdfpp.h:1306
std::size_t size(const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count) const
Returns the number of elements selected by a hyperslab count.
Definition netcdfpp.h:1275
void set(const T v, const std::array< std::size_t, N > &index)
Writes one fixed-rank element.
Definition netcdfpp.h:1432
friend class Group
Definition netcdfpp.h:993
void set_compression(bool shuffle_filter, int deflate_level)
Sets shuffle and deflate compression.
Definition netcdfpp.h:1198
void read(T *v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count) const
Reads a fixed-rank hyperslab into caller-provided storage.
Definition netcdfpp.h:1379
void write(const T *v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count)
Writes a fixed-rank hyperslab from caller-provided storage.
Definition netcdfpp.h:1496
void read(T *v, const std::size_t *start, const std::size_t *count, const std::ptrdiff_t *stride, const std::ptrdiff_t *imap) const
Reads mapped data into caller-provided storage.
Definition netcdfpp.h:1367
void write(const T *v)
Writes the whole variable from caller-provided storage.
Definition netcdfpp.h:1460
std::vector< T > get(const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count, const std::array< std::ptrdiff_t, N > &stride) const
Reads a fixed-rank strided hyperslab.
Definition netcdfpp.h:1337
void read(T *v, const std::size_t *index) const
Reads one element into caller-provided storage.
Definition netcdfpp.h:1349
void read(T *v, const std::array< std::size_t, N > &index) const
Reads one fixed-rank element into caller-provided storage.
Definition netcdfpp.h:1374
std::vector< T > get(const std::size_t *start, const std::size_t *count, const std::ptrdiff_t *stride) const
Reads a strided hyperslab by raw NetCDF pointers.
Definition netcdfpp.h:1316
void rename(std::string name)
Renames the variable in place.
Definition netcdfpp.h:1244
void set(const std::vector< T > &v, const std::size_t *start, const std::size_t *count, const std::ptrdiff_t *stride)
Writes a strided hyperslab from a vector.
Definition netcdfpp.h:1421
std::string type_name() const
Returns the NetCDF type name of the variable.
Definition netcdfpp.h:1522
Group parent() const
Returns the parent group.
Definition netcdfpp.h:1241
void set(const std::vector< T > &v, const std::size_t *start, const std::size_t *count)
Writes a hyperslab from a vector.
Definition netcdfpp.h:1416
void set(const std::vector< T > &v, const std::size_t *start, const std::size_t *count, const std::ptrdiff_t *stride, const std::ptrdiff_t *imap)
Writes mapped data from a vector.
Definition netcdfpp.h:1426
Maybe< Attribute > attribute(std::string name) const
Looks up a variable attribute by name.
Definition netcdfpp.h:1052
nc_type type() const
Returns the NetCDF type id of the variable.
Definition netcdfpp.h:1515
void set(const std::vector< T > &v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count, const std::array< std::ptrdiff_t, N > &stride, const std::array< std::ptrdiff_t, N > &imap)
Writes fixed-rank mapped data from a vector.
Definition netcdfpp.h:1450
std::vector< std::size_t > get_chunking() const
Returns chunk sizes, or an empty vector for contiguous storage.
Definition netcdfpp.h:1166
void write(const T *v, const std::size_t *index)
Writes one element from caller-provided storage.
Definition netcdfpp.h:1466
std::vector< std::size_t > sizes() const
Returns the current size of each dimension.
Definition netcdfpp.h:1250
std::vector< T > get() const
Reads the whole variable as a vector.
Definition netcdfpp.h:1289
Variable require_compound(std::size_t fieldscount) const
Returns this variable or throws if its user-defined type is not a matching compound type.
Definition netcdfpp.h:1539
void set_default_chunking()
Lets NetCDF choose default chunk sizes.
Definition netcdfpp.h:1186
void read(T *v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count, const std::array< std::ptrdiff_t, N > &stride, const std::array< std::ptrdiff_t, N > &imap) const
Reads fixed-rank mapped data into caller-provided storage.
Definition netcdfpp.h:1389
void read(T *v) const
Reads the whole variable into caller-provided storage.
Definition netcdfpp.h:1343
void set_chunking(const std::vector< std::size_t > &chunks)
Sets chunked storage, or contiguous storage when chunks is empty.
Definition netcdfpp.h:1177
bool get_checksum_enabled() const
Returns true when Fletcher32 checksums are enabled.
Definition netcdfpp.h:1213
std::vector< Attribute > attributes() const
Returns all variable attributes.
Definition netcdfpp.h:1062
Variable require_type(const std::string &name) const
Returns this variable or throws if its NetCDF type name differs.
Definition netcdfpp.h:1529
std::enable_if< Type< T >::is_atomic||std::is_same< constchar *, T >::value||std::is_same< char *, T >::value, void >::type set(T v, const std::size_t *index)
Writes one value by raw NetCDF index pointer.
Definition netcdfpp.h:1404
void set(const std::vector< T > &v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count, const std::array< std::ptrdiff_t, N > &stride)
Writes a fixed-rank strided hyperslab from a vector.
Definition netcdfpp.h:1442
void write(const T *v, const std::size_t *start, const std::size_t *count, const std::ptrdiff_t *stride, const std::ptrdiff_t *imap)
Writes mapped data from caller-provided storage.
Definition netcdfpp.h:1484
void set_checksum_enabled(bool v)
Enables or disables Fletcher32 checksums.
Definition netcdfpp.h:1220
void write(const T *v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count, const std::array< std::ptrdiff_t, N > &stride, const std::array< std::ptrdiff_t, N > &imap)
Writes fixed-rank mapped data from caller-provided storage.
Definition netcdfpp.h:1506
T get(const std::array< std::size_t, N > &index) const
Reads one element by fixed-rank index.
Definition netcdfpp.h:1327
int get_endianness() const
Returns the NetCDF endianness setting.
Definition netcdfpp.h:1203
Variable require_dimensions(const std::vector< std::string > &names) const
Returns this variable or throws if its dimensions do not match.
Definition netcdfpp.h:1090
Variable require_size(std::size_t size_p) const
Returns this variable or throws if its total element count differs.
Definition netcdfpp.h:1280
std::vector< Dimension > dimensions() const
Returns the variable dimensions.
Definition netcdfpp.h:1153
std::enable_if<!Type< T >::is_atomic &&!std::is_same< constchar *, T >::value &&!std::is_same< char *, T >::value, void >::type set(const T &v, const std::size_t *index)
Writes one non-atomic value by raw NetCDF index pointer.
Definition netcdfpp.h:1410
void copy_attributes(const Variable &v)
Copies all attributes from another variable.
Definition netcdfpp.h:1098
void write(const T *v, const std::size_t *start, const std::size_t *count)
Writes a hyperslab from caller-provided storage.
Definition netcdfpp.h:1472
void write(const T *v, const std::array< std::size_t, N > &index)
Writes one fixed-rank element from caller-provided storage.
Definition netcdfpp.h:1491
std::pair< bool, T > get_fill() const
Returns whether fill is enabled and the fill value.
Definition netcdfpp.h:1224
void copy_values(const Variable &v)
Copies raw values from another variable after checking shape and type size.
Definition netcdfpp.h:1105
void set_endianness(int endianness)
Sets NC_ENDIAN_NATIVE, NC_ENDIAN_LITTLE, or NC_ENDIAN_BIG.
Definition netcdfpp.h:1210
void write(const T *v, const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count, const std::array< std::ptrdiff_t, N > &stride)
Writes a fixed-rank strided hyperslab from caller-provided storage.
Definition netcdfpp.h:1501
std::pair< bool, int > get_compression() const
Returns shuffle status and deflate level, or -1 when deflate is disabled.
Definition netcdfpp.h:1189
void write(const T *v, const std::size_t *start, const std::size_t *count, const std::ptrdiff_t *stride)
Writes a strided hyperslab from caller-provided storage.
Definition netcdfpp.h:1478
Maybe< UserType > user_type() const
Returns the user-defined type for this variable, if it has one.
Definition netcdfpp.h:1551
std::size_t dimension_count() const
Returns the number of dimensions.
Definition netcdfpp.h:1146
std::vector< T > get(const std::array< std::size_t, N > &start, const std::array< std::size_t, N > &count) const
Reads a fixed-rank hyperslab.
Definition netcdfpp.h:1332
void read(T *v, const std::size_t *start, const std::size_t *count, const std::ptrdiff_t *stride) const
Reads a strided hyperslab into caller-provided storage.
Definition netcdfpp.h:1361
T get(const std::size_t *index) const
Reads one element by raw NetCDF index pointer.
Definition netcdfpp.h:1299
bool check_dimensions(const std::vector< std::string > &names) const
Returns true when the variable dimensions match the supplied names exactly.
Definition netcdfpp.h:1076
Attribute add_attribute(const Attribute &a)
Copies an attribute onto this variable.
Definition netcdfpp.h:1045
std::size_t size() const
Returns the total number of elements.
Definition netcdfpp.h:1263
void set_fill(T v)
Enables fill and sets the fill value.
Definition netcdfpp.h:1233
Definition netcdfpp.h:268
const std::string & name() const
Definition netcdfpp.h:289
void raise_error(int ret) const
Definition netcdfpp.h:280
int id() const
Definition netcdfpp.h:290
std::shared_ptr< Path > path
Definition netcdfpp.h:270
static std::string get_error_message(int ret)
Definition netcdfpp.h:273
void check(int ret) const
Definition netcdfpp.h:282
Object(std::shared_ptr< Path > path_p)
Definition netcdfpp.h:271
T * data_or_null(std::vector< T > &v)
Definition netcdfpp.h:185
std::vector< std::string > process_char_vector(std::vector< char * > &buf)
Definition netcdfpp.h:194
constexpr bool is_user_type(nc_type type)
Definition netcdfpp.h:182
std::vector< const char * > process_string_vector(const std::vector< std::string > &v)
Definition netcdfpp.h:212
T for_type(nc_type t, Function &&f)
Calls a callable with a default value of the C++ type matching a NetCDF atomic type.
Definition netcdfpp.h:98
#define NETCDFPP_IMPL_TYPE(internal, lib)
Definition netcdfpp.h:70
#define NETCDFPP_IMPL_VARIABLE_WRITE(type, name)
Definition netcdfpp.h:1967
#define NETCDFPP_IMPL_ALL(type, name)
Definition netcdfpp.h:1989
#define NETCDFPP_IMPL_VARIABLE_READ(type, name)
Definition netcdfpp.h:1945
static constexpr bool is_atomic
Definition netcdfpp.h:56
Compound field metadata.
Definition netcdfpp.h:856
nc_type type
NetCDF type id of the field.
Definition netcdfpp.h:858
std::vector< int > dimensions
Array dimensions for array fields; empty for scalar fields.
Definition netcdfpp.h:864
std::size_t offset
Byte offset of the field in the compound type.
Definition netcdfpp.h:862
std::string name
Field name.
Definition netcdfpp.h:860
RAII wrapper for one NetCDF variable-length value returned by the C API.
Definition netcdfpp.h:981
const T * data
Pointer to the allocated element data.
Definition netcdfpp.h:985
~VLenElement()
Definition netcdfpp.h:988
const std::size_t size
Number of elements.
Definition netcdfpp.h:983
VLenElement()
Definition netcdfpp.h:987
Definition netcdfpp.h:236
Definition netcdfpp.h:218
std::string name
Definition netcdfpp.h:219
int id
Definition netcdfpp.h:220
bool is_group
Definition netcdfpp.h:221
std::shared_ptr< Path > parent
Definition netcdfpp.h:222
std::string get_full_path() const
Definition netcdfpp.h:224