diff --git a/copy_externals.csh b/copy_externals.csh index 0f5b0fd28..1674c143d 100755 --- a/copy_externals.csh +++ b/copy_externals.csh @@ -1,7 +1,7 @@ #!/bin/csh -f rm -r -f tmp && mkdir tmp && cd tmp -git clone -b main git@github.com:mdaus/coda-oss.git +git clone --depth 1 -b main git@github.com:mdaus/coda-oss.git rm -r -f coda-oss/.git cd .. diff --git a/externals/coda-oss/.gitignore b/externals/coda-oss/.gitignore index e1ff9db15..7489cb720 100644 --- a/externals/coda-oss/.gitignore +++ b/externals/coda-oss/.gitignore @@ -2,8 +2,8 @@ *~ *.pyc __pycache__/ -# Build artifacts +# Build artifacts install/ install-*/ target/ @@ -20,6 +20,7 @@ CMakeFiles/ Makefile modules/**/Makefile out/ +CMakeSettings.json # Waf .waf-* @@ -51,4 +52,5 @@ project.sln **/x64/ *.vcxproj.user -CMakeSettings.json +# Unit-tests +TEST_*_TMP.* diff --git a/externals/coda-oss/build/build.py b/externals/coda-oss/build/build.py index 847e0e8fd..516a0ee9b 100644 --- a/externals/coda-oss/build/build.py +++ b/externals/coda-oss/build/build.py @@ -891,12 +891,6 @@ def configureCompilerOptions(self): # If you want the plugins to not depend on Intel libraries, # configure with: # --with-cflags=-static-intel --with-cxxflags=-static-intel --with-linkflags=-static-intel - if cxxCompiler == 'gcc': - config['cxx']['debug'] = '-ggdb3' - config['cxx']['optz_debug'] = '-Og' - elif cxxCompiler == 'icpc': - config['cxx']['debug'] = '-g' - config['cxx']['optz_debug'] = '' if cxxCompiler == 'g++' or cxxCompiler == 'icpc': config['cxx']['warn'] = warningFlags.split() config['cxx']['verbose'] = '-v' @@ -931,12 +925,21 @@ def configureCompilerOptions(self): self.env.append_value('LINKFLAGS', linkFlags.split()) - if ccCompiler == 'gcc': - config['cc']['debug'] = '-ggdb3' - config['cc']['optz_debug'] = '-Og' - elif ccCompiler == 'icc': - config['cc']['debug'] = '-g' - config['cc']['optz_debug'] = '' + if Options.options.debugging: + if cxxCompiler == 'g++': + config['cxx']['debug'] = '-ggdb3' + config['cxx']['optz_debug'] = '-Og' + elif cxxCompiler == 'icpc': + config['cxx']['debug'] = '-g' + config['cxx']['optz_debug'] = '' + + if ccCompiler == 'gcc': + config['cc']['debug'] = '-ggdb3' + config['cc']['optz_debug'] = '-Og' + elif ccCompiler == 'icc': + config['cc']['debug'] = '-g' + config['cc']['optz_debug'] = '' + if ccCompiler == 'gcc' or ccCompiler == 'icc': config['cc']['warn'] = warningFlags.split() config['cc']['verbose'] = '-v' diff --git a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/CPlusPlus.h b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/CPlusPlus.h index 388cb8fd5..f28d64236 100644 --- a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/CPlusPlus.h +++ b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/CPlusPlus.h @@ -53,16 +53,6 @@ #endif // __INTEL_COMPILER #endif // CODA_OSS_cplusplus -#if CODA_OSS_cplusplus < 201402L - // oops ... try to fix - #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER_BUILD_DATE >= 20151021) - // __cplusplus is 201300, not 201402L - // Enough C++14, at least with our std/ work-arounds - #undef CODA_OSS_cplusplus - #define CODA_OSS_cplusplus 201402L - #endif -#endif // CODA_OSS_cplusplus - #if CODA_OSS_cplusplus < 202002L // oops ... try to fix #if defined(__GNUC__) && (__cplusplus >= 201709L) // note > C++ 17 of 201703L diff --git a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/optional_.h b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/optional_.h index 9ce2bf2ef..c321b5b70 100644 --- a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/optional_.h +++ b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/optional_.h @@ -63,27 +63,21 @@ class optional final using value_type = T; #if defined(_MSC_VER) && _PREFAST_ // Visual Studio /analyze - __pragma(warning(push)) __pragma(warning( - disable : 26495)) // Variable '...' is uninitialized. Always - // initialize a member variable(type.6). + __pragma(warning(push)) __pragma(warning(disable : 26495)) // Variable '...' is uninitialized. Always initialize a member variable(type.6). #endif - optional() noexcept + optional() noexcept { } #if defined(_MSC_VER) && _PREFAST_ __pragma(warning(pop)) #endif - optional(const value_type& v) : - value_(v), has_value_(true) + optional(const value_type& v) : value_(v), has_value_(true) { } #if defined(_MSC_VER) && _PREFAST_ // Visual Studio /analyze - __pragma(warning(push)) __pragma(warning( - disable : 26495)) // Variable '...' is uninitialized. Always - // initialize a member variable(type.6). + __pragma(warning(push)) __pragma(warning(disable : 26495)) // Variable '...' is uninitialized. Always initialize a member variable(type.6). #endif - optional(const optional& other) : - has_value_(other.has_value_) + optional(const optional& other) : has_value_(other.has_value_) { if (has_value()) { @@ -94,18 +88,15 @@ class optional final __pragma(warning(pop)) #endif - template < - typename... Args> // https://en.cppreference.com/w/cpp/utility/Optional/emplace - T& emplace(Args&&... args) + template // https://en.cppreference.com/w/cpp/utility/Optional/emplace + T& emplace(Args&&... args) { value_ = value_type(std::forward(args)...); has_value_ = true; return value_; } - template < - typename U = - T> // https://en.cppreference.com/w/cpp/utility/optional/operator%3D + template // https://en.cppreference.com/w/cpp/utility/optional/operator%3D optional& operator=(U&& value) noexcept { value_ = std::forward(value); @@ -163,11 +154,10 @@ class optional final // contains a value!" } - const T& operator*() const& + const T& operator*() const& noexcept { assert(has_value()); - return value_; // "This operator does not check whether the optional - // contains a value!" + return value_; // "This operator does not check whether the optional contains a value!" } T& operator*() & { diff --git a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/type_traits.h b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/type_traits.h index 5bd920a91..5c92c1d32 100644 --- a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/type_traits.h +++ b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/type_traits.h @@ -29,21 +29,7 @@ #include "coda_oss/namespace_.h" namespace coda_oss { -// workaround missing "is_trivially_copyable" in g++ < 5.0 -// https://stackoverflow.com/a/31798726/8877 -#if defined(__GNUC__) && (__GNUC__ < 5) -template -struct is_trivially_copyable final -{ - // This old Intel compiler has enough C++14 for our needs; see CPlusPlus.h - #if !(defined(__INTEL_COMPILER) && (__INTEL_COMPILER_BUILD_DATE <= 20151021)) - static_assert(CODA_OSS_cplusplus < 201402L, "C++14 must have is_trivially_copyable."); - #endif - static constexpr bool value = __has_trivial_copy(T); -}; -#else using std::is_trivially_copyable; -#endif } #endif // CODA_OSS_coda_oss_type_traits_h_INCLUDED_ diff --git a/externals/coda-oss/modules/c++/except/include/except/Backtrace.h b/externals/coda-oss/modules/c++/except/include/except/Backtrace.h index 697889526..42cf6ba6a 100644 --- a/externals/coda-oss/modules/c++/except/include/except/Backtrace.h +++ b/externals/coda-oss/modules/c++/except/include/except/Backtrace.h @@ -42,6 +42,7 @@ namespace version { namespace except { #if _MSC_VER #pragma warning(push) +#pragma warning(disable: 4619) // #pragma warning: there is no warning number '...' #pragma warning(disable: 5264) // '...': '...' variable is not used #endif // _MSC_VER diff --git a/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/Read.h b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/Read.h index ed57dd12b..09a8502ee 100644 --- a/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/Read.h +++ b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/Read.h @@ -28,7 +28,7 @@ * \file Read.h * \brief HDF File-reading API * - * These are simple routines to read HDF5 files; they're loosly modeled after the MATLab API + * These are simple routines to read HDF5 files; they're loosely modeled after the MATLab API * https://www.mathworks.com/help/matlab/import_export/import-hdf5-files.html */ @@ -39,16 +39,17 @@ #include "sys/filesystem.h" #include "types/RowCol.h" +#include "SpanRC.h" + namespace hdf5 { namespace lite { -CODA_OSS_API types::RowCol readFile(const coda_oss::filesystem::path&, const std::string& loc, std::vector&); -CODA_OSS_API types::RowCol readFile(const coda_oss::filesystem::path&, const std::string& loc, std::vector&); +CODA_OSS_API SpanRC readFile(const coda_oss::filesystem::path&, const std::string& loc, std::vector&); +CODA_OSS_API SpanRC readFile(const coda_oss::filesystem::path&, const std::string& loc, std::vector&); } } #endif // CODA_OSS_hdf5_lite_Read_h_INCLUDED_ - diff --git a/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h new file mode 100644 index 000000000..7d6582124 --- /dev/null +++ b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h @@ -0,0 +1,115 @@ +/* ========================================================================= + * This file is part of hdf5.lite-c++ + * ========================================================================= + * + * (C) Copyright 2022, Maxar Technologies, Inc. + * + * hdf5.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef CODA_OSS_hdf5_lite_SpanRC_h_INCLUDED_ +#define CODA_OSS_hdf5_lite_SpanRC_h_INCLUDED_ +#pragma once + +/*! + * \file SpanRC.h + * + * This is a super-simple version of C++23's mdspan. It's here because 1) don't want widespread use, and + * 2) CODA already has a View2D. + */ + +#include + +#include "config/Exports.h" +#include "coda_oss/span.h" +#include "types/RowCol.h" + +namespace hdf5 +{ +namespace lite +{ + +template +struct SpanRC final +{ + using size_type = types::RowCol; + using element_type = T; + using pointer = T*; + using reference = T&; + + SpanRC() = default; + SpanRC(pointer p, size_type rc) noexcept : s_(p, rc.area()), rc_(rc) + { + } + SpanRC(pointer p, size_t r, size_t c) noexcept : SpanRC(p, size_type(r, c)) + { + } + SpanRC(const SpanRC&) noexcept = default; + + constexpr pointer data() const noexcept + { + return s_.data(); + } + + /*constexpr*/ reference operator[](size_t idx) const noexcept + { + assert(idx < size()); // prevents "constexpr" in C++11 + return data()[idx]; + } + /*constexpr*/ reference operator()(size_t r, size_t c) const noexcept + { + const auto offset = (r * dims().col) + c; + return (*this)[offset]; + } + /*constexpr*/ reference operator[](size_type idx) const noexcept + { + return (*this)(idx.row, idx.col); + } + + constexpr size_t size() const noexcept + { + assert(s_.size() == rc_.area()); + return s_.size(); + } + constexpr size_t area() const noexcept + { + return size(); + } + + constexpr size_type size_bytes() const noexcept + { + return s_.size_bytes(); + } + + constexpr bool empty() const noexcept + { + return s_.empty(); + } + + const auto& dims() const + { + return rc_; + } + + private: + types::RowCol rc_; + coda_oss::span s_; +}; + +} +} + +#endif // CODA_OSS_hdf5_lite_SpanRC_h_INCLUDED_ diff --git a/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/Write.h b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/Write.h new file mode 100644 index 000000000..3a0e4c7c2 --- /dev/null +++ b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/Write.h @@ -0,0 +1,80 @@ +/* ========================================================================= + * This file is part of hdf5.lite-c++ + * ========================================================================= + * + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * hdf5.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef CODA_OSS_hdf5_lite_Write_h_INCLUDED_ +#define CODA_OSS_hdf5_lite_Write_h_INCLUDED_ +#pragma once + +/*! + * \file Read.h + * \brief HDF File-reading API + * + * These are simple routines to write HDF5 files; they're loosely modeled after the MATLab API + * https://www.mathworks.com/help/matlab/ref/h5create.html + * https://www.mathworks.com/help/matlab/ref/h5write.html + */ + +#include +#include + +#include "config/Exports.h" +#include "sys/filesystem.h" +#include "types/RowCol.h" + +#include "SpanRC.h" + +namespace hdf5 +{ +namespace lite +{ +template // currently implemented for float and double +CODA_OSS_API void createFile(const coda_oss::filesystem::path&, const std::string& ds, const types::RowCol&); +CODA_OSS_API void createFile(const coda_oss::filesystem::path&, const std::string& ds, SpanRC); +inline void createFile(const coda_oss::filesystem::path& path, const std::string& ds, SpanRC data_) +{ + SpanRC data(data_.data(), data_.dims()); + createFile(path, ds, data); +} +CODA_OSS_API void createFile(const coda_oss::filesystem::path&, const std::string& ds, SpanRC); +inline void createFile(const coda_oss::filesystem::path& path, const std::string& ds, SpanRC data_) +{ + SpanRC data(data_.data(), data_.dims()); + createFile(path, ds, data); +} + +CODA_OSS_API void writeFile(const coda_oss::filesystem::path&, const std::string& loc, SpanRC); +inline void writeFile(const coda_oss::filesystem::path& path, const std::string& ds, SpanRC data_) +{ + SpanRC data(data_.data(), data_.dims()); + writeFile(path, ds, data); +} +CODA_OSS_API void writeFile(const coda_oss::filesystem::path&, const std::string& loc, SpanRC); +inline void writeFile(const coda_oss::filesystem::path& path, const std::string& ds, SpanRC data_) +{ + SpanRC data(data_.data(), data_.dims()); + writeFile(path, ds, data); +} + +} +} + +#endif // CODA_OSS_hdf5_lite_Write_h_INCLUDED_ diff --git a/externals/coda-oss/modules/c++/hdf5.lite/source/Read.cpp b/externals/coda-oss/modules/c++/hdf5.lite/source/Read.cpp index c4f567658..325111a4f 100644 --- a/externals/coda-oss/modules/c++/hdf5.lite/source/Read.cpp +++ b/externals/coda-oss/modules/c++/hdf5.lite/source/Read.cpp @@ -56,7 +56,7 @@ static void read(const H5::DataSet& dataset, std::vector& result) dataset.read(result.data(), mem_type); } template -static types::RowCol readDatasetT(const H5::DataSet& dataset, std::vector& result) +static hdf5::lite::SpanRC readDatasetT(const H5::DataSet& dataset, std::vector& result) { if (dataset.getTypeClass() != H5T_FLOAT) { @@ -64,8 +64,9 @@ static types::RowCol readDatasetT(const H5::DataSet& dataset, std::vecto throw hdf5::lite::DataSetException(context); } - const auto retval = hdf5::lite::details::getSimpleExtentSize(dataset); - result.resize(retval.area()); + const auto dims = hdf5::lite::details::getSimpleExtentSize(dataset); + result.resize(dims.area()); + hdf5::lite::SpanRC retval(result.data(), dims); // dataset.read() doesn't care about the buffer type ... that's because H5Dread() also // uses void*. However, the LT API has H5LTread_dataset_double() and H5LTread_dataset_float(), @@ -74,16 +75,16 @@ static types::RowCol readDatasetT(const H5::DataSet& dataset, std::vecto return retval; } -inline types::RowCol readDataset_(const H5::DataSet& dataset, std::vector& result) +inline hdf5::lite::SpanRC readDataset_(const H5::DataSet& dataset, std::vector& result) { return readDatasetT(dataset, result); } -inline types::RowCol readDataset_(const H5::DataSet& dataset, std::vector& result) +inline hdf5::lite::SpanRC readDataset_(const H5::DataSet& dataset, std::vector& result) { return readDatasetT(dataset, result); } template -static types::RowCol readFile_(const coda_oss::filesystem::path& fileName, const std::string& datasetName, +static hdf5::lite::SpanRC readFile_(const coda_oss::filesystem::path& fileName, const std::string& datasetName, std::vector& result) { /* @@ -94,12 +95,12 @@ static types::RowCol readFile_(const coda_oss::filesystem::path& fileNam return readDataset_(dataset, result); } -types::RowCol hdf5::lite::readFile(const coda_oss::filesystem::path& fileName, const std::string& loc, +hdf5::lite::SpanRC hdf5::lite::readFile(const coda_oss::filesystem::path& fileName, const std::string& loc, std::vector& result) { return details::try_catch_H5Exceptions(readFile_, __FILE__, __LINE__, fileName, loc, result); } -types::RowCol hdf5::lite::readFile(const coda_oss::filesystem::path& fileName, const std::string& loc, +hdf5::lite::SpanRC hdf5::lite::readFile(const coda_oss::filesystem::path& fileName, const std::string& loc, std::vector& result) { return details::try_catch_H5Exceptions(readFile_, __FILE__, __LINE__, fileName, loc, result); diff --git a/externals/coda-oss/modules/c++/hdf5.lite/source/Write.cpp b/externals/coda-oss/modules/c++/hdf5.lite/source/Write.cpp new file mode 100644 index 000000000..ce140935a --- /dev/null +++ b/externals/coda-oss/modules/c++/hdf5.lite/source/Write.cpp @@ -0,0 +1,115 @@ +/* ========================================================================= + * This file is part of hd5.lite-c++ + * ========================================================================= + * + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * hd5.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include "hdf5/lite/Write.h" + +#include // std::ignore +#include + +#include "coda_oss/cstddef.h" // byte + +#include "hdf5/lite/HDF5Exception.h" +#include "H5.h" +#include "hdf5.lite.h" + +// https://raw.githubusercontent.com/HDFGroup/hdf5/develop/c++/examples/h5tutr_rdwt.cpp + +template static H5::PredType getPredType(); +template <> +inline H5::PredType getPredType() +{ + static_assert(sizeof(float) * 8 == 32, "'float' should be 32-bits"); // IEEE_F32LE + return H5::PredType::IEEE_F32LE; +} +template <> +inline H5::PredType getPredType() +{ + static_assert(sizeof(double) * 8 == 64, "'double' should be 64-bits"); // IEEE_F64LE + return H5::PredType::IEEE_F64LE; +} + +template +static void createFile_(const coda_oss::filesystem::path& fileName, const std::string& ds, const types::RowCol& sz) +{ + // https://raw.githubusercontent.com/HDFGroup/hdf5/develop/c++/examples/h5tutr_crtdat.cpp + // + // Create a new file using the default property lists. + H5::H5File file(fileName.string(), H5F_ACC_TRUNC); + + // Create the data space for the dataset. + constexpr int RANK = 2; + const hsize_t dims[]{sz.row, sz.col}; // dataset dimensions + H5::DataSpace dataspace(RANK, dims); + + // Create the dataset. + const auto data_type = getPredType(); + std::ignore = file.createDataSet(ds, data_type, dataspace); +} +template<> +void hdf5::lite::createFile(const coda_oss::filesystem::path& fileName, const std::string& ds, const types::RowCol& sz) +{ + details::try_catch_H5ExceptionsV(createFile_, __FILE__, __LINE__, fileName, ds, sz); +} +template<> +void hdf5::lite::createFile(const coda_oss::filesystem::path& fileName, const std::string& ds, const types::RowCol& sz) +{ + details::try_catch_H5ExceptionsV(createFile_, __FILE__, __LINE__, fileName, ds, sz); +} +void hdf5::lite::createFile(const coda_oss::filesystem::path& fileName, const std::string& ds, hdf5::lite::SpanRC data) +{ + createFile(fileName, ds, data.dims()); +} +void hdf5::lite::createFile(const coda_oss::filesystem::path& fileName, const std::string& ds, hdf5::lite::SpanRC data) +{ + createFile(fileName, ds, data.dims()); +} + + +template +static void writeFile_(const coda_oss::filesystem::path& fileName, const std::string& ds, hdf5::lite::SpanRC data) +{ + // https://raw.githubusercontent.com/HDFGroup/hdf5/develop/c++/examples/h5tutr_rdwt.cpp + + // Open an existing file and dataset. + H5::H5File file(fileName.string(), H5F_ACC_RDWR); + auto dataset = file.openDataSet(ds); + + const auto dims = hdf5::lite::details::getSimpleExtentSize(dataset); + if (data.dims() != dims) + { + const except::Context ctx("dataSet dimensions do not match data dimensions", __FILE__, __LINE__, "writeFile"); + throw hdf5::lite::DataSetException(ctx); + } + + // Write the data to the dataset using default memory space, file + // space, and transfer properties. + const auto data_type = getPredType(); + dataset.write(data.data(), data_type); +} +void hdf5::lite::writeFile(const coda_oss::filesystem::path& fileName, const std::string& ds, SpanRC data) +{ + details::try_catch_H5ExceptionsV(writeFile_, __FILE__, __LINE__, fileName, ds, data); +} +void hdf5::lite::writeFile(const coda_oss::filesystem::path& fileName, const std::string& ds, SpanRC data) +{ + details::try_catch_H5ExceptionsV(writeFile_, __FILE__, __LINE__, fileName, ds, data); +} diff --git a/externals/coda-oss/modules/c++/hdf5.lite/source/hdf5.lite.h b/externals/coda-oss/modules/c++/hdf5.lite/source/hdf5.lite.h index 709cc784c..fce6fb7c0 100644 --- a/externals/coda-oss/modules/c++/hdf5.lite/source/hdf5.lite.h +++ b/externals/coda-oss/modules/c++/hdf5.lite/source/hdf5.lite.h @@ -60,6 +60,13 @@ auto try_catch_H5Exceptions(TFunc f, const char* file, int line, TArgs&&... args details::try_catch_H5Exceptions_(call_f, file, line, &retval /*context*/); return retval; } +template +auto try_catch_H5ExceptionsV(TFunc f, const char* file, int line, TArgs&&... args) +{ + // "Hide" the arguments inside of a lambda + auto call_f = [&](void*) { f(std::forward(args)...); }; + details::try_catch_H5Exceptions_(call_f, file, line, nullptr /*context*/); +} } } diff --git a/externals/coda-oss/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp b/externals/coda-oss/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp new file mode 100644 index 000000000..0d99d1105 --- /dev/null +++ b/externals/coda-oss/modules/c++/hdf5.lite/unittests/test_hdf5write.cpp @@ -0,0 +1,93 @@ +/* ========================================================================= + * This file is part of hdf5.lite-c++ + * ========================================================================= + * + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * hdf5.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include +#include +#include + +#include + +#include "sys/FileFinder.h" + +#include "hdf5/lite/Write.h" +#include "hdf5/lite/HDF5Exception.h" +#include "hdf5/lite/Info.h" +#include "hdf5/lite/Read.h" + +static std::filesystem::path find_unittest_file(const std::filesystem::path& name) +{ + static const auto unittests = std::filesystem::path("modules") / "c++" / "hdf5.lite" / "unittests"; + return sys::test::findGITModuleFile("coda-oss", unittests, name); +} + +TEST_CASE(test_hdf5Create) +{ + static const auto path_ = find_unittest_file("example.h5"); + static const auto path = path_.parent_path() / "TEST_hdf5Create_TMP.h5"; + + // https://www.mathworks.com/help/matlab/ref/h5write.html + hdf5::lite::createFile(path, "/DS1", {10, 20}); +} + +TEST_CASE(test_hdf5Write) +{ + static const auto path_ = find_unittest_file("example.h5"); + static const auto path = path_.parent_path() / "TEST_hdf5Write_TMP.h5"; + + const types::RowCol dims{10, 20}; + std::vector data_(dims.area()); + const hdf5::lite::SpanRC data(data_.data(), dims); + double d = 0.0; + for (size_t r = 0; r result; + const auto rc = hdf5::lite::readFile(path, "/DS1", result); + TEST_ASSERT(rc.dims() == dims); + TEST_ASSERT_EQ(dims.area(), result.size()); + for (size_t i = 0; i < result.size(); i++) + { + const auto expected = static_cast(i); + TEST_ASSERT_ALMOST_EQ(result[i], expected); + } +} + +TEST_MAIN( + TEST_CHECK(test_hdf5Create); + TEST_CHECK(test_hdf5Write); +) diff --git a/externals/coda-oss/modules/c++/str/include/str/EncodedStringView.h b/externals/coda-oss/modules/c++/str/include/str/EncodedStringView.h index 38beb310b..1fd1e99ac 100644 --- a/externals/coda-oss/modules/c++/str/include/str/EncodedStringView.h +++ b/externals/coda-oss/modules/c++/str/include/str/EncodedStringView.h @@ -110,7 +110,7 @@ class CODA_OSS_API EncodedStringView final std::wstring wstring() const; // UTF-16 on Windows, UTF-32 on Linux // These are for "advanced" use, most "normal" code should use the routines above. - std::string::const_pointer c_str() const + std::string::const_pointer c_str() const noexcept { return mString.data(); } @@ -122,7 +122,7 @@ class CODA_OSS_API EncodedStringView final { return mIsUtf8 ? nullptr : cast(c_str()); } - size_t size() const + size_t size() const noexcept { return mString.size(); } diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Attributes.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Attributes.h index 17c40e410..8b354844b 100644 --- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Attributes.h +++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Attributes.h @@ -31,6 +31,7 @@ #include "except/Exception.h" #include "xml/lite/QName.h" #include "str/Convert.h" +#include "gsl/gsl.h" /*! * \file Attributes.h @@ -330,7 +331,7 @@ struct Attributes final } std::string operator[](const xml::lite::QName& name) const { - const size_t idx = getIndex(name); + const auto idx = gsl::narrow(getIndex(name)); return mAttributes[idx].getValue(); } @@ -348,7 +349,7 @@ struct Attributes final } std::string operator[](const std::string& s) const { - const size_t idx = getIndex(s); + const auto idx = gsl::narrow(getIndex(s)); return mAttributes[idx].getValue(); } diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Document.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Document.h index e61422d30..1d53fdbab 100644 --- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Document.h +++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Document.h @@ -104,7 +104,7 @@ struct Document // SOAPDocument derives :-( * \param characterData The character data (if any) * \return A new element */ - Element *createElement(const std::string & qname, const std::string & uri, std::string characterData = ""); + virtual Element *createElement(const std::string & qname, const std::string & uri, std::string characterData = ""); #ifndef SWIG // SWIG doesn't like std::unique_ptr std::unique_ptr createElement(const xml::lite::QName&, const std::string& characterData) const; std::unique_ptr createElement(const xml::lite::QName&, const coda_oss::u8string& characterData) const; diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h index dc2cb3939..8942aaf57 100644 --- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h +++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h @@ -120,8 +120,8 @@ class ValidatorXerces : public ValidatorInterface ValidatorXerces(const ValidatorXerces&) = delete; ValidatorXerces& operator=(const ValidatorXerces&) = delete; - ValidatorXerces(ValidatorXerces&&) = delete; - ValidatorXerces& operator=(ValidatorXerces&&) = delete; + ValidatorXerces(ValidatorXerces&&) = default; + ValidatorXerces& operator=(ValidatorXerces&&) = default; using ValidatorInterface::validate; diff --git a/externals/coda-oss/modules/c++/xml.lite/unittests/test_soapelements.cpp b/externals/coda-oss/modules/c++/xml.lite/unittests/test_soapelements.cpp new file mode 100644 index 000000000..21ecbfdd8 --- /dev/null +++ b/externals/coda-oss/modules/c++/xml.lite/unittests/test_soapelements.cpp @@ -0,0 +1,65 @@ +/* ========================================================================= + * This file is part of xml.lite-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * (C) Copyright 2023, Maxar Technologies, Inc. + * + * xml.lite-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include "xml/lite/Document.h" +#include "xml/lite/Element.h" +#include "xml/lite/QName.h" +static const std::string test_text = "SOAP Test"; + +struct SOAPBody final : public xml::lite::Element +{ + SOAPBody() = default; + SOAPBody (const xml::lite::QName& qname) + { + setQName(qname); + } +}; + +struct SOAP final : public xml::lite::Document +{ + xml::lite::Element* createElement(const std::string & qname, + const std::string& uri, + std::string characterData = "") override { + const xml::lite::QName asQName(uri, qname); + xml::lite::Element* elem = new SOAPBody(asQName); + elem->setCharacterData(test_text); + return elem; + } +}; + +TEST_CASE(test_overrideCreateElement) +{ + SOAP soap_test; + auto a = soap_test.createElement("a","b","Not SOAP Test"); + auto b = dynamic_cast(a); + TEST_ASSERT_NOT_NULL(b); + TEST_ASSERT_EQ(a->getCharacterData(), test_text); + TEST_ASSERT_EQ(b->getCharacterData(), test_text); +} + +TEST_MAIN +( + TEST_CHECK(test_overrideCreateElement); +) + diff --git a/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlattribute.cpp b/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlattribute.cpp index f94a13653..011bb79d1 100644 --- a/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlattribute.cpp +++ b/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlattribute.cpp @@ -1,10 +1,10 @@ /* ========================================================================= - * This file is part of io-c++ + * This file is part of xml.lite-c++ * ========================================================================= * * (C) Copyright 2004 - 2019, MDA Information Systems LLC * - * io-c++ is free software; you can redistribute it and/or modify + * xml.lite-c++ is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. diff --git a/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlelement.cpp b/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlelement.cpp index ccbdde0a7..a9890ab00 100644 --- a/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlelement.cpp +++ b/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlelement.cpp @@ -1,10 +1,10 @@ /* ========================================================================= - * This file is part of io-c++ + * This file is part of xml.lite-c++ * ========================================================================= * * (C) Copyright 2004 - 2019, MDA Information Systems LLC * - * io-c++ is free software; you can redistribute it and/or modify + * xml.lite-c++ is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. diff --git a/modules/c++/cpp.h b/modules/c++/cpp.h index f3e3960da..931c7632d 100644 --- a/modules/c++/cpp.h +++ b/modules/c++/cpp.h @@ -1,6 +1,8 @@ #pragma once #pragma warning(push) +#pragma warning(disable: 4619) // #pragma warning: there is no warning number '...' + #pragma warning(disable: 4668) // '...' is not defined as a preprocessor macro, replacing with '...' for '...' #pragma warning(disable: 4820) // '...': '...' bytes padding added after data member '...' #pragma warning(disable: 4710) // '...': function not inlined @@ -16,6 +18,7 @@ #pragma warning(disable: 5027) // '...': move assignment operator was implicitly defined as deleted #pragma warning(disable: 5219) // implicit conversion from '...' to '...', possible loss of data #pragma warning(disable: 6285) // ( || ) is always a non-zero constant. Did you intend to use the bitwise-and operator? +#pragma warning(disable: 5264) // '...': '...' variable is not used #define _USE_MATH_DEFINES #include diff --git a/modules/c++/nitf/include/nitf/Object.hpp b/modules/c++/nitf/include/nitf/Object.hpp index 7b5c1eb68..3a264b0c4 100644 --- a/modules/c++/nitf/include/nitf/Object.hpp +++ b/modules/c++/nitf/include/nitf/Object.hpp @@ -208,8 +208,9 @@ class NITRO_NITFCPP_API Object * corresponding nitf_##_destruct method. */ +// Don't need both "override" and "final": https://learn.microsoft.com/en-us/cpp/code-quality/c26435?view=msvc-170 #define DECLARE_CLASS_IN_operator_function_(Name_, Package_) \ -void operator()(Package_##_##Name_ * nativeObject) NITRO_nitf_MemoryDestructor_noexcept_false_ override final \ +void operator()(Package_##_##Name_ * nativeObject) NITRO_nitf_MemoryDestructor_noexcept_false_ final \ { Package_##_##Name_##_destruct(&nativeObject); } #ifdef _MSC_VER diff --git a/modules/c++/pch.h b/modules/c++/pch.h index 03f81a187..a969486e3 100644 --- a/modules/c++/pch.h +++ b/modules/c++/pch.h @@ -1,9 +1,11 @@ #pragma once +#pragma warning(disable: 4619) // #pragma warning: there is no warning number '...' #pragma warning(disable: 4820) // '...': '...' bytes padding added after data member '...' #pragma warning(disable: 4710) // '...': function not inlined #pragma warning(disable: 5045) // Compiler will insert Spectre mitigation for memory load if / Qspectre switch specified #pragma warning(disable: 4668) // '...' is not defined as a preprocessor macro, replacing with '...' for '...' +#pragma warning(disable: 5264) // '...': '...' variable is not used // TODO: get rid of these someday? #pragma warning(disable: 4514) // '...': unreferenced inline function has been removed #pragma warning(disable: 26823) // Dereferencing a possibly null pointer '...' (lifetime.1).