43#include <initializer_list>
62 static constexpr nc_type
id = NC_INT64;
66struct Type<unsigned long long> {
67 static constexpr nc_type
id = NC_UINT64;
71#define NETCDFPP_IMPL_TYPE(internal, lib) \
73 struct SystemType<lib> { \
74 using type = internal; \
77 struct Type<internal> { \
78 static constexpr nc_type id = lib; \
79 static constexpr bool is_atomic = true; \
95template<
typename T,
typename Function>
150 throw std::runtime_error(
"Unsupported type");
164 explicit Exception(
int r, std::string s) : std::runtime_error(std::move(s)), ret(r) {}
183constexpr bool is_user_type(nc_type type) {
return type >= NC_FIRSTUSERTYPEID; }
187 return v.empty() ? nullptr : &v[0];
192 return v.empty() ? nullptr : &v[0];
196 std::vector<std::string> res;
197 res.reserve(buf.size());
198 std::copy(std::begin(buf), std::end(buf), std::back_inserter(res));
206 std::vector<std::string> res;
208 std::copy(buf, buf + len, std::back_inserter(res));
209 nc_free_string(len, buf);
214 std::vector<const char*> buf(v.size());
215 std::transform(std::begin(v), std::end(v), std::begin(buf), [](
const std::string& s) {
return s.c_str(); });
226 std::string res =
name;
227 const std::shared_ptr<Path>* current = &
parent;
229 res.insert(0, (*current)->name + ((*current)->parent ?
"/" :
":"));
230 current = &(*current)->parent;
241 static constexpr const char* name =
"Attribute";
246 static constexpr const char* name =
"Dimension";
251 static constexpr const char* name =
"File";
256 static constexpr const char* name =
"Group";
261 static constexpr const char* name =
"UserType";
266 static constexpr const char* name =
"Variable";
272 explicit Object(std::shared_ptr<Path> path_p) :
path(std::move(path_p)) {}
275 if (NC_ISSYSERR(ret)) {
276 return std::strerror(ret);
278 return nc_strerror(ret);
284 if (ret != NC_NOERR) {
290 const std::string&
name()
const {
return path->name; }
304 std::shared_ptr<detail::Path> path;
306 void raise_error()
const {
307 throw Exception(NC_ENOTFOUND, std::string(
detail::ClassName<
typename std::remove_const<T>::type>::name) +
" not found: " + path->get_full_path());
311 explicit Maybe(std::shared_ptr<detail::Path> path_p) : path(std::move(path_p)) {}
322 inline bool valid()
const {
return path->id >= 0; }
325 inline operator bool()
const {
return valid(); }
335 explicit Attribute(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
338 if (
path->parent->is_group) {
339 return path->parent->id;
341 return path->parent->parent->id;
346 if (
path->parent->is_group) {
349 return path->parent->id;
354 int get_internal(
int ncid_p,
int othid_p,
const char* name_p, T* v)
const {
356 return nc_get_att(ncid_p, othid_p, name_p, v);
360 int set_internal(
int ncid_p,
int othid_p,
const char* name_p, std::size_t len,
const T* v);
371 std::vector<T>
get()
const {
372 static_assert(!std::is_same<char*, T>::value && !std::is_same<const char*, T>::value,
"Use get_string() for reading string attributes");
374 check(nc_inq_attlen(ncid(), othid(),
path->name.c_str(), &len));
375 std::vector<T> res(len);
386 check(nc_inq_attlen(ncid(), othid(),
path->name.c_str(), &len));
387 std::vector<char> buf(len + 1);
389 check(nc_get_att_text(ncid(), othid(),
path->name.c_str(), &buf[0]));
390 return std::string(&buf[0]);
414 check(nc_rename_att(ncid(), othid(),
path->name.c_str(),
name.c_str()));
420 void set(
const std::vector<T>& v) {
421 static_assert(
Type<T>::is_atomic,
"For user type attributes use Attribute::set(const std::vector<T>& v, const UserType& type)");
434 typename std::enable_if<std::is_same<std::string, T>::value,
void>
::type set(T v) {
435 check(set_internal(ncid(), othid(),
path->name.c_str(), v.length() + 1, v.c_str()));
439 typename std::enable_if<std::is_same<const char*, T>::value || std::is_same<char*, T>::value,
void>
::type set(T v) {
440 check(set_internal(ncid(), othid(),
path->name.c_str(), std::strlen(v) + 1, v));
444 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(
446 static_assert(
Type<T>::is_atomic,
"For user type attributes use Attribute::set(T v, const UserType& type)");
447 check(set_internal<T>(ncid(), othid(),
path->name.c_str(), 1, &v));
453 check(nc_inq_attlen(ncid(), othid(),
path->name.c_str(), &len));
460 check(nc_inq_atttype(ncid(), othid(),
path->name.c_str(), &res));
466 char name[NC_MAX_NAME + 1];
474 if (name_l !=
name) {
475 throw Exception(NC_EVARMETA,
"Unexpected type '" + name_l +
"': " +
path->get_full_path());
491 mutable std::size_t size_m = 0;
492 mutable bool size_read =
false;
494 explicit Dimension(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
509 check(nc_inq_unlimdims(
path->parent->id, &len,
nullptr));
513 std::vector<int> ids(len);
515 return std::find(std::begin(ids), std::end(ids),
path->id) != std::end(ids);
537 explicit Group(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
581 res.copy_from(g, variable_values);
660 const auto ret = nc_inq_attid(
path->id, NC_GLOBAL, res->name.c_str(), &res->id);
661 if (ret != NC_ENOTATT) {
671 std::vector<Attribute> res;
673 char name[NC_MAX_NAME + 1];
674 for (
int id = 0;
id < count; ++
id) {
703 for (
const auto& it : g.
groups()) {
716 const auto ret = nc_inq_dimid(
path->id, res->name.c_str(), &res->id);
717 if (ret != NC_EBADDIM) {
731 std::vector<int> ids(count);
734 char name[NC_MAX_NAME + 1];
735 std::vector<Dimension> res;
737 std::transform(std::begin(ids), std::end(ids), std::back_inserter(res), [&](
int id) {
747 const auto ret = nc_inq_grp_ncid(
path->id, res->name.c_str(), &res->id);
748 if (ret != NC_ENOGRP) {
757 check(nc_inq_grps(
path->id, &count,
nullptr));
762 std::vector<int> ids(count);
765 char name[NC_MAX_NAME + 1];
766 std::vector<Group> res;
768 std::transform(std::begin(ids), std::end(ids), std::back_inserter(res), [&](
int id) {
792 const auto ret = nc_inq_typeid(
path->id, res->name.c_str(), &res->id);
793 if (ret != NC_EBADTYPE) {
808 const auto ret = nc_inq_varid(
path->id, res->name.c_str(), &res->id);
809 if (ret != NC_ENOTVAR) {
825 File() :
Group(std::make_shared<detail::Path>(detail::Path{
"", -1, true, nullptr})) {}
831 File(std::string filename,
char mode) :
File() {
open(std::move(filename), mode); }
834 File(
const char* filename,
char mode) :
File(std::string(filename), mode) {}
840 void open(std::string filename,
char mode) {
842 path->name = std::move(filename);
851 check(nc_create(
path->name.c_str(), NC_NETCDF4 | NC_CLOBBER, &
path->id));
854 throw std::runtime_error(
"Unknown file mode");
893 mutable bool fields_read =
false;
894 mutable std::size_t size_m = 0;
895 mutable nc_type basetype_m = 0;
896 mutable std::size_t fieldscount_m = 0;
897 mutable int typeclass_m = 0;
899 explicit UserType(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
901 void read_fields()
const {
902 check(nc_inq_user_type(
path->parent->id,
path->id,
nullptr, &size_m, &basetype_m, &fieldscount_m, &typeclass_m));
920 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(),
934 std::vector<CompoundField> res;
937 char name[NC_MAX_NAME + 1];
938 for (
int i = 0; i < static_cast<int>(
fieldscount()); ++i) {
939 check(nc_inq_compound_fieldndims(
path->parent->id,
path->id, i, &dims_count));
944 res.emplace_back(std::move(f));
952 std::vector<std::pair<std::string, T>> res;
954 char name[NC_MAX_NAME + 1];
958 res.emplace_back(
name, v);
976 return fieldscount_m;
984 return fieldscount_m;
1022 explicit Variable(std::shared_ptr<detail::Path> path_p) : detail::
Object(std::move(path_p)) {}
1024 std::vector<int> dimension_ids()
const {
1029 std::vector<int> ids(count);
1034 static std::string
type_name(
int ncid_p, nc_type type_p) {
1035 char name[NC_MAX_NAME + 1];
1036 if (nc_inq_type(ncid_p, type_p,
name,
nullptr) != NC_NOERR) {
1042 static bool same_type_for_copy(
int this_ncid, nc_type this_type,
int oth_ncid, nc_type oth_type) {
1045 if (this_is_user != oth_is_user) {
1048 if (!this_is_user) {
1049 return this_type == oth_type;
1054 std::size_t
size(
const std::size_t* ,
const std::size_t* count)
const {
1056 check(nc_inq_varndims(
path->parent->id,
path->id, &dims_count));
1058 std::size_t res = 1;
1059 for (
int i = 0; i < dims_count; ++i) {
1079 const auto ret = nc_inq_attid(
path->parent->id,
path->id, res->name.c_str(), &res->id);
1080 if (ret != NC_ENOTATT) {
1090 std::vector<Attribute> res;
1092 char name[NC_MAX_NAME + 1];
1093 for (
int id = 0;
id < count; ++
id) {
1103 if (dims.size() != names.size()) {
1106 for (std::size_t i = 0; i < names.size(); ++i) {
1107 if (dims[i].
name() != names[i]) {
1117 throw Exception(NC_EVARMETA,
"Unexpected dimensions: " +
path->get_full_path());
1131 const auto this_type =
type();
1132 const auto oth_type = v.
type();
1133 if (!same_type_for_copy(
path->parent->id, this_type, v.
path->parent->id, oth_type)) {
1134 throw Exception(NC_EVARMETA,
"Variable types do not match: " +
path->get_full_path() +
" and " + v.
path->get_full_path());
1137 std::size_t this_type_len;
1138 check(nc_inq_type(
path->parent->id, this_type,
nullptr, &this_type_len));
1139 std::size_t oth_type_len;
1140 check(nc_inq_type(v.
path->parent->id, oth_type,
nullptr, &oth_type_len));
1142 if (this_type_len != oth_type_len) {
1143 throw Exception(NC_EVARMETA,
"Variable type sizes do not match: " +
path->get_full_path() +
" and " + v.
path->get_full_path());
1146 const auto this_sizes =
sizes();
1147 const auto oth_sizes = v.
sizes();
1148 if (this_sizes.size() != oth_sizes.size()) {
1149 throw Exception(NC_EVARMETA,
"Variable dimension counts do not match: " +
path->get_full_path() +
" and " + v.
path->get_full_path());
1151 for (std::size_t i = 0; i < oth_sizes.size(); ++i) {
1152 if (this_sizes[i] != 0
1153 && this_sizes[i] != oth_sizes[i]) {
1154 throw Exception(NC_EVARMETA,
"Variable sizes do not match: " +
path->get_full_path() +
" and " + v.
path->get_full_path());
1158 std::vector<std::size_t> index(this_sizes.size(), 0);
1160 std::vector<char> buf(this_type_len * v.size());
1161 if (this_sizes.empty()) {
1179 const auto ids = dimension_ids();
1180 char name[NC_MAX_NAME + 1];
1181 std::vector<Dimension> res;
1182 res.reserve(ids.size());
1183 std::transform(std::begin(ids), std::end(ids), std::back_inserter(res), [&](
int id) {
1195 if (mode == NC_CONTIGUOUS) {
1203 if (chunks.empty()) {
1204 check(nc_def_var_chunking(
path->parent->id,
path->id, NC_CONTIGUOUS,
nullptr));
1218 check(nc_inq_var_deflate(
path->parent->id,
path->id, &shuffle_filter, &deflate_filter, &deflate_level));
1219 return std::make_pair(shuffle_filter, deflate_filter ? deflate_level : -1);
1224 check(nc_def_var_deflate(
path->parent->id,
path->id, shuffle_filter, deflate_level < 0 ? 0 : 1, deflate_level));
1240 check(nc_inq_var_fletcher32(
path->parent->id,
path->id, &res));
1241 return res == NC_FLETCHER32;
1247 template<
typename T>
1252 check(nc_inq_var_fill(
path->parent->id,
path->id, &no_fill, &res));
1253 return std::make_pair(!no_fill, res);
1256 template<
typename T>
1275 std::vector<std::size_t>
sizes()
const {
1276 std::vector<std::size_t> res;
1277 const auto dims = dimension_ids();
1278 res.reserve(dims.size());
1279 std::transform(std::begin(dims), std::end(dims), std::back_inserter(res), [
this](
int id) {
1281 check(nc_inq_dimlen(
path->parent->id,
id, &tmp));
1289 std::size_t res = 1;
1291 for (
const auto id : dimension_ids()) {
1292 check(nc_inq_dimlen(
path->parent->id,
id, &tmp));
1298 template<std::
size_t N>
1300 std::size_t
size(
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count)
const {
1301 return size(&start[0], &count[0]);
1306 if (size_p !=
size()) {
1307 throw Exception(NC_EVARMETA,
"Unexpected variable size: " +
path->get_full_path());
1312 template<
typename T>
1315 std::vector<T> res(
size());
1322 template<
typename T>
1324 T
get(
const std::size_t* index)
const {
1329 template<
typename T>
1331 std::vector<T>
get(
const std::size_t* start,
const std::size_t* count)
const {
1332 std::vector<T> res(
size(start, count));
1339 template<
typename T>
1341 std::vector<T>
get(
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride)
const {
1342 std::vector<T> res(
size(start, count));
1350 template<
typename T, std::
size_t N>
1352 T
get(
const std::array<std::size_t, N>& index)
const {
1353 return get<T>(&index[0]);
1355 template<
typename T, std::
size_t N>
1357 std::vector<T>
get(
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count)
const {
1358 return get<T>(&start[0], &count[0]);
1360 template<
typename T, std::
size_t N>
1362 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 {
1363 return get<T>(&start[0], &count[0], &stride[0]);
1366 template<
typename T>
1369 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1372 template<
typename T>
1374 void read(T* v,
const std::size_t* index)
const {
1375 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1378 template<
typename T>
1380 void read(T* v,
const std::size_t* start,
const std::size_t* count)
const {
1381 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1382 check(nc_get_vara(
path->parent->id,
path->id, start, count, v));
1384 template<
typename T>
1386 void read(T* v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride)
const {
1387 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1388 check(nc_get_vars(
path->parent->id,
path->id, start, count, stride, v));
1390 template<
typename T>
1392 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 {
1393 static_assert(std::is_same<void, T>::value,
"NetCDF supports mapped access only for atomic types");
1394 check(nc_get_varm(
path->parent->id,
path->id, start, count, stride, imap, v));
1397 template<
typename T, std::
size_t N>
1399 void read(T* v,
const std::array<std::size_t, N>& index)
const {
1402 template<
typename T, std::
size_t N>
1404 void read(T* v,
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count)
const {
1405 read(v, &start[0], &count[0]);
1407 template<
typename T, std::
size_t N>
1409 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 {
1410 read(v, &start[0], &count[0], &stride[0]);
1412 template<
typename T, std::
size_t N>
1415 const std::array<std::size_t, N>& start,
1416 const std::array<std::size_t, N>& count,
1417 const std::array<std::ptrdiff_t, N>& stride,
1418 const std::array<std::ptrdiff_t, N>& imap)
const {
1419 read(v, &start[0], &count[0], &stride[0], &imap[0]);
1422 template<
typename T>
1424 void set(
const std::vector<T>& v) {
1427 template<
typename T>
1429 typename std::enable_if<Type<T>::is_atomic || std::is_same<const char*, T>::value || std::is_same<char*, T>::value,
void>
::type set(
1430 T v,
const std::size_t* index) {
1433 template<
typename T>
1435 typename std::enable_if<!Type<T>::is_atomic && !std::is_same<const char*, T>::value && !std::is_same<char*, T>::value,
void>
::type set(
1436 const T& v,
const std::size_t* index) {
1439 template<
typename T>
1441 void set(
const std::vector<T>& v,
const std::size_t* start,
const std::size_t* count) {
1444 template<
typename T>
1446 void set(
const std::vector<T>& v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride) {
1449 template<
typename T>
1451 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) {
1455 template<
typename T, std::
size_t N>
1457 void set(
const T v,
const std::array<std::size_t, N>& index) {
1460 template<
typename T, std::
size_t N>
1462 void set(
const std::vector<T>& v,
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count) {
1463 set(v, &start[0], &count[0]);
1465 template<
typename T, std::
size_t N>
1467 void set(
const std::vector<T>& v,
1468 const std::array<std::size_t, N>& start,
1469 const std::array<std::size_t, N>& count,
1470 const std::array<std::ptrdiff_t, N>& stride) {
1471 set(v, &start[0], &count[0], &stride[0]);
1473 template<
typename T, std::
size_t N>
1475 void set(
const std::vector<T>& v,
1476 const std::array<std::size_t, N>& start,
1477 const std::array<std::size_t, N>& count,
1478 const std::array<std::ptrdiff_t, N>& stride,
1479 const std::array<std::ptrdiff_t, N>& imap) {
1480 set(v, &start[0], &count[0], &stride[0], &imap[0]);
1483 template<
typename T>
1486 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1489 template<
typename T>
1491 void write(
const T* v,
const std::size_t* index) {
1492 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1495 template<
typename T>
1497 void write(
const T* v,
const std::size_t* start,
const std::size_t* count) {
1498 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1499 check(nc_put_vara(
path->parent->id,
path->id, start, count, v));
1501 template<
typename T>
1503 void write(
const T* v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride) {
1504 static_assert(!
Type<T>::is_atomic || std::is_same<void, T>::value,
"Use void or one of the explicitly supported types");
1505 check(nc_put_vars(
path->parent->id,
path->id, start, count, stride, v));
1507 template<
typename T>
1509 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) {
1510 static_assert(std::is_same<void, T>::value,
"NetCDF supports mapped access only for atomic types");
1511 check(nc_put_varm(
path->parent->id,
path->id, start, count, stride, imap, v));
1514 template<
typename T, std::
size_t N>
1516 void write(
const T* v,
const std::array<std::size_t, N>& index) {
1517 write(v, &index[0]);
1519 template<
typename T, std::
size_t N>
1521 void write(
const T* v,
const std::array<std::size_t, N>& start,
const std::array<std::size_t, N>& count) {
1522 write(v, &start[0], &count[0]);
1524 template<
typename T, std::
size_t N>
1526 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) {
1527 write(v, &start[0], &count[0], &stride[0]);
1529 template<
typename T, std::
size_t N>
1532 const std::array<std::size_t, N>& start,
1533 const std::array<std::size_t, N>& count,
1534 const std::array<std::ptrdiff_t, N>& stride,
1535 const std::array<std::ptrdiff_t, N>& imap) {
1536 write(v, &start[0], &count[0], &stride[0], &imap[0]);
1548 char name[NC_MAX_NAME + 1];
1556 if (name_l !=
name) {
1557 throw Exception(NC_EVARMETA,
"Unexpected type '" + name_l +
"': " +
path->get_full_path());
1562 template<
typename T>
1565 const auto user_type_l =
user_type().require();
1566 if (user_type_l.typeclass() != NC_COMPOUND) {
1567 throw Exception(NC_EVARMETA,
"Type '" + user_type_l.name() +
"' is not a compound: " +
path->get_full_path());
1569 if (user_type_l.bytes_size() !=
sizeof(T) || user_type_l.fieldscount() != fieldscount) {
1570 throw Exception(NC_EVARMETA,
"Unexpected size for type '" + user_type_l.name() +
"': " +
path->get_full_path());
1577 const auto id =
type();
1578 char name[NC_MAX_NAME + 1];
1583 res->name =
path->name +
" not of user type";
1590 auto type_l = a.
type();
1591 std::size_t type_len;
1592 char name[NC_MAX_NAME + 1];
1593 check(nc_inq_type(a.ncid(), type_l,
name, &type_len));
1596 const auto this_type = ([
this,
name]() {
1602 type_l = this_type.id();
1603 if (this_type.bytes_size() != type_len) {
1604 throw Exception(NC_EATTMETA,
"Attribute type sizes do not match: " +
path->get_full_path() +
" and " + a.
path->get_full_path());
1608 const auto oth_size = a.
size();
1609 std::vector<char> buf(type_len * oth_size);
1619 check(nc_inq_attlen(ncid(), othid(),
path->name.c_str(), &len));
1623 char** buf =
static_cast<char**
>(std::malloc(len *
sizeof(
char*)));
1624 check(nc_get_att_string(ncid(), othid(),
path->name.c_str(), buf));
1652 check(nc_put_att(ncid(), othid(),
path->name.c_str(),
type.id(), 1, &v));
1656 const auto id =
type();
1657 char name[NC_MAX_NAME + 1];
1662 res->name =
path->name +
" not of user type";
1671 check(nc_def_compound(
path->id, bytes_size,
name.c_str(), &
id));
1681 static_assert(std::is_enum<T>::value,
"should be an enum class");
1696 check(nc_def_opaque(
path->id, bytes_size,
name.c_str(), &
id));
1719 char name[NC_MAX_NAME + 1];
1720 for (
int i = 0; i < static_cast<int>(t.
fieldscount()); ++i) {
1721 check(nc_inq_enum_member(t.
path->parent->id, t.
id(), i,
name, &buf[0]));
1729 if (field.dimensions.empty()) {
1730 check(nc_insert_compound(
path->id, res.id(), field.name.c_str(), field.offset, field.type));
1732 check(nc_insert_array_compound(
path->id, res.id(), field.name.c_str(), field.offset, field.type,
static_cast<int>(field.dimensions.size()),
1739 throw Exception(0,
"Invalid user type class: " + t.
path->get_full_path());
1775 return add_variable<T>(d.
name(), {d});
1784 std::vector<int> dimids(dims.size());
1785 std::transform(std::begin(dims), std::end(dims), std::begin(dimids), [](
const Dimension& d) {
return d.
path->id; });
1789 std::vector<int> dimids(dims.size());
1790 std::transform(std::begin(dims), std::end(dims), std::begin(dimids), [
this](
const std::string& s) {
return dimension(s).require().path->id; });
1806inline Variable Group::add_variable<std::string>(std::string name,
const std::vector<int>& dims) {
1810inline Variable Group::add_variable<std::string>(std::string name,
const std::vector<Dimension>& dims) {
1814inline Variable Group::add_variable<std::string>(std::string name,
const std::vector<std::string>& dims) {
1824 return add_variable(std::move(
name), type, std::vector<std::string>(dims));
1833 return add_variable(std::move(
name), type, std::vector<std::string>(dims));
1837 return add_variable<T>(std::move(
name), std::vector<int>(dims));
1841 return add_variable<T>(std::move(
name), std::vector<Dimension>(dims));
1845 return add_variable<T>(std::move(
name), std::vector<std::string>(dims));
1849 std::vector<std::string> dims;
1850 dims.reserve(orig_dims.size());
1851 std::transform(std::begin(orig_dims), std::end(orig_dims), std::back_inserter(dims), [](
const Dimension& d) {
return d.
name(); });
1852 auto type = v.
type();
1857 res.copy_attributes(v);
1860 res.set_compression(comp.first, comp.second);
1864 res.set_checksum_enabled(
true);
1872 check(nc_inq_var_fill(v.
path->parent->id, v.
path->id, &no_fill,
nullptr));
1874 check(nc_def_var_fill(res.path->parent->id, res.path->id, 1,
nullptr));
1886 check(nc_inq_typeids(
path->id, &count,
nullptr));
1891 std::vector<int> ids(count);
1894 char name[NC_MAX_NAME + 1];
1895 std::vector<UserType> res;
1896 for (
const auto id : ids) {
1907 check(nc_inq_varids(
path->id, &count,
nullptr));
1912 std::vector<int> ids(count);
1915 char name[NC_MAX_NAME + 1];
1916 std::vector<Variable> res;
1918 std::transform(std::begin(ids), std::end(ids), std::back_inserter(res), [&](
int id) {
1927 std::vector<char*> buf(
size());
1937 check(nc_get_var1_string(
path->parent->id,
path->id, index, &buf));
1938 std::string res(buf);
1939 nc_free_string(1, &buf);
1943inline std::vector<std::string>
Variable::get(
const std::size_t* start,
const std::size_t* count)
const {
1944 std::vector<char*> buf(
size(start, count));
1952inline std::vector<std::string>
Variable::get(
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride)
const {
1953 std::vector<char*> buf(
size(start, count));
1968 const char* t = v.c_str();
1969 check(nc_put_var1_string(
path->parent->id,
path->id, index, &t));
1973 check(nc_put_var1_string(
path->parent->id,
path->id, index, &v));
1976inline void Variable::set(
const std::vector<std::string>& v,
const std::size_t* start,
const std::size_t* count) {
1981inline void Variable::set(
const std::vector<std::string>& v,
const std::size_t* start,
const std::size_t* count,
const std::ptrdiff_t* stride) {
1987 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) {
1992#define NETCDFPP_IMPL_ATTRIBUTE_GET(type, name) \
1994 inline int Attribute::get_internal(int ncid_p, int othid_p, const char* name_p, type* v) const { \
1995 return nc_get_att##name(ncid_p, othid_p, name_p, v); \
1998#define NETCDFPP_IMPL_ATTRIBUTE_SET(type, name) \
2000 inline int Attribute::set_internal(int ncid_p, int othid_p, const char* name_p, std::size_t len, const type* v) { \
2001 return nc_put_att##name(ncid_p, othid_p, name_p, Type<type>::id, len, v); \
2004#define NETCDFPP_IMPL_VARIABLE_READ(type, name) \
2006 inline void Variable::read(type* v) const { \
2007 check(nc_get_var##name(path->parent->id, path->id, v)); \
2010 inline void Variable::read(type* v, const std::size_t* index) const { \
2011 check(nc_get_var1##name(path->parent->id, path->id, index, v)); \
2014 inline void Variable::read(type* v, const std::size_t* start, const std::size_t* count) const { \
2015 check(nc_get_vara##name(path->parent->id, path->id, start, count, v)); \
2018 inline void Variable::read(type* v, const std::size_t* start, const std::size_t* count, const std::ptrdiff_t* stride) const { \
2019 check(nc_get_vars##name(path->parent->id, path->id, start, count, stride, v)); \
2022 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 { \
2023 check(nc_get_varm##name(path->parent->id, path->id, start, count, stride, imap, v)); \
2026#define NETCDFPP_IMPL_VARIABLE_WRITE(type, name) \
2028 inline void Variable::write(const type* v) { \
2029 check(nc_put_var##name(path->parent->id, path->id, v)); \
2032 inline void Variable::write(const type* v, const std::size_t* index) { \
2033 check(nc_put_var1##name(path->parent->id, path->id, index, v)); \
2036 inline void Variable::write(const type* v, const std::size_t* start, const std::size_t* count) { \
2037 check(nc_put_vara##name(path->parent->id, path->id, start, count, v)); \
2040 inline void Variable::write(const type* v, const std::size_t* start, const std::size_t* count, const std::ptrdiff_t* stride) { \
2041 check(nc_put_vars##name(path->parent->id, path->id, start, count, stride, v)); \
2044 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) { \
2045 check(nc_put_varm##name(path->parent->id, path->id, start, count, stride, imap, v)); \
2048#define NETCDFPP_IMPL_ALL(type, name) \
2049 NETCDFPP_IMPL_ATTRIBUTE_GET(type, name) \
2050 NETCDFPP_IMPL_ATTRIBUTE_SET(type, name) \
2051 NETCDFPP_IMPL_VARIABLE_READ(type, name) \
2052 NETCDFPP_IMPL_VARIABLE_WRITE(type, name)
2058inline int Attribute::set_internal(
int ncid_p,
int othid_p,
const char* name_p, std::size_t len,
const char* v) {
2059 return nc_put_att_text(ncid_p, othid_p, name_p, len, v);
NetCDF attribute attached to a group or variable.
Definition netcdfpp.h:329
void set(const std::vector< T > &v)
Writes a vector of atomic values to the attribute.
Definition netcdfpp.h:420
std::vector< T > get() const
Reads the attribute as a vector of values.
Definition netcdfpp.h:371
void copy_values(const Attribute &a)
Copies the value and type metadata from another attribute.
Definition netcdfpp.h:1589
Attribute require_type(const std::string &name) const
Returns this attribute or throws if its NetCDF type name differs.
Definition netcdfpp.h:472
std::size_t size() const
Returns the number of values stored in the attribute.
Definition netcdfpp.h:451
Maybe< Variable > parent_variable() const
Returns the parent variable for variable attributes.
Definition netcdfpp.h:405
std::string type_name() const
Returns the NetCDF type name of the attribute.
Definition netcdfpp.h:465
Maybe< UserType > user_type() const
Returns the user-defined type for this attribute, if it has one.
Definition netcdfpp.h:1655
std::enable_if< std::is_same< std::string, T >::value, void >::type set(T v)
Writes a string attribute.
Definition netcdfpp.h:434
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:439
std::string get_string() const
Reads a classic NetCDF text attribute as a C++ string.
Definition netcdfpp.h:384
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:444
nc_type type() const
Returns the NetCDF type id of the attribute.
Definition netcdfpp.h:458
Maybe< Group > parent_group() const
Returns the parent group for group attributes.
Definition netcdfpp.h:397
void rename(std::string name)
Renames the attribute in place.
Definition netcdfpp.h:413
bool is_group_attribute() const
Returns true when this attribute is attached to a group rather than a variable.
Definition netcdfpp.h:394
NetCDF dimension.
Definition netcdfpp.h:485
friend class Group
Definition netcdfpp.h:486
std::size_t size() const
Returns the current dimension length.
Definition netcdfpp.h:498
void rename(std::string name)
Renames the dimension in place.
Definition netcdfpp.h:522
bool is_unlimited() const
Returns true when the dimension is unlimited.
Definition netcdfpp.h:507
Group parent() const
Returns the parent group.
Definition netcdfpp.h:1667
Exception thrown when a NetCDF-C call fails.
Definition netcdfpp.h:158
Exception(int r, std::string s)
Creates an exception with the NetCDF return code and a complete message.
Definition netcdfpp.h:164
int return_code() const
Returns the NetCDF-C return code that caused the exception.
Definition netcdfpp.h:167
NetCDF file handle and root group.
Definition netcdfpp.h:822
File(const char *filename, char mode)
Opens or creates a file.
Definition netcdfpp.h:834
File()
Creates a closed file handle.
Definition netcdfpp.h:825
void close()
Closes the file if it is open.
Definition netcdfpp.h:859
File(std::string filename, char mode)
Opens or creates a file.
Definition netcdfpp.h:831
void sync() const
Flushes buffered changes to disk.
Definition netcdfpp.h:870
bool is_open() const
Returns true when this object owns an open NetCDF file id.
Definition netcdfpp.h:867
~File()
Closes the file if it is open.
Definition netcdfpp.h:837
void open(std::string filename, char mode)
Opens or creates a file, closing any currently open file first.
Definition netcdfpp.h:840
NetCDF group, including the root group represented by File.
Definition netcdfpp.h:529
std::vector< Dimension > dimensions() const
Returns all dimensions visible in this group.
Definition netcdfpp.h:724
Variable add_dimension_variable(std::string name)
Defines an unlimited dimension and a variable with the same name.
Definition netcdfpp.h:1766
Attribute add_attribute(std::string name)
Defines an attribute handle. The attribute is created when a value is written.
Definition netcdfpp.h:541
Group(std::shared_ptr< detail::Path > path_p)
Definition netcdfpp.h:537
std::vector< Variable > variables() const
Returns all variables in this group.
Definition netcdfpp.h:1905
UserType add_user_type(const UserType &t)
Copies a user-defined type into this group.
Definition netcdfpp.h:1710
void copy_attributes(const Group &g)
Copies all group attributes from another group.
Definition netcdfpp.h:682
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:1755
Dimension add_dimension(std::string name, std::size_t len)
Defines a fixed-size dimension.
Definition netcdfpp.h:554
Attribute add_attribute(const Attribute &a)
Copies an attribute into this group.
Definition netcdfpp.h:544
UserType add_type_opaque(std::string name, std::size_t bytes_size)
Defines an opaque user type.
Definition netcdfpp.h:1694
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:1669
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:1704
UserType add_type_enum(std::string name, nc_type basetype)
Defines an enum user type with an explicit NetCDF base type.
Definition netcdfpp.h:1684
Maybe< Dimension > dimension(std::string name) const
Looks up a dimension by name.
Definition netcdfpp.h:714
std::vector< Group > groups() const
Returns all direct child groups.
Definition netcdfpp.h:755
void copy_dimensions(const Group &g)
Copies all dimensions from another group.
Definition netcdfpp.h:688
void copy_groups(const Group &g, bool variable_values=false)
Copies child groups from another group.
Definition netcdfpp.h:702
void copy_variables(const Group &g, bool variable_values=false)
Copies variables from another group.
Definition netcdfpp.h:1749
void copy_user_types(const Group &g)
Copies user-defined types from another group.
Definition netcdfpp.h:1743
Maybe< UserType > user_type(std::string name) const
Looks up a user-defined type by name.
Definition netcdfpp.h:790
void copy_from(const Group &g, bool variable_values=false)
Copies attributes, dimensions, user types, variables, and child groups.
Definition netcdfpp.h:694
void rename(std::string name)
Renames the group in place.
Definition netcdfpp.h:776
friend class Variable
Definition netcdfpp.h:534
Maybe< Group > parent() const
Returns the parent group, if this is not the root group.
Definition netcdfpp.h:782
Group add_group(const Group &g, bool variable_values=false)
Copies a group into this group.
Definition netcdfpp.h:579
friend class Dimension
Definition netcdfpp.h:531
friend class Attribute
Definition netcdfpp.h:530
Maybe< Variable > variable(std::string name) const
Looks up a variable by name.
Definition netcdfpp.h:806
Maybe< Group > group(std::string name) const
Looks up a child group by name.
Definition netcdfpp.h:745
Maybe< Attribute > attribute(std::string name) const
Looks up a group attribute by name.
Definition netcdfpp.h:658
friend class UserType
Definition netcdfpp.h:533
Dimension add_dimension(std::string name)
Defines an unlimited dimension.
Definition netcdfpp.h:551
Dimension add_dimension(const Dimension &d)
Copies a dimension into this group.
Definition netcdfpp.h:560
Group add_group(std::string name)
Defines a child group.
Definition netcdfpp.h:573
friend class Maybe< Group >
Definition netcdfpp.h:532
std::vector< Attribute > attributes() const
Returns all group attributes.
Definition netcdfpp.h:668
std::vector< UserType > user_types() const
Returns all user-defined types in this group.
Definition netcdfpp.h:1884
Optional result returned by object lookup functions.
Definition netcdfpp.h:302
bool valid() const
Returns true when the lookup found an object.
Definition netcdfpp.h:322
T require() const
Returns the object or throws netCDF::Exception if the lookup failed.
Definition netcdfpp.h:314
Maybe(std::shared_ptr< detail::Path > path_p)
Definition netcdfpp.h:311
NetCDF user-defined type.
Definition netcdfpp.h:874
Group parent() const
Returns the parent group.
Definition netcdfpp.h:908
std::size_t memberscount() const
Returns the number of members in an enum type.
Definition netcdfpp.h:980
nc_type basetype() const
Returns the base NetCDF type of enum and variable-length types.
Definition netcdfpp.h:964
friend class Group
Definition netcdfpp.h:875
UserType add_compound_field(const std::string &name, std::size_t offset)
Adds a scalar field to a compound type.
Definition netcdfpp.h:912
std::vector< CompoundField > compound_fields() const
Returns compound field metadata.
Definition netcdfpp.h:933
std::size_t bytes_size() const
Returns the byte size of the user-defined type.
Definition netcdfpp.h:988
int typeclass() const
Returns NC_VLEN, NC_OPAQUE, NC_ENUM, or NC_COMPOUND.
Definition netcdfpp.h:996
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:919
std::vector< std::pair< std::string, T > > enum_members() const
Returns enum members as name/value pairs.
Definition netcdfpp.h:951
std::size_t fieldscount() const
Returns the number of fields in a compound type.
Definition netcdfpp.h:972
UserType add_enum_member(const std::string &name, T v)
Adds an enum member.
Definition netcdfpp.h:927
friend class testing::TestUserType
Definition netcdfpp.h:877
NetCDF variable.
Definition netcdfpp.h:1017
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:1462
void unset_fill()
Disables fill for this variable.
Definition netcdfpp.h:1263
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:1380
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:1409
Attribute add_attribute(std::string name)
Defines an attribute handle. The attribute is created when a value is written.
Definition netcdfpp.h:1067
void set(const std::vector< T > &v)
Writes the whole variable from a vector.
Definition netcdfpp.h:1424
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:1331
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:1300
void set(const T v, const std::array< std::size_t, N > &index)
Writes one fixed-rank element.
Definition netcdfpp.h:1457
friend class Group
Definition netcdfpp.h:1018
void set_compression(bool shuffle_filter, int deflate_level)
Sets shuffle and deflate compression.
Definition netcdfpp.h:1223
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:1404
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:1521
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:1392
void write(const T *v)
Writes the whole variable from caller-provided storage.
Definition netcdfpp.h:1485
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:1362
void read(T *v, const std::size_t *index) const
Reads one element into caller-provided storage.
Definition netcdfpp.h:1374
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:1399
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:1341
void rename(std::string name)
Renames the variable in place.
Definition netcdfpp.h:1269
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:1446
std::string type_name() const
Returns the NetCDF type name of the variable.
Definition netcdfpp.h:1547
Group parent() const
Returns the parent group.
Definition netcdfpp.h:1266
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:1441
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:1451
Maybe< Attribute > attribute(std::string name) const
Looks up a variable attribute by name.
Definition netcdfpp.h:1077
nc_type type() const
Returns the NetCDF type id of the variable.
Definition netcdfpp.h:1540
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:1475
std::vector< std::size_t > get_chunking() const
Returns chunk sizes, or an empty vector for contiguous storage.
Definition netcdfpp.h:1191
void write(const T *v, const std::size_t *index)
Writes one element from caller-provided storage.
Definition netcdfpp.h:1491
std::vector< std::size_t > sizes() const
Returns the current size of each dimension.
Definition netcdfpp.h:1275
std::vector< T > get() const
Reads the whole variable as a vector.
Definition netcdfpp.h:1314
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:1564
void set_default_chunking()
Lets NetCDF choose default chunk sizes.
Definition netcdfpp.h:1211
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:1414
void read(T *v) const
Reads the whole variable into caller-provided storage.
Definition netcdfpp.h:1368
void set_chunking(const std::vector< std::size_t > &chunks)
Sets chunked storage, or contiguous storage when chunks is empty.
Definition netcdfpp.h:1202
bool get_checksum_enabled() const
Returns true when Fletcher32 checksums are enabled.
Definition netcdfpp.h:1238
std::vector< Attribute > attributes() const
Returns all variable attributes.
Definition netcdfpp.h:1087
Variable require_type(const std::string &name) const
Returns this variable or throws if its NetCDF type name differs.
Definition netcdfpp.h:1554
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:1429
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:1467
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:1509
void set_checksum_enabled(bool v)
Enables or disables Fletcher32 checksums.
Definition netcdfpp.h:1245
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:1531
T get(const std::array< std::size_t, N > &index) const
Reads one element by fixed-rank index.
Definition netcdfpp.h:1352
int get_endianness() const
Returns the NetCDF endianness setting.
Definition netcdfpp.h:1228
Variable require_dimensions(const std::vector< std::string > &names) const
Returns this variable or throws if its dimensions do not match.
Definition netcdfpp.h:1115
Variable require_size(std::size_t size_p) const
Returns this variable or throws if its total element count differs.
Definition netcdfpp.h:1305
std::vector< Dimension > dimensions() const
Returns the variable dimensions.
Definition netcdfpp.h:1178
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:1435
void copy_attributes(const Variable &v)
Copies all attributes from another variable.
Definition netcdfpp.h:1123
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:1497
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:1516
std::pair< bool, T > get_fill() const
Returns whether fill is enabled and the fill value.
Definition netcdfpp.h:1249
void copy_values(const Variable &v)
Copies raw values from another variable after checking shape and type size.
Definition netcdfpp.h:1130
void set_endianness(int endianness)
Sets NC_ENDIAN_NATIVE, NC_ENDIAN_LITTLE, or NC_ENDIAN_BIG.
Definition netcdfpp.h:1235
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:1526
std::pair< bool, int > get_compression() const
Returns shuffle status and deflate level, or -1 when deflate is disabled.
Definition netcdfpp.h:1214
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:1503
Maybe< UserType > user_type() const
Returns the user-defined type for this variable, if it has one.
Definition netcdfpp.h:1576
std::size_t dimension_count() const
Returns the number of dimensions.
Definition netcdfpp.h:1171
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:1357
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:1386
T get(const std::size_t *index) const
Reads one element by raw NetCDF index pointer.
Definition netcdfpp.h:1324
bool check_dimensions(const std::vector< std::string > &names) const
Returns true when the variable dimensions match the supplied names exactly.
Definition netcdfpp.h:1101
Attribute add_attribute(const Attribute &a)
Copies an attribute onto this variable.
Definition netcdfpp.h:1070
std::size_t size() const
Returns the total number of elements.
Definition netcdfpp.h:1288
void set_fill(T v)
Enables fill and sets the fill value.
Definition netcdfpp.h:1258
Definition netcdfpp.h:269
const std::string & name() const
Definition netcdfpp.h:290
void raise_error(int ret) const
Definition netcdfpp.h:281
int id() const
Definition netcdfpp.h:291
std::shared_ptr< Path > path
Definition netcdfpp.h:271
static std::string get_error_message(int ret)
Definition netcdfpp.h:274
void check(int ret) const
Definition netcdfpp.h:283
Object(std::shared_ptr< Path > path_p)
Definition netcdfpp.h:272
T * data_or_null(std::vector< T > &v)
Definition netcdfpp.h:186
std::vector< std::string > process_char_vector(std::vector< char * > &buf)
Definition netcdfpp.h:195
constexpr bool is_user_type(nc_type type)
Definition netcdfpp.h:183
std::vector< const char * > process_string_vector(const std::vector< std::string > &v)
Definition netcdfpp.h:213
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:99
#define NETCDFPP_IMPL_TYPE(internal, lib)
Definition netcdfpp.h:71
#define NETCDFPP_IMPL_VARIABLE_WRITE(type, name)
Definition netcdfpp.h:2026
#define NETCDFPP_IMPL_ALL(type, name)
Definition netcdfpp.h:2048
#define NETCDFPP_IMPL_VARIABLE_READ(type, name)
Definition netcdfpp.h:2004
static constexpr bool is_atomic
Definition netcdfpp.h:57
Compound field metadata.
Definition netcdfpp.h:881
nc_type type
NetCDF type id of the field.
Definition netcdfpp.h:883
std::vector< int > dimensions
Array dimensions for array fields; empty for scalar fields.
Definition netcdfpp.h:889
std::size_t offset
Byte offset of the field in the compound type.
Definition netcdfpp.h:887
std::string name
Field name.
Definition netcdfpp.h:885
RAII wrapper for one NetCDF variable-length value returned by the C API.
Definition netcdfpp.h:1006
const T * data
Pointer to the allocated element data.
Definition netcdfpp.h:1010
~VLenElement()
Definition netcdfpp.h:1013
const std::size_t size
Number of elements.
Definition netcdfpp.h:1008
VLenElement()
Definition netcdfpp.h:1012
Definition netcdfpp.h:237
Definition netcdfpp.h:219
std::string name
Definition netcdfpp.h:220
int id
Definition netcdfpp.h:221
bool is_group
Definition netcdfpp.h:222
std::shared_ptr< Path > parent
Definition netcdfpp.h:223
std::string get_full_path() const
Definition netcdfpp.h:225