diff --git a/externals/nitro/externals/coda-oss/modules/c++/sys/include/sys/ByteSwap.h b/externals/nitro/externals/coda-oss/modules/c++/sys/include/sys/ByteSwap.h
deleted file mode 100644
index 67fd4f167..000000000
--- a/externals/nitro/externals/coda-oss/modules/c++/sys/include/sys/ByteSwap.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/* =========================================================================
- * This file is part of sys-c++
- * =========================================================================
- *
- * (C) Copyright 2004 - 2014, MDA Information Systems LLC
- * (C) Copyright 2023, Maxar Technologies, Inc.
- *
- * sys-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 .
- *
- */
-
-#pragma once
-#ifndef CODA_OSS_sys_ByteSwap_h_INCLUDED_
-#define CODA_OSS_sys_ByteSwap_h_INCLUDED_
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include "config/Exports.h"
-
-#include "ByteSwapValue.h"
-#include "Runnable.h"
-#include "SysInt.h"
-
-namespace sys
-{
-/*!
- * Swap bytes in-place. Note that a complex pixel
- * is equivalent to two floats so elemSize and numElems
- * must be adjusted accordingly.
- *
- * \param [inout] buffer to transform
- * \param elemSize
- * \param numElems
- */
-coda_oss::span CODA_OSS_API byteSwap(coda_oss::spanbuffer, size_t elemSize);
-void CODA_OSS_API byteSwap(void* buffer, size_t elemSize, size_t numElems);
-
-// If the caller has given us bytes, assume she knows what she's doing; i.e., don't check sizeof(T)
-template
-inline void byteSwap_(TByte* buffer, size_t elemSize, size_t numElems)
-{
- void* const buffer_ = buffer;
- byteSwap(buffer_, elemSize, numElems);
-}
-inline void byteSwap(coda_oss::byte* buffer, size_t elemSize, size_t numElems)
-{
- return byteSwap_(buffer, elemSize, numElems);
-}
-inline void byteSwap(byte* buffer, size_t elemSize, size_t numElems)
-{
- return byteSwap_(buffer, elemSize, numElems);
-}
-inline void byteSwap(ubyte* buffer, size_t elemSize, size_t numElems)
-{
- return byteSwap_(buffer, elemSize, numElems);
-}
-
-namespace details
-{
-template
-inline void check_elemSize(size_t elemSize)
-{
- static_assert(is_byte_swappable(), "T should not be a 'struct'");
- if (sizeof(T) != elemSize)
- {
- throw std::invalid_argument("'elemSize' != sizeof(T)");
- }
-}
-
-// Repackage into a span; the size is 2* because for byte-swapping
-// we want to look at this as an array of `T`, not `std::complex`.
-template
-inline auto make_span(coda_oss::span> s)
-{
- static_assert(std::is_floating_point::value, "std::complex should use floating-point");
-
- const void* const p_ = s.data();
- auto const p = static_cast(p_);
- const auto sz = s.size() * 2; // real and imag
- return sys::make_span(p, sz);
-}
-template
-inline auto make_span(coda_oss::span> s)
-{
- static_assert(std::is_floating_point::value, "std::complex should use floating-point");
-
- void* const p_ = s.data();
- auto const p = static_cast(p_);
- const auto sz = s.size() * 2; // real and imag
- return sys::make_span(p, sz);
-}
-
-}
-
-// Otherwise, we can sanity-check the `elemSize` parameter
-template
-inline void byteSwap(T* buffer, size_t elemSize, size_t numElems)
-{
- details::check_elemSize(elemSize);
- void* const buffer_ = buffer;
- byteSwap(buffer_, elemSize, numElems);
-}
-template
-inline void byteSwap(std::complex* buffer, size_t elemSize, size_t numElems) // dont't want `T` as `std::complex<...>`
-{
- static_assert(std::is_floating_point::value, "std::complex should use floating-point");
-
- details::check_elemSize(elemSize);
- void* const buffer_ = buffer;
- byteSwap(buffer_, elemSize, numElems);
-}
-
-template
-inline auto byteSwap(coda_oss::span buffer)
-{
- static_assert(!std::is_const::value, "T cannot be 'const'");
- static_assert(details::is_byte_swappable(), "T should not be a 'struct'");
- return byteSwap(as_writable_bytes(buffer), sizeof(T));
-}
-
-// Take care of treating std::complex as T[]
-template
-inline auto byteSwap(coda_oss::span> buffer)
-{
- return byteSwap(details::make_span(buffer));
-}
-
-/*!
- * Swap bytes into output buffer. Note that a complex pixel
- * is equivalent to two floats so elemSize and numElems
- * must be adjusted accordingly.
- *
- * \param buffer to transform
- * \param elemSize
- * \param numElems
- * \param[out] outputBuffer buffer to write swapped elements to
- */
-coda_oss::span CODA_OSS_API byteSwap(coda_oss::span buffer,
- size_t elemSize, coda_oss::span outputBuffer);
-void CODA_OSS_API byteSwap(const void* buffer, size_t elemSize, size_t numElems, void* outputBuffer);
-
-// If the caller has given us bytes, assume she knows what she's doing; i.e., don't check sizeof(T)
-template
-inline void byteSwap_(const TByte* buffer, size_t elemSize, size_t numElems, U* outputBuffer)
-{
- const void* const buffer_ = buffer;
- void* const outputBuffer_ = outputBuffer;
- byteSwap(buffer_, elemSize, numElems, outputBuffer_);
-}
-template
-inline void byteSwap(const coda_oss::byte* buffer, size_t elemSize, size_t numElems, U* outputBuffer)
-{
- byteSwap_(buffer, elemSize, numElems, outputBuffer);
-}
-template
-inline void byteSwap(const byte* buffer, size_t elemSize, size_t numElems, U* outputBuffer)
-{
- byteSwap_(buffer, elemSize, numElems, outputBuffer);
-}
-template
-inline void byteSwap(const ubyte* buffer, size_t elemSize, size_t numElems, U* outputBuffer)
-{
- byteSwap_(buffer, elemSize, numElems, outputBuffer);
-}
-
-// Otherwise, we can sanity-check the `elemSize` parameter
-template
-inline void byteSwap(const T* buffer, size_t elemSize, size_t numElems, U* outputBuffer)
-{
- details::check_elemSize(elemSize);
- const void* const buffer_ = buffer;
- void* const outputBuffer_ = outputBuffer;
- byteSwap(buffer_, elemSize, numElems, outputBuffer_);
-}
-template
-inline void byteSwap(const std::complex* buffer, size_t elemSize, size_t numElems, U* outputBuffer) // dont't want `T` as `std::complex<...>`
-{
- static_assert(std::is_floating_point::value, "std::complex should use floating-point");
-
- details::check_elemSize(elemSize);
- const void* const buffer_ = buffer;
- void* const outputBuffer_ = outputBuffer;
- byteSwap(buffer_, elemSize, numElems, outputBuffer_);
-}
-
-template
-inline auto byteSwap(coda_oss::span buffer, coda_oss::span outputBuffer)
-{
- static_assert(details::is_byte_swappable(), "T should not be a 'struct'");
- return byteSwap(as_bytes(buffer), sizeof(T), outputBuffer);
-}
-// Take care of treating std::complex as T[]
-template
-inline auto byteSwap(coda_oss::span> buffer, coda_oss::span outputBuffer)
-{
- return byteSwap(details::make_span(buffer), outputBuffer);
-}
-
-template
-inline auto byteSwap(coda_oss::span buffer)
-{
- std::vector retval(buffer.size_bytes());
- std::ignore = byteSwap(buffer, make_span(retval));
- return retval;
-}
-// Take care of treating std::complex as T[]
-template
-inline auto byteSwap(coda_oss::span> buffer)
-{
- return byteSwap(details::make_span(buffer));
-}
-
-// With buffer byte-swap now in place, we can safely byte-swap std::complex.
-// This signature is from ByteSwapValue.h
-template
-inline auto byteSwapValue(std::complex z)
-{
- static_assert(std::is_floating_point::value, "std::complex should use floating-point");
-
- // C++ mandates that `std::complex` be the same as `T cx[2]`; that is
- // the structure is contiguous. https://en.cppreference.com/w/cpp/numeric/complex
- const auto& z_ = reinterpret_cast(z);
- return byteSwap(make_span(z_));
-}
-template
-inline auto byteSwap(std::complex val)
-{
- const auto bytes = byteSwapValue(val);
- assert(bytes.size() == sizeof(val));
-
- const void* const pBytes = bytes.data();
- auto const pRetVal = static_cast*>(pBytes);
- return *pRetVal;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-struct ByteSwapRunnable final : public sys::Runnable
-{
- ByteSwapRunnable(void* buffer, size_t elemSize, size_t startElement, size_t numElements) noexcept :
- mBuffer(static_cast(buffer) + startElement * elemSize),
- mElemSize(elemSize), mNumElements(numElements)
- {
- }
- void run() override
- {
- byteSwap(mBuffer, mElemSize, mNumElements);
- }
-
- virtual ~ByteSwapRunnable() = default;
- ByteSwapRunnable(const ByteSwapRunnable&) = delete;
- ByteSwapRunnable& operator=(const ByteSwapRunnable&) = delete;
- ByteSwapRunnable(ByteSwapRunnable&&) = delete;
- ByteSwapRunnable& operator=(ByteSwapRunnable&&) = delete;
-
-private:
- void* const mBuffer;
- const size_t mElemSize;
- const size_t mNumElements;
-};
-
-struct ByteSwapCopyRunnable final : public sys::Runnable
-{
- ByteSwapCopyRunnable(const void* buffer, size_t elemSize, size_t startElement, size_t numElements, void* outputBuffer) noexcept :
- mBuffer(static_cast(buffer) + startElement * elemSize),
- mElemSize(elemSize), mNumElements(numElements),
- mOutputBuffer(static_cast(outputBuffer) + startElement * elemSize)
- {
- }
- void run() override
- {
- byteSwap(mBuffer, mElemSize, mNumElements, mOutputBuffer);
- }
-
- virtual ~ByteSwapCopyRunnable() = default;
- ByteSwapCopyRunnable(const ByteSwapCopyRunnable&) = delete;
- ByteSwapCopyRunnable& operator=(const ByteSwapCopyRunnable&) = delete;
- ByteSwapCopyRunnable(ByteSwapCopyRunnable&&) = delete;
- ByteSwapCopyRunnable& operator=(ByteSwapCopyRunnable&&) = delete;
-
-private:
- const void* const mBuffer;
- const size_t mElemSize;
- const size_t mNumElements;
- void* const mOutputBuffer;
-};
-
-}
-#endif // CODA_OSS_sys_ByteSwap_h_INCLUDED_
diff --git a/externals/nitro/externals/coda-oss/modules/c++/sys/unittests/test_byte_swap.cpp b/externals/nitro/externals/coda-oss/modules/c++/sys/unittests/test_byte_swap.cpp
deleted file mode 100644
index 2d784428b..000000000
--- a/externals/nitro/externals/coda-oss/modules/c++/sys/unittests/test_byte_swap.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-/* =========================================================================
- * This file is part of sys-c++
- * =========================================================================
- *
- * (C) Copyright 2004 - 2017, MDA Information Systems LLC
- *
- * sys-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 "TestCase.h"
-
-#include
-#include
-#include // std::endian
-#include
-#include
-#include
-
-#include
-#include
-
-TEST_CASE(testEndianness)
-{
- /*const*/ auto native = std::endian::native; // "const" causes "conditional expression is constant."
-
- if (native == std::endian::big) { }
- else if (native == std::endian::little) { }
- else
- {
- TEST_FAIL_MSG("Mixed-endian not supported!");
- }
-
- const bool isBigEndianSystem = sys::isBigEndianSystem();
-
- if (native == std::endian::big)
- {
- TEST_ASSERT(isBigEndianSystem);
- }
- else
- {
- TEST_ASSERT(!isBigEndianSystem);
- }
- if (native == std::endian::little)
- {
- TEST_ASSERT(!isBigEndianSystem);
- }
- else
- {
- TEST_ASSERT(isBigEndianSystem);
- }
-
-
- if (isBigEndianSystem)
- {
- TEST_ASSERT(native == std::endian::big);
- }
- else
- {
- TEST_ASSERT(native == std::endian::little);
- }
-}
-
-template
-static std::vector make_origValues(size_t NUM_PIXELS)
-{
- ::srand(334);
-
- std::vector retval(NUM_PIXELS);
- for (size_t ii = 0; ii < NUM_PIXELS; ++ii)
- {
- const auto value = static_cast(::rand()) / RAND_MAX *
- std::numeric_limits::max();
- retval[ii] = static_cast(value);
- }
- return retval;
-}
-
-TEST_CASE(testByteSwapV)
-{
- constexpr size_t NUM_PIXELS = 10000;
- const auto origValues = make_origValues (NUM_PIXELS);
-
- // Byte swap the old-fashioned way
- auto values1(origValues);
- sys::byteSwap(values1.data(), sizeof(uint64_t), NUM_PIXELS);
-
- // Byte swap into output buffer
- std::vector swappedValues2(origValues.size());
- sys::byteSwap(origValues.data(), sizeof(uint64_t), NUM_PIXELS, swappedValues2.data());
-
- // Everything should match
- for (size_t ii = 0; ii < NUM_PIXELS; ++ii)
- {
- TEST_ASSERT_EQ(values1[ii], swappedValues2[ii]);
- }
-}
-
-TEST_CASE(testByteSwapCxV)
-{
- constexpr size_t NUM_PIXELS = 10000;
- using value_type = std::complex;
- const auto origValues = make_origValues(NUM_PIXELS);
-
- constexpr auto elemSize = sizeof(value_type) / 2;
- constexpr auto numElems = NUM_PIXELS * 2;
-
- // Byte swap the old-fashioned way
- auto values1(origValues);
- sys::byteSwap(values1.data(), elemSize, numElems);
-
- // Byte swap into output buffer
- std::vector swappedValues2(origValues.size());
- sys::byteSwap(origValues.data(), elemSize, numElems, swappedValues2.data());
-
- // Everything should match
- for (size_t ii = 0; ii < NUM_PIXELS; ++ii)
- {
- using int_type = uint64_t;
- static_assert(sizeof(int_type) == sizeof(value_type), "Unknown sizeof(std::complex)");
-
- // If these values are byte-swapped, they could be bogus.
- const void* const pValue1_ = &(values1[ii]);
- const void* const pSwappedValue2_ = &(swappedValues2[ii]);
-
- auto const pValue1 = static_cast(pValue1_);
- auto const pSwappedValue2 = static_cast(pSwappedValue2_);
-
- TEST_ASSERT_EQ(*pValue1, *pSwappedValue2);
- }
-}
-
-template
-inline std::span as_span(const std::vector& bytes)
-{
- const void* const pBytes_ = bytes.data();
- auto const p = static_cast(pBytes_);
- const auto sz = bytes.size() / sizeof(T);
- return sys::make_span(p, sz);
-}
-
-TEST_CASE(testByteSwap)
-{
- constexpr size_t NUM_PIXELS = 10000;
- const auto origValues = make_origValues(NUM_PIXELS);
- const auto origValues_ = sys::make_span(origValues);
-
- auto values1(origValues);
- sys::byteSwap(sys::make_span(values1));
-
- // Byte swap into output buffer
- std::vector swappedValues2(origValues.size());
- sys::byteSwap(origValues_, sys::as_writable_bytes(swappedValues2));
-
- // std::vector returned
- const auto swappedValues3_ = sys::byteSwap(origValues_);
- const auto swappedValues3 = as_span(swappedValues3_);
-
- // Everything should match
- for (size_t ii = 0; ii < NUM_PIXELS; ++ii)
- {
- TEST_ASSERT_EQ(values1[ii], swappedValues2[ii]);
- TEST_ASSERT_EQ(values1[ii], swappedValues3[ii]);
- }
-}
-
-// 0xnn is an `int` which can't be used to initialize std::byte w/o a cast
-#define CODA_OSS_define_byte(v) constexpr static std::byte v = static_cast(0 ## v)
-CODA_OSS_define_byte(x00);
-CODA_OSS_define_byte(x11);
-CODA_OSS_define_byte(x22);
-CODA_OSS_define_byte(x33);
-CODA_OSS_define_byte(x44);
-CODA_OSS_define_byte(x55);
-CODA_OSS_define_byte(x66);
-CODA_OSS_define_byte(x77);
-CODA_OSS_define_byte(x88);
-CODA_OSS_define_byte(x99);
-CODA_OSS_define_byte(xAA);
-CODA_OSS_define_byte(xBB);
-CODA_OSS_define_byte(xCC);
-CODA_OSS_define_byte(xDD);
-CODA_OSS_define_byte(xEE);
-CODA_OSS_define_byte(xFF);
-#undef CODA_OSS_define_byte
-
-static constexpr std::byte two_bytes[]{x00, xFF};
-static constexpr std::byte four_bytes[]{x00, x11, xEE, xFF};
-static constexpr std::byte eight_bytes[]{x00, x11, x22, x33, xCC, xDD, xEE, xFF};
-static constexpr std::byte sixteen_bytes[]{x00, x11, x22, x33, x44, x55, x66, x77, x88, x99, xAA, xBB, xCC, xDD, xEE, xFF};
-
-template
-static void test_assert_eq_swapped(const std::string& testName, size_t sz,
- const TByteSpanLike1& pValueBytes, const TByteSpanLike2& pResultBytes)
-{
- for (size_t i = 0, j = sz; i < sz && j > 0; i++, j--)
- {
- TEST_ASSERT(pResultBytes[i] == pValueBytes[j - 1]);
- }
-}
-
-template
-static void testByteSwapValues_(const std::string& testName, const void* pBytes)
-{
- auto pUInt = static_cast(pBytes);
- auto swap = sys::byteSwap(*pUInt);
- TEST_ASSERT_NOT_EQ(*pUInt, swap);
-
- const void* pResult_ = &swap;
- auto const pResultBytes = static_cast(pResult_);
- auto const pValueBytes = static_cast(pBytes);
- test_assert_eq_swapped(testName, sizeof(TUInt), pResultBytes, pValueBytes);
-
- swap = sys::byteSwap(swap); // swap back
- TEST_ASSERT_EQ(*pUInt, swap);
-
- // swap as an "array" of one value
- sys::byteSwap(pUInt, sizeof(TUInt), 1, &swap);
- TEST_ASSERT_NOT_EQ(*pUInt, swap);
- sys::byteSwap(&swap, sizeof(TUInt), 1); // swap back
- TEST_ASSERT_EQ(*pUInt, swap);
-
- const auto resultBytes = sys::byteSwapValue(*pUInt);
- TEST_ASSERT_EQ(resultBytes.size(), sizeof(TUInt));
- test_assert_eq_swapped(testName, sizeof(TUInt), resultBytes.data(), pValueBytes);
-}
-TEST_CASE(testByteSwapValues)
-{
- testByteSwapValues_(testName, two_bytes);
- testByteSwapValues_(testName, four_bytes);
- testByteSwapValues_(testName, eight_bytes);
-}
-
-TEST_CASE(testByteSwapCxValue)
-{
- using value_type = std::complex;
- const value_type cx{3.14f, -31.4f}; // using raw bytes can lean to `nan`s
- auto const pValue = &cx;
-
- auto swap = sys::byteSwap(*pValue);
- TEST_ASSERT_NOT_EQ(*pValue, swap); // technically a bit goofy as the bits may not represent `T`s
-
- swap = sys::byteSwap(swap); // swap back
- TEST_ASSERT_EQ(*pValue, swap);
-}
-
-TEST_CASE(testByteSwap12)
-{
- // test a goofy element size
- constexpr std::byte twelve_bytes[]{
- x00, x11, x22, x33, x44, x55,
- x99, xAA, xBB, xDD, xEE, xFF};
- const auto pValueBytes = sys::as_bytes(twelve_bytes);
- constexpr auto extent_twelve_bytes = std::extent::value;
-
- std::vector swappedValues(extent_twelve_bytes);
- auto pResultBytes = sys::make_span(swappedValues);
-
- auto elemSize = 12;
- auto numElements = swappedValues.size() / elemSize;
- sys::byteSwap(twelve_bytes, elemSize, numElements, pResultBytes.data());
- test_assert_eq_swapped(testName, elemSize, pResultBytes, pValueBytes);
-
- // swap as a SINGLE 12-byte value
- const auto result = sys::details::swapBytes(pValueBytes, pResultBytes);
- test_assert_eq_swapped(testName, elemSize, result, pValueBytes);
-
- elemSize = 6; // note that an ODD size doesn't work correctly
- numElements = swappedValues.size() / elemSize;
- sys::byteSwap(twelve_bytes, elemSize, numElements, swappedValues.data());
- test_assert_eq_swapped(testName, elemSize, &(pResultBytes[0]), &(pValueBytes[0]));
- test_assert_eq_swapped(testName, elemSize, &(pResultBytes[6]), &(pValueBytes[6]));
-
- sys::byteSwap(swappedValues.data(), elemSize, numElements); // swap back
- for (size_t i = 0; i < swappedValues.size(); i++)
- {
- TEST_ASSERT(pResultBytes[i] == pValueBytes[i]);
- }
-}
-
-template
-static inline void six_byteSwap(const void* in, T& out)
-{
- auto const inBytes = sys::make_span(in, sizeof(T));
- out = sys::byteSwapValue(inBytes);
-}
-TEST_CASE(testSixByteSwap)
-{
- const int i = 123;
- int i_swapped;
- six_byteSwap(&i, i_swapped);
- TEST_ASSERT_NOT_EQ(i, i_swapped);
-
- int result;
- six_byteSwap(&i_swapped, result);
- TEST_ASSERT_EQ(i, result);
-}
-
-TEST_MAIN(
- TEST_CHECK(testEndianness);
- TEST_CHECK(testByteSwapV);
- TEST_CHECK(testByteSwapCxV);
- TEST_CHECK(testByteSwap);
- TEST_CHECK(testByteSwapValues);
- TEST_CHECK(testByteSwapCxValue);
- TEST_CHECK(testByteSwap12);
- TEST_CHECK(testSixByteSwap);
- )
diff --git a/externals/nitro/externals/coda-oss/modules/c++/types/include/types/Complex.h b/externals/nitro/externals/coda-oss/modules/c++/types/include/types/Complex.h
deleted file mode 100644
index cefa90a83..000000000
--- a/externals/nitro/externals/coda-oss/modules/c++/types/include/types/Complex.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/* =========================================================================
- * This file is part of types-c++
- * =========================================================================
- *
- * (C) Copyright 2004 - 2014, MDA Information Systems LLC
- * (C) Copyright 2023, Maxar Technologies, Inc.
- *
- * types-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 .
- *
- */
-
-#pragma once
-#ifndef CODA_OSS_types_Complex_h_INCLUDED_
-#define CODA_OSS_types_Complex_h_INCLUDED_
-
-#include
-
-#include
-#include
-#include
-
-#include "config/disable_compiler_warnings.h"
-#include "coda_oss/CPlusPlus.h"
-
-namespace types
-{
-/*!
- * \class Complex
- * \brief Our own implementation of std::complex for SIX and friends.
- *
- * `std::complex` is no longer valid C++; provide a (partial) work-around.
- * See https://en.cppreference.com/w/cpp/numeric/complex for details.
- *
- * SIX (and others) mostly use `std::complex` as a convenient
- * package for two values; very little "complex math" is done using integers.
- */
-template
-struct Complex final
-{
- using value_type = T;
- static_assert(!std::is_floating_point::value, "Use std::complex for floating-point.");
- static_assert(std::is_signed::value, "T should be a signed integer.");
-
- Complex(value_type re = 0, value_type im = 0) : z{re, im} { }
- Complex(const Complex&) = default;
- Complex& operator=(const Complex&) = default;
- Complex(Complex&&) = default;
- Complex& operator=(Complex&&) = default;
- ~Complex() = default;
-
- // If someone already has a std::complex, is there any harm in creating ours?
- Complex(const std::complex& other) : Complex(other.real(), other.imag()) { }
- Complex& operator=(const std::complex& other)
- {
- real(other.real());
- imag(other.imag());
- return *this;
- }
-
- #if defined(CODA_OSS_types_Complex_implicit_cast) || defined(_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING)
- CODA_OSS_disable_warning_push
- #ifdef _MSC_VER
- #pragma warning(disable : 4996) // '...': warning STL4037: The effect of instantiating the template std::complex for any type other than float, double, or long double is unspecified. You can define _SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING to suppress this warning.
- #endif
- // Better interop with existing code? Creates ambiguities?
- operator const std::complex&() const
- {
- const void* const pThis = this;
- return *static_cast*>(pThis);
- }
- operator std::complex&()
- {
- void* const pThis = this;
- return *static_cast*>(pThis);
- }
- CODA_OSS_disable_warning_pop
- #endif // CODA_OSS_types_Complex_implicit_cast || _SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING
-
- value_type real() const
- {
- return z[0];
- }
- void real(value_type value)
- {
- z[0] = value;
- }
-
- value_type imag() const
- {
- return z[1];
- }
- void imag(value_type value)
- {
- z[1] = value;
- }
-
-private:
- value_type z[2]{0, 0};
-};
-
-namespace details
-{
-CODA_OSS_disable_warning_push
-#ifdef _MSC_VER
-#pragma warning(disable : 4996) // '...': warning STL4037: The effect of instantiating the template std::complex for any type other than float, double, or long double is unspecified. You can define _SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING to suppress this warning.
-#endif
-// Getting different results with GCC vs MSVC :-( So just use
-// std::complex Assume by the time we're actually using C++23 with a
-// compiler that enforces this restriction, "something" will be different.
-template
-inline const std::complex& cast(const Complex& z)
-{
- const void* const pZ_ = &z;
- return *static_cast*>(pZ_);
-}
-template
-inline std::complex& cast(Complex& z)
-{
- void* const pZ_ = &z;
- return *static_cast*>(pZ_);
-}
-CODA_OSS_disable_warning_pop
-}
-
-// https://en.cppreference.com/w/cpp/numeric/complex/operator_ltltgtgt
-template
-inline auto& operator<<(std::basic_ostream& o, const Complex& z)
-{
- return o << details::cast(z);
-}
-template
-inline auto& operator>>(std::basic_istream& o, Complex& z)
-{
- return o >> details::cast(z);
-}
-
-// https://en.cppreference.com/w/cpp/numeric/complex/operator_cmp
-template
-inline bool operator==(const Complex& lhs, const Complex& rhs)
-{
- return (lhs.real() == rhs.real()) && (lhs.imag() == rhs.imag());
-}
-template
-inline bool operator!=(const Complex& lhs, const Complex& rhs)
-{
- return !(lhs == rhs);
-}
-
-// Keep functions like abs() to a minimum; complex math probably shouldn't be done with integers.
-template
-inline auto abs(const Complex& z) // https://en.cppreference.com/w/cpp/numeric/complex/abs
-{
- return abs(details::cast(z));
-}
-
-template
-using ComplexInteger = Complex;
-
-namespace details
-{
-// This circumlocution is to prevent clients from doing `ComplexReal`.
-// (And also to use the word "circumlocution." :-) )
-template struct ComplexReal
-{
- static_assert(std::is_floating_point::value, "T must be floating-point.");
- using type = std::complex;
-};
-} // namespace details
-template
-using ComplexReal = typename details::ComplexReal::type;
-
-// This might be more trouble than it's worth: there really isn't that much code
-// that is generic for both integer and real complex types; recall that the primary
-// use of `std::complex` is a "convenient package" for two values.
-//
-//Have the compiler pick between std::complex and Complex
-//template
-//using complex = std::conditional_t::value, ComplexReal, ComplexInteger>;
-static_assert(sizeof(std::complex) == sizeof(Complex), "sizeof(sizeof(std::complex) != sizeof(Complex)");
-static_assert(std::is_same, ComplexReal>::value, "should be std::complex");
-
-// Convenient aliases
-using zfloat = ComplexReal; // i.e., std::complex
-using zdouble = ComplexReal; // i.e., std::complex
-//using zlong_double = ComplexReal; // i.e., std::complex
-using zint8_t = ComplexInteger; // Complex
-using zint16_t = ComplexInteger; // Complex
-using zint32_t = ComplexInteger; // Complex
-using zint64_t = ComplexInteger; // Complex
-}
-
-#endif // CODA_OSS_types_Complex_h_INCLUDED_