diff options
-rw-r--r-- | include/jau/basic_types.hpp | 237 | ||||
-rw-r--r-- | include/jau/darray.hpp | 22 | ||||
-rw-r--r-- | include/jau/jni/helper_jni.hpp | 12 | ||||
-rw-r--r-- | include/jau/jni/jni_mem.hpp | 1 | ||||
-rw-r--r-- | include/jau/math/geom/frustum.hpp | 2 | ||||
-rw-r--r-- | include/jau/math/mat4f.hpp | 4 | ||||
-rw-r--r-- | include/jau/math/math_error.hpp | 105 | ||||
-rw-r--r-- | include/jau/math/util/pmvmat4f.hpp | 12 | ||||
-rw-r--r-- | include/jau/ringbuffer.hpp | 2 | ||||
-rw-r--r-- | java_jni/jni/helper_jni.cxx | 48 | ||||
-rw-r--r-- | java_jni/jni/jau/ByteInStream_Feed.cxx | 24 | ||||
-rw-r--r-- | java_jni/jni/jau/ByteInStream_File.cxx | 12 | ||||
-rw-r--r-- | java_jni/jni/jau/ByteInStream_URL.cxx | 12 | ||||
-rw-r--r-- | java_jni/jni/jau/ByteOutStream_File.cxx | 10 | ||||
-rw-r--r-- | java_jni/jni/jau/jau_fs_FileUtil.cxx | 4 | ||||
-rw-r--r-- | java_jni/jni/jau/jau_sys_Clock.cxx | 8 | ||||
-rw-r--r-- | java_jni/jni/jni_mem.cxx | 10 | ||||
-rw-r--r-- | src/basic_types.cpp | 13 | ||||
-rw-r--r-- | src/eui48.cpp | 4 | ||||
-rw-r--r-- | src/uuid.cpp | 18 | ||||
-rw-r--r-- | test/test_big_int01.hpp | 2 | ||||
-rw-r--r-- | test/test_exceptions01.cpp | 264 |
22 files changed, 632 insertions, 194 deletions
diff --git a/include/jau/basic_types.hpp b/include/jau/basic_types.hpp index 85a9883..493492b 100644 --- a/include/jau/basic_types.hpp +++ b/include/jau/basic_types.hpp @@ -26,12 +26,13 @@ #define JAU_BASIC_TYPES_HPP_ #include <cstring> +#include <ios> +#include <ratio> +#include <stdexcept> #include <string> -#include <memory> #include <cstdint> -#include <vector> -#include <type_traits> #include <iostream> +#include <system_error> #include <jau/cpp_lang_util.hpp> #include <jau/packed_attribute.hpp> @@ -306,50 +307,98 @@ namespace jau { class ExceptionBase { private: + // brief message std::string msg_; + // optional whole backtrace std::string backtrace_; + // brief message + optional whole backtrace std::string what_; - protected: - ExceptionBase(std::string type, std::string const& m, const char* file, int line) noexcept; + protected: + ExceptionBase(const std::string &type, std::string const& m, const char* file, int line) noexcept; public: virtual ~ExceptionBase() noexcept = default; - ExceptionBase(const ExceptionBase &o) = default; ExceptionBase(ExceptionBase &&o) = default; ExceptionBase& operator=(const ExceptionBase &o) = default; ExceptionBase& operator=(ExceptionBase &&o) = default; - const std::string& message() const noexcept { return msg_; } + /** Returns brief message. */ + const std::string& brief_message() const noexcept { return msg_; } + /** Returns optional whole backtrace. */ const std::string& backtrace() const noexcept { return backtrace_; } - - /** Allow conversion to `const std::string&`, as required by Catch2's `REQUIRE_THROWS_MATCHES` */ - operator const std::string& () const noexcept { return message(); }; - - virtual const char* what() const noexcept { - return what_.c_str(); // return std::runtime_error::what(); - } + /** Returns brief message and optional whole backtrace, i.e. std::exception::what() string. */ + const std::string& whole_message() const noexcept { return what_; } + + /** Allow conversion to `const std::string&` using brief_message(), as required by Catch2's `REQUIRE_THROWS_MATCHES` */ + operator const std::string& () const noexcept { return brief_message(); }; std::ostream& operator<<(std::ostream& out) noexcept { return out << what_; } + + virtual const char* what() const noexcept { + return whole_message().c_str(); + } + }; + class RuntimeExceptionBase : public ExceptionBase { + protected: + RuntimeExceptionBase(const std::string &type, std::string const& m, const char* file, int line) noexcept + : ExceptionBase(type, m, file, line) {} + + public: + ~RuntimeExceptionBase() noexcept override = default; + + RuntimeExceptionBase(const RuntimeExceptionBase& o) = default; + RuntimeExceptionBase(RuntimeExceptionBase&& o) = default; + RuntimeExceptionBase& operator=(const RuntimeExceptionBase& o) = default; + RuntimeExceptionBase& operator=(RuntimeExceptionBase&& o) = default; }; + class LogicErrorBase : public ExceptionBase { + protected: + LogicErrorBase(const std::string &type, std::string const& m, const char* file, int line) noexcept + : ExceptionBase(type, m, file, line) {} - class OutOfMemoryError : public std::bad_alloc, public ExceptionBase { public: - OutOfMemoryError(std::string const& m, const char* file, int line) - : bad_alloc(), ExceptionBase("OutOfMemoryError", m, file, line) {} + ~LogicErrorBase() noexcept override = default; + + LogicErrorBase(const LogicErrorBase& o) = default; + LogicErrorBase(LogicErrorBase&& o) = default; + LogicErrorBase& operator=(const LogicErrorBase& o) = default; + LogicErrorBase& operator=(LogicErrorBase&& o) = default; + }; + class RuntimeSystemExceptionBase : public RuntimeExceptionBase { + protected: + std::error_code m_ec; + RuntimeSystemExceptionBase(const std::string &type, const std::error_code& ec, std::string const& m, const char* file, int line) noexcept + : RuntimeExceptionBase(type, m, file, line), m_ec(ec) {} + + public: + ~RuntimeSystemExceptionBase() noexcept override = default; + RuntimeSystemExceptionBase(const RuntimeSystemExceptionBase& o) = default; + RuntimeSystemExceptionBase(RuntimeSystemExceptionBase&& o) = default; + RuntimeSystemExceptionBase& operator=(const RuntimeSystemExceptionBase& o) = default; + RuntimeSystemExceptionBase& operator=(RuntimeSystemExceptionBase&& o) = default; + + const std::error_code& code() const noexcept { return m_ec; } + }; + + class OutOfMemoryError : public ExceptionBase, public std::bad_alloc { + public: + OutOfMemoryError(std::string const& m, const char* file, int line) + : ExceptionBase("OutOfMemoryError", m, file, line), bad_alloc() {} + const char* what() const noexcept override { - return ExceptionBase::what(); // return std::runtime_error::what(); + return whole_message().c_str(); } }; - - class RuntimeException : public std::exception, public ExceptionBase { + + class RuntimeException : public RuntimeExceptionBase, public std::runtime_error { protected: - RuntimeException(std::string type, std::string const& m, const char* file, int line) noexcept - : exception(), ExceptionBase(std::move(type), m, file, line) {} + RuntimeException(const std::string &type, std::string const& m, const char* file, int line) noexcept + : RuntimeExceptionBase(type, m, file, line), runtime_error(whole_message()) {} public: RuntimeException(std::string const& m, const char* file, int line) noexcept @@ -361,66 +410,134 @@ namespace jau { RuntimeException(RuntimeException&& o) = default; RuntimeException& operator=(const RuntimeException& o) = default; RuntimeException& operator=(RuntimeException&& o) = default; + + // base class std::exception: + const char* what() const noexcept override { + return whole_message().c_str(); + } + }; + class LogicError : public LogicErrorBase, public std::logic_error { + protected: + LogicError(const std::string &type, std::string const& m, const char* file, int line) noexcept + : LogicErrorBase(type, m, file, line), logic_error(whole_message()) {} + + public: + LogicError(std::string const& m, const char* file, int line) noexcept + : LogicError("LogicErrorStd", m, file, line) {} + + ~LogicError() noexcept override = default; + LogicError(const LogicError& o) = default; + LogicError(LogicError&& o) = default; + LogicError& operator=(const LogicError& o) = default; + LogicError& operator=(LogicError&& o) = default; + const char* what() const noexcept override { - return ExceptionBase::what(); + return whole_message().c_str(); } }; + class RuntimeSystemException : public RuntimeSystemExceptionBase, public std::system_error { + protected: + RuntimeSystemException(const std::string &type, const std::error_code& ec, std::string const& m, const char* file, int line) noexcept + : RuntimeSystemExceptionBase(type, ec, m, file, line), system_error(ec, whole_message()) {} - class InternalError : public RuntimeException { public: - InternalError(std::string const& m, const char* file, int line) noexcept - : RuntimeException("InternalError", m, file, line) {} - }; + RuntimeSystemException(const std::error_code& ec, std::string const& m, const char* file, int line) noexcept + : RuntimeSystemException("RuntimeSystemExceptionStd", ec, m, file, line) {} - class NotImplementedError : public RuntimeException { + ~RuntimeSystemException() noexcept override = default; + + RuntimeSystemException(const RuntimeSystemException& o) = default; + RuntimeSystemException(RuntimeSystemException&& o) = default; + RuntimeSystemException& operator=(const RuntimeSystemException& o) = default; + RuntimeSystemException& operator=(RuntimeSystemException&& o) = default; + + const char* what() const noexcept override { + return whole_message().c_str(); + } + }; + + class IndexOutOfBoundsError : public LogicErrorBase, public std::out_of_range { + protected: + IndexOutOfBoundsError(const char* file, int line, const std::string &type, std::string const& m) noexcept + : LogicErrorBase(type, m, file, line), out_of_range(whole_message()) {} + public: - NotImplementedError(std::string const& m, const char* file, int line) noexcept - : RuntimeException("NotImplementedError", m, file, line) {} + IndexOutOfBoundsError(const std::size_t index, const std::size_t length, const char* file, int line) noexcept + : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index "+std::to_string(index)+", data length "+std::to_string(length)) {} + + IndexOutOfBoundsError(const std::string& index_s, const std::string& length_s, const char* file, int line) noexcept + : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index "+index_s+", data length "+length_s) {} + + IndexOutOfBoundsError(const std::size_t index, const std::size_t count, const std::size_t length, const char* file, int line) noexcept + : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index "+std::to_string(index)+", count "+std::to_string(count)+", data length "+std::to_string(length)) {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; - class NullPointerException : public RuntimeException { + class IllegalArgumentError : public LogicErrorBase, public std::invalid_argument { + protected: + IllegalArgumentError(std::string const& type, std::string const& m, const char* file, int line) noexcept + : LogicErrorBase(type, m, file, line), invalid_argument(whole_message()) {} + public: - NullPointerException(std::string const& m, const char* file, int line) noexcept - : RuntimeException("NullPointerException", m, file, line) {} + IllegalArgumentError(std::string const& m, const char* file, int line) noexcept + : IllegalArgumentError("IllegalArgumentError", m, file, line) {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; - class IllegalArgumentException : public RuntimeException { + class IllegalStateError : public LogicErrorBase, public std::domain_error { + protected: + IllegalStateError(std::string const& type, std::string const& m, const char* file, int line) noexcept + : LogicErrorBase(type, m, file, line), domain_error(whole_message()) {} + public: - IllegalArgumentException(std::string const& m, const char* file, int line) noexcept - : RuntimeException("IllegalArgumentException", m, file, line) {} + IllegalStateError(std::string const& m, const char* file, int line) noexcept + : IllegalStateError("IllegalStateError", m, file, line) {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; - class IllegalStateException : public RuntimeException { + class IOError : public RuntimeSystemExceptionBase, public std::ios_base::failure { public: - IllegalStateException(std::string const& m, const char* file, int line) noexcept - : RuntimeException("IllegalStateException", m, file, line) {} + IOError(std::string const& m, const char* file, int line, const std::error_code& ec = std::io_errc::stream) noexcept + : RuntimeSystemExceptionBase("IOError", ec, m, file, line), failure(whole_message(), ec) {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; - class UnsupportedOperationException : public RuntimeException { + class InternalError : public RuntimeException { public: - UnsupportedOperationException(std::string const& m, const char* file, int line) noexcept - : RuntimeException("UnsupportedOperationException", m, file, line) {} + InternalError(std::string const& m, const char* file, int line) noexcept + : RuntimeException("InternalError", m, file, line) {} }; - class IndexOutOfBoundsException : public RuntimeException { + class NotImplementedException : public RuntimeException { public: - IndexOutOfBoundsException(const std::size_t index, const std::size_t length, const char* file, int line) noexcept - : RuntimeException("IndexOutOfBoundsException", "Index "+std::to_string(index)+", data length "+std::to_string(length), file, line) {} - - IndexOutOfBoundsException(const std::string& index_s, const std::string& length_s, const char* file, int line) noexcept - : RuntimeException("IndexOutOfBoundsException", "Index "+index_s+", data length "+length_s, file, line) {} - - IndexOutOfBoundsException(const std::size_t index, const std::size_t count, const std::size_t length, const char* file, int line) noexcept - : RuntimeException("IndexOutOfBoundsException", "Index "+std::to_string(index)+", count "+std::to_string(count)+", data length "+std::to_string(length), file, line) {} + NotImplementedException(std::string const& m, const char* file, int line) noexcept + : RuntimeException("NotImplementedException", m, file, line) {} }; - class IOError : public RuntimeException { + class NullPointerException : public RuntimeException { public: - IOError(std::string const& m, const char* file, int line) noexcept - : RuntimeException("IOError", m, file, line) {} + NullPointerException(std::string const& m, const char* file, int line) noexcept + : RuntimeException("NullPointerException", m, file, line) {} }; + class UnsupportedOperationException : public RuntimeException { + public: + UnsupportedOperationException(std::string const& m, const char* file, int line) noexcept + : RuntimeException("UnsupportedOperationException", m, file, line) {} + }; /** // ************************************************* @@ -436,42 +553,42 @@ namespace jau { inline void set_bit_uint32(const uint8_t nr, uint32_t &mask) { using namespace jau::int_literals; - if( nr > 31 ) { throw IndexOutOfBoundsException(nr, 32, E_FILE_LINE); } + if( nr > 31 ) { throw IndexOutOfBoundsError(nr, 32, E_FILE_LINE); } mask |= 1_u32 << (nr & 31); } inline void clear_bit_uint32(const uint8_t nr, uint32_t &mask) { using namespace jau::int_literals; - if( nr > 31 ) { throw IndexOutOfBoundsException(nr, 32, E_FILE_LINE); } + if( nr > 31 ) { throw IndexOutOfBoundsError(nr, 32, E_FILE_LINE); } mask |= ~(1_u32 << (nr & 31)); } inline uint32_t test_bit_uint32(const uint8_t nr, const uint32_t mask) { using namespace jau::int_literals; - if( nr > 31 ) { throw IndexOutOfBoundsException(nr, 32, E_FILE_LINE); } + if( nr > 31 ) { throw IndexOutOfBoundsError(nr, 32, E_FILE_LINE); } return mask & (1_u32 << (nr & 31)); } inline void set_bit_uint64(const uint8_t nr, uint64_t &mask) { using namespace jau::int_literals; - if( nr > 63 ) { throw IndexOutOfBoundsException(nr, 64, E_FILE_LINE); } + if( nr > 63 ) { throw IndexOutOfBoundsError(nr, 64, E_FILE_LINE); } mask |= 1_u64 << (nr & 63); } inline void clear_bit_uint64(const uint8_t nr, uint64_t &mask) { using namespace jau::int_literals; - if( nr > 63 ) { throw IndexOutOfBoundsException(nr, 64, E_FILE_LINE); } + if( nr > 63 ) { throw IndexOutOfBoundsError(nr, 64, E_FILE_LINE); } mask |= ~(1_u64 << (nr & 63)); } inline uint64_t test_bit_uint64(const uint8_t nr, const uint64_t mask) { using namespace jau::int_literals; - if( nr > 63 ) { throw IndexOutOfBoundsException(nr, 64, E_FILE_LINE); } + if( nr > 63 ) { throw IndexOutOfBoundsError(nr, 64, E_FILE_LINE); } return mask & (1_u64 << (nr & 63)); } diff --git a/include/jau/darray.hpp b/include/jau/darray.hpp index 7ad869b..279914a 100644 --- a/include/jau/darray.hpp +++ b/include/jau/darray.hpp @@ -204,7 +204,7 @@ namespace jau { constexpr value_type * allocStore(const size_type size_) { if( 0 != size_ ) { if( size_ > DIFF_MAX ) { - throw jau::IllegalArgumentException("alloc "+std::to_string(size_)+" > difference_type max "+ + throw jau::IllegalArgumentError("alloc "+std::to_string(size_)+" > difference_type max "+ std::to_string(DIFF_MAX), E_FILE_LINE); } value_type * m = alloc_inst.allocate(size_); @@ -327,7 +327,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha constexpr void ctor_copy_range_check(pointer dest, iterator first, const_iterator last) { JAU_DARRAY_PRINTF0("ctor_copy_range_check [%zd .. %zd] -> ??, dist %zd\n", (first-begin_), (last-begin_)-1, (last-first)-1); if( first > last ) { - throw jau::IllegalArgumentException("first "+to_hexstring(first)+" > last "+to_hexstring(last), E_FILE_LINE); + throw jau::IllegalArgumentError("first "+to_hexstring(first)+" > last "+to_hexstring(last), E_FILE_LINE); } for(; first < last; ++dest, ++first) { new (const_cast<pointer_mutable>(dest)) value_type( *first ); // placement new @@ -336,7 +336,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha constexpr pointer clone_range_check(const size_type dest_capacity, iterator first, const_iterator last) { JAU_DARRAY_PRINTF0("clone_range_check [%zd .. %zd], count %zd -> %d\n", (first-begin_), (last-begin_)-1, (last-first)-1, (int)dest_capacity); if( dest_capacity < size_type(last-first) ) { - throw jau::IllegalArgumentException("capacity "+std::to_string(dest_capacity)+" < source range "+ + throw jau::IllegalArgumentError("capacity "+std::to_string(dest_capacity)+" < source range "+ std::to_string(difference_type(last-first)), E_FILE_LINE); } pointer dest = allocStore(dest_capacity); @@ -347,7 +347,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha template< class InputIt > constexpr static void ctor_copy_range_foreign(pointer dest, InputIt first, InputIt last) { if( first > last ) { - throw jau::IllegalArgumentException("first "+jau::to_string( first )+" > last "+ + throw jau::IllegalArgumentError("first "+jau::to_string( first )+" > last "+ jau::to_string( last ), E_FILE_LINE); } for(; first != last; ++dest, ++first) { @@ -357,7 +357,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha template< class InputIt > constexpr pointer clone_range_foreign(const size_type dest_capacity, InputIt first, InputIt last) { if( dest_capacity < size_type(last-first) ) { - throw jau::IllegalArgumentException("capacity "+std::to_string(dest_capacity)+" < source range "+ + throw jau::IllegalArgumentError("capacity "+std::to_string(dest_capacity)+" < source range "+ std::to_string(difference_type(last-first)), E_FILE_LINE); } pointer dest = allocStore(dest_capacity); @@ -803,7 +803,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha if( 0 <= i && i < size() ) { return *(begin_+i); } - throw jau::IndexOutOfBoundsException(i, size(), E_FILE_LINE); + throw jau::IndexOutOfBoundsError(i, size(), E_FILE_LINE); } /** @@ -813,7 +813,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha if( 0 <= i && i < size() ) { return *(begin_+i); } - throw jau::IndexOutOfBoundsException(i, size(), E_FILE_LINE); + throw jau::IndexOutOfBoundsError(i, size(), E_FILE_LINE); } // write access, mutable array operations @@ -997,7 +997,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha return begin_ <= pos && pos <= end_ ? const_cast<iterator>(pos) : end_; } else { - throw jau::IndexOutOfBoundsException(std::to_string(difference_type(pos - begin_)), std::to_string(size()), E_FILE_LINE); + throw jau::IndexOutOfBoundsError(std::to_string(difference_type(pos - begin_)), std::to_string(size()), E_FILE_LINE); } } @@ -1038,7 +1038,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha return begin_ <= pos_new && pos_new <= end_ ? pos_new : end_; } else { - throw jau::IndexOutOfBoundsException(std::to_string(difference_type(pos - begin_)), std::to_string(size()), E_FILE_LINE); + throw jau::IndexOutOfBoundsError(std::to_string(difference_type(pos - begin_)), std::to_string(size()), E_FILE_LINE); } } @@ -1071,7 +1071,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha return begin_ <= pos_new && pos_new <= end_ ? pos_new : end_; } else { - throw jau::IndexOutOfBoundsException(std::to_string(difference_type(pos - begin_)), std::to_string(size()), E_FILE_LINE); + throw jau::IndexOutOfBoundsError(std::to_string(difference_type(pos - begin_)), std::to_string(size()), E_FILE_LINE); } } @@ -1101,7 +1101,7 @@ In copy constructor ‘std::__shared_count<_Lp>::__shared_count(const std::__sha return begin_ <= pos_new && pos_new <= end_ ? pos_new : end_; } else { - throw jau::IndexOutOfBoundsException(std::to_string(difference_type(pos - begin_)), std::to_string(size()), E_FILE_LINE); + throw jau::IndexOutOfBoundsError(std::to_string(difference_type(pos - begin_)), std::to_string(size()), E_FILE_LINE); } } diff --git a/include/jau/jni/helper_jni.hpp b/include/jau/jni/helper_jni.hpp index 0ee3f75..36247cb 100644 --- a/include/jau/jni/helper_jni.hpp +++ b/include/jau/jni/helper_jni.hpp @@ -76,21 +76,23 @@ namespace jau::jni { void java_exception_check_and_throw(JNIEnv *env, const char* file, int line); void print_native_caught_exception_fwd2java(const jau::OutOfMemoryError &e, const char* file, int line); - void print_native_caught_exception_fwd2java(const jau::RuntimeException &e, const char* file, int line); + void print_native_caught_exception_fwd2java(const jau::LogicErrorBase &e, const char* file, int line); + void print_native_caught_exception_fwd2java(const jau::RuntimeExceptionBase &e, const char* file, int line); void print_native_caught_exception_fwd2java(const std::exception &e, const char* file, int line); void print_native_caught_exception_fwd2java(const std::string &msg, const char* file, int line); void print_native_caught_exception_fwd2java(const char * cmsg, const char* file, int line); void raise_java_exception(JNIEnv *env, const std::exception &e, const char* file, int line); void raise_java_exception(JNIEnv *env, const std::runtime_error &e, const char* file, int line); - void raise_java_exception(JNIEnv *env, const jau::RuntimeException &e, const char* file, int line); + void raise_java_exception(JNIEnv *env, const jau::LogicErrorBase &e, const char* file, int line); + void raise_java_exception(JNIEnv *env, const jau::RuntimeExceptionBase &e, const char* file, int line); void raise_java_exception(JNIEnv *env, const jau::InternalError &e, const char* file, int line); void raise_java_exception(JNIEnv *env, const jau::NullPointerException &e, const char* file, int line); - void raise_java_exception(JNIEnv *env, const jau::IllegalArgumentException &e, const char* file, int line); + void raise_java_exception(JNIEnv *env, const jau::IllegalArgumentError &e, const char* file, int line); void raise_java_exception(JNIEnv *env, const std::invalid_argument &e, const char* file, int line); - void raise_java_exception(JNIEnv *env, const jau::IllegalStateException &e, const char* file, int line); + void raise_java_exception(JNIEnv *env, const jau::IllegalStateError &e, const char* file, int line); void raise_java_exception(JNIEnv *env, const jau::UnsupportedOperationException &e, const char* file, int line); - void raise_java_exception(JNIEnv *env, const jau::IndexOutOfBoundsException &e, const char* file, int line); + void raise_java_exception(JNIEnv *env, const jau::IndexOutOfBoundsError &e, const char* file, int line); void raise_java_exception(JNIEnv *env, const std::bad_alloc &e, const char* file, int line); void raise_java_exception(JNIEnv *env, const jau::OutOfMemoryError &e, const char* file, int line); diff --git a/include/jau/jni/jni_mem.hpp b/include/jau/jni/jni_mem.hpp index 5fca3f1..378a42c 100644 --- a/include/jau/jni/jni_mem.hpp +++ b/include/jau/jni/jni_mem.hpp @@ -30,7 +30,6 @@ #define JAU_JNIMEM__HPP_ #include <jni.h> -#include <stdexcept> #include <mutex> #include <jau/basic_types.hpp> diff --git a/include/jau/math/geom/frustum.hpp b/include/jau/math/geom/frustum.hpp index d6452fa..e516efb 100644 --- a/include/jau/math/geom/frustum.hpp +++ b/include/jau/math/geom/frustum.hpp @@ -127,7 +127,7 @@ class Frustum { : fovhv(fovhv_), zNear(zNear_), zFar(zFar_) { if( zNear <= 0.0f || zFar <= zNear ) { - throw IllegalArgumentException("Requirements zNear > 0 and zFar > zNear, but zNear "+std::to_string(zNear)+", zFar "+std::to_string(zFar), E_FILE_LINE); + throw IllegalArgumentError("Requirements zNear > 0 and zFar > zNear, but zNear "+std::to_string(zNear)+", zFar "+std::to_string(zFar), E_FILE_LINE); } } diff --git a/include/jau/math/mat4f.hpp b/include/jau/math/mat4f.hpp index a0bc107..f016f3a 100644 --- a/include/jau/math/mat4f.hpp +++ b/include/jau/math/mat4f.hpp @@ -1203,10 +1203,10 @@ class alignas(Value_type) Matrix4 { const value_type bottom, const value_type top, const value_type zNear, const value_type zFar) { if( zNear <= zero || zFar <= zNear ) { - throw jau::IllegalArgumentException("Requirements zNear > 0 and zFar > zNear, but zNear "+std::to_string(zNear)+", zFar "+std::to_string(zFar), E_FILE_LINE); + throw jau::IllegalArgumentError("Requirements zNear > 0 and zFar > zNear, but zNear "+std::to_string(zNear)+", zFar "+std::to_string(zFar), E_FILE_LINE); } if( left == right || top == bottom) { - throw jau::IllegalArgumentException("GL_INVALID_VALUE: top,bottom and left,right must not be equal", E_FILE_LINE); + throw jau::IllegalArgumentError("GL_INVALID_VALUE: top,bottom and left,right must not be equal", E_FILE_LINE); } { // m00 = m11 = m22 = m33 = 1f; diff --git a/include/jau/math/math_error.hpp b/include/jau/math/math_error.hpp index fdd496f..4ecf3f5 100644 --- a/include/jau/math/math_error.hpp +++ b/include/jau/math/math_error.hpp @@ -43,62 +43,107 @@ namespace jau::math { */ /** Error types as specified by [C++ Math Error Handling](https://en.cppreference.com/w/cpp/numeric/math/math_errhandling) */ - enum class math_error_t { - /** See FE_INVALID */ + enum class math_error_t : uint16_t { + /** no math error */ + none = 0, + /** See FE_INVALID, i.e. MathDomainError, std::domain_error : std::logic_error */ invalid, - /** See FE_DIVBYZERO */ + /** See FE_DIVBYZERO, i.e. MathDivByZeroError, std::domain_error : std::logic_error*/ div_by_zero, - /** See FE_OVERFLOW */ + /** See FE_OVERFLOW, i.e. MathOverflowError, std::overflow_error : std::runtime_error */ overflow, - /** See FE_UNDERFLOW */ + /** See FE_UNDERFLOW, i.e. MathUnderflowError, std::underflow_error : std::runtime_error */ underflow, - /** See FE_INEXACT */ - inexact + /** See FE_INEXACT, i.e. MathInexactError, std::runtime_error */ + inexact, + /** undefined math error */ + undefined = 1U << 15, }; /** Returns std::string representation of math_error_t */ std::string to_string(const math_error_t v) noexcept; - class MathError : public RuntimeException { + class MathErrorBase : public ExceptionBase { private: math_error_t m_error; - public: - MathError(math_error_t err, std::string const& m, const char* file, int line) noexcept - : RuntimeException("MathError("+to_string(err)+")", m, file, line), m_error(err) {} - - math_error_t error() const noexcept; + protected: + MathErrorBase(math_error_t err, std::string const& m, const char* file, int line) noexcept + : ExceptionBase("MathError("+to_string(err)+")", m, file, line), m_error(err) {} + + public: + math_error_t error() const noexcept; }; - /** math_error_t::invalid */ - class MathDomainError : public MathError { + class MathRuntimeErrorBase : public MathErrorBase { + protected: + MathRuntimeErrorBase(math_error_t err, std::string const& m, const char* file, int line) noexcept + : MathErrorBase(err, m, file, line) {} + }; + + class MathError : public MathErrorBase, public std::exception { public: - MathDomainError(std::string const& m, const char* file, int line) noexcept - : MathError(math_error_t::invalid, m, file, line) {} + MathError(math_error_t err, std::string const& m, const char* file, int line) noexcept + : MathErrorBase(err, m, file, line), exception() {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; - /** math_error_t::div_by_zero, i.e. pole error */ - class MathDivByZeroError : public MathError { + + /** math_error_t::inexact */ + class MathInexactError : public MathRuntimeErrorBase, public std::runtime_error { public: - MathDivByZeroError(std::string const& m, const char* file, int line) noexcept - : MathError(math_error_t::div_by_zero, m, file, line) {} + MathInexactError(std::string const& m, const char* file, int line) noexcept + : MathRuntimeErrorBase(math_error_t::inexact, m, file, line), runtime_error(whole_message()) {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; + /** math_error_t::overflow */ - class MathOverflowError : public MathError { + class MathOverflowError : public MathRuntimeErrorBase, public std::overflow_error { public: MathOverflowError(std::string const& m, const char* file, int line) noexcept - : MathError(math_error_t::overflow, m, file, line) {} + : MathRuntimeErrorBase(math_error_t::overflow, m, file, line), overflow_error(whole_message()) {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; + /** math_error_t::underflow */ - class MathUnderflowError : public MathError { + class MathUnderflowError : public MathRuntimeErrorBase, public std::underflow_error { public: MathUnderflowError(std::string const& m, const char* file, int line) noexcept - : MathError(math_error_t::underflow, m, file, line) {} + : MathRuntimeErrorBase(math_error_t::underflow, m, file, line), underflow_error(whole_message()) {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; - /** math_error_t::inexact */ - class MathInexactError : public MathError { + + /** math_error_t::invalid */ + class MathDomainError : public MathErrorBase, public std::domain_error { + protected: + MathDomainError(math_error_t err, std::string const& m, const char* file, int line) noexcept + : MathErrorBase(err, m, file, line), domain_error(whole_message()) {} + public: - MathInexactError(std::string const& m, const char* file, int line) noexcept - : MathError(math_error_t::inexact, m, file, line) {} + MathDomainError(std::string const& m, const char* file, int line) noexcept + : MathErrorBase(math_error_t::invalid, m, file, line), domain_error(whole_message()) {} + + const char* what() const noexcept override { + return whole_message().c_str(); + } }; - + + /** math_error_t::div_by_zero, i.e. pole error */ + class MathDivByZeroError : public MathDomainError { + public: + MathDivByZeroError(std::string const& m, const char* file, int line) noexcept + : MathDomainError(math_error_t::div_by_zero, m, file, line) {} + }; + /**@}*/ } // namespace jau diff --git a/include/jau/math/util/pmvmat4f.hpp b/include/jau/math/util/pmvmat4f.hpp index 3073ea3..f4cc846 100644 --- a/include/jau/math/util/pmvmat4f.hpp +++ b/include/jau/math/util/pmvmat4f.hpp @@ -329,7 +329,7 @@ class PMVMatrix4 { */ Mat4& getMvi() { if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { // FIXME - throw jau::IllegalArgumentException("Not requested in ctor", E_FILE_LINE); + throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE); } updateImpl(false); return matMvi; @@ -344,7 +344,7 @@ class PMVMatrix4 { */ SyncMat4& getSyncMvi() { if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { // FIXME - throw jau::IllegalArgumentException("Not requested in ctor", E_FILE_LINE); + throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE); } return syncMvi; } @@ -358,7 +358,7 @@ class PMVMatrix4 { */ Mat4& getMvit() { if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { // FIXME - throw jau::IllegalArgumentException("Not requested in ctor", E_FILE_LINE); + throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE); } updateImpl(false); return matMvit; @@ -373,7 +373,7 @@ class PMVMatrix4 { */ SyncMat4& getSyncMvit() { if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { // FIXME - throw jau::IllegalArgumentException("Not requested in ctor", E_FILE_LINE); + throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE); } return syncMvit; } @@ -387,7 +387,7 @@ class PMVMatrix4 { */ SyncMats4f& getSyncPMvMvi() { if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { // FIXME - throw jau::IllegalArgumentException("Not requested in ctor", E_FILE_LINE); + throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE); } return syncP_Mv_Mvi; } @@ -401,7 +401,7 @@ class PMVMatrix4 { */ SyncMats4f& getSyncPMvMviMvit() { if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { // FIXME - throw jau::IllegalArgumentException("Not requested in ctor", E_FILE_LINE); + throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE); } return syncP_Mv_Mvi_Mvit; } diff --git a/include/jau/ringbuffer.hpp b/include/jau/ringbuffer.hpp index b808007..85468f8 100644 --- a/include/jau/ringbuffer.hpp +++ b/include/jau/ringbuffer.hpp @@ -976,7 +976,7 @@ class ringbuffer { return; } if( size_ > newCapacity ) { - throw IllegalArgumentException("amount "+std::to_string(newCapacity)+" < size, "+toString(), E_FILE_LINE); + throw IllegalArgumentError("amount "+std::to_string(newCapacity)+" < size, "+toString(), E_FILE_LINE); } // save current data diff --git a/java_jni/jni/helper_jni.cxx b/java_jni/jni/helper_jni.cxx index e0e6e87..19ed13f 100644 --- a/java_jni/jni/helper_jni.cxx +++ b/java_jni/jni/helper_jni.cxx @@ -24,7 +24,6 @@ */ #include <jni.h> -#include <memory> #include <stdexcept> #include <vector> @@ -80,7 +79,10 @@ void jau::jni::java_exception_check_and_throw(JNIEnv *env, const char* file, int void jau::jni::print_native_caught_exception_fwd2java(const jau::OutOfMemoryError &e, const char* file, int line) { fprintf(stderr, "Native exception caught @ %s:%d and forward to Java: %s\n", file, line, e.what()); fflush(stderr); } -void jau::jni::print_native_caught_exception_fwd2java(const jau::RuntimeException &e, const char* file, int line) { +void jau::jni::print_native_caught_exception_fwd2java(const jau::LogicErrorBase &e, const char* file, int line) { + fprintf(stderr, "Native exception caught @ %s:%d and forward to Java: %s\n", file, line, e.what()); fflush(stderr); +} +void jau::jni::print_native_caught_exception_fwd2java(const jau::RuntimeExceptionBase &e, const char* file, int line) { fprintf(stderr, "Native exception caught @ %s:%d and forward to Java: %s\n", file, line, e.what()); fflush(stderr); } void jau::jni::print_native_caught_exception_fwd2java(const std::exception &e, const char* file, int line) { @@ -101,36 +103,40 @@ void jau::jni::raise_java_exception(JNIEnv *env, const std::runtime_error &e, co print_native_caught_exception_fwd2java(e, file, line); env->ThrowNew(env->FindClass("java/lang/RuntimeException"), e.what()); } -void jau::jni::raise_java_exception(JNIEnv *env, const jau::RuntimeException &e, const char* file, int line) { +void jau::jni::raise_java_exception(JNIEnv *env, const jau::LogicErrorBase &e, const char* file, int line) { + print_native_caught_exception_fwd2java(e, file, line); + env->ThrowNew(env->FindClass("java/lang/Exception"), e.what()); +} +void jau::jni::raise_java_exception(JNIEnv *env, const jau::RuntimeExceptionBase &e, const char* file, int line) { print_native_caught_exception_fwd2java(e, file, line); env->ThrowNew(env->FindClass("java/lang/RuntimeException"), e.what()); } void jau::jni::raise_java_exception(JNIEnv *env, const jau::InternalError &e, const char* file, int line) { - print_native_caught_exception_fwd2java(e, file, line); + print_native_caught_exception_fwd2java(static_cast<const jau::RuntimeExceptionBase&>(e), file, line); env->ThrowNew(env->FindClass("java/lang/InternalError"), e.what()); } void jau::jni::raise_java_exception(JNIEnv *env, const jau::NullPointerException &e, const char* file, int line) { - print_native_caught_exception_fwd2java(e, file, line); + print_native_caught_exception_fwd2java(static_cast<const jau::RuntimeExceptionBase&>(e), file, line); env->ThrowNew(env->FindClass("java/lang/NullPointerException"), e.what()); } -void jau::jni::raise_java_exception(JNIEnv *env, const jau::IllegalArgumentException &e, const char* file, int line) { - print_native_caught_exception_fwd2java(e, file, line); +void jau::jni::raise_java_exception(JNIEnv *env, const jau::IllegalArgumentError &e, const char* file, int line) { + print_native_caught_exception_fwd2java(static_cast<const jau::LogicErrorBase&>(e), file, line); env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), e.what()); } void jau::jni::raise_java_exception(JNIEnv *env, const std::invalid_argument &e, const char* file, int line) { print_native_caught_exception_fwd2java(e, file, line); env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), e.what()); } -void jau::jni::raise_java_exception(JNIEnv *env, const jau::IllegalStateException &e, const char* file, int line) { - print_native_caught_exception_fwd2java(e, file, line); +void jau::jni::raise_java_exception(JNIEnv *env, const jau::IllegalStateError &e, const char* file, int line) { + print_native_caught_exception_fwd2java(static_cast<const jau::LogicErrorBase&>(e), file, line); env->ThrowNew(env->FindClass("java/lang/IllegalStateException"), e.what()); } void jau::jni::raise_java_exception(JNIEnv *env, const jau::UnsupportedOperationException &e, const char* file, int line) { - print_native_caught_exception_fwd2java(e, file, line); + print_native_caught_exception_fwd2java(static_cast<const jau::RuntimeExceptionBase&>(e), file, line); env->ThrowNew(env->FindClass("java/lang/UnsupportedOperationException"), e.what()); } -void jau::jni::raise_java_exception(JNIEnv *env, const jau::IndexOutOfBoundsException &e, const char* file, int line) { - print_native_caught_exception_fwd2java(e, file, line); +void jau::jni::raise_java_exception(JNIEnv *env, const jau::IndexOutOfBoundsError &e, const char* file, int line) { + print_native_caught_exception_fwd2java(static_cast<const jau::LogicErrorBase&>(e), file, line); env->ThrowNew(env->FindClass("java/lang/IndexOutOfBoundsException"), e.what()); } void jau::jni::raise_java_exception(JNIEnv *env, const std::bad_alloc &e, const char* file, int line) { @@ -153,17 +159,19 @@ void jau::jni::rethrow_and_raise_java_exception_jauimpl(JNIEnv *env, const char* jau::jni::raise_java_exception(env, e, file, line); } catch (const jau::InternalError &e) { jau::jni::raise_java_exception(env, e, file, line); - } catch (const jau::NullPointerException &e) { + } catch (const jau::IndexOutOfBoundsError &e) { jau::jni::raise_java_exception(env, e, file, line); - } catch (const jau::IllegalArgumentException &e) { + } catch (const jau::IllegalArgumentError &e) { jau::jni::raise_java_exception(env, e, file, line); - } catch (const jau::IllegalStateException &e) { + } catch (const jau::IllegalStateError &e) { jau::jni::raise_java_exception(env, e, file, line); } catch (const jau::UnsupportedOperationException &e) { jau::jni::raise_java_exception(env, e, file, line); - } catch (const jau::IndexOutOfBoundsException &e) { + } catch (const jau::NullPointerException &e) { + jau::jni::raise_java_exception(env, e, file, line); + } catch (const jau::RuntimeExceptionBase &e) { jau::jni::raise_java_exception(env, e, file, line); - } catch (const jau::RuntimeException &e) { + } catch (const jau::LogicErrorBase &e) { jau::jni::raise_java_exception(env, e, file, line); } catch (const std::runtime_error &e) { jau::jni::raise_java_exception(env, e, file, line); @@ -326,7 +334,7 @@ bool jau::jni::from_jboolean_to_bool(jboolean val) std::string jau::jni::from_jstring_to_string(JNIEnv *env, jstring jstr) { if (!jstr) { - throw jau::IllegalArgumentException("String argument should not be null", E_FILE_LINE); + throw jau::IllegalArgumentError("String argument should not be null", E_FILE_LINE); } const char *str_chars = (char *)env->GetStringUTFChars(jstr, nullptr); if (!str_chars) { @@ -343,7 +351,7 @@ jstring jau::jni::from_string_to_jstring(JNIEnv *env, const std::string & str) { jau::io::secure_string jau::jni::from_jbytebuffer_to_sstring(JNIEnv *env, jobject jbytebuffer) { if (!jbytebuffer) { - throw jau::IllegalArgumentException("ByteBuffer argument should not be null", E_FILE_LINE); + throw jau::IllegalArgumentError("ByteBuffer argument should not be null", E_FILE_LINE); } const char* address = (const char*)env->GetDirectBufferAddress(jbytebuffer); size_t capacity = (size_t)env->GetDirectBufferCapacity(jbytebuffer); @@ -466,7 +474,7 @@ std::vector<std::string> jau::jni::convert_jlist_string_to_vector(JNIEnv *env, j // C++ java_anon implementation // -jau::jni::JavaGlobalObj::~JavaGlobalObj() noexcept { +jau::jni::JavaGlobalObj::~JavaGlobalObj() noexcept { // NOLINT(bugprone-exception-escape): handled try { JNIEnv *env = *jni_env; if( nullptr == env ) { diff --git a/java_jni/jni/jau/ByteInStream_Feed.cxx b/java_jni/jni/jau/ByteInStream_Feed.cxx index eab710c..03f806c 100644 --- a/java_jni/jni/jau/ByteInStream_Feed.cxx +++ b/java_jni/jni/jau/ByteInStream_Feed.cxx @@ -169,11 +169,11 @@ jint Java_org_jau_io_ByteInStream_1Feed_read(JNIEnv *env, jobject obj, jbyteArra jau::jni::shared_ptr_ref<jau::io::ByteInStream_Feed> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jout); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * out_ptr = criticalArray.get(jout, criticalArray.Mode::UPDATE_AND_RELEASE); @@ -192,12 +192,12 @@ jint Java_org_jau_io_ByteInStream_1Feed_read2Impl(JNIEnv *env, jobject obj, jobj jau::jni::shared_ptr_ref<jau::io::ByteInStream_Feed> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const jlong out_cap = env->GetDirectBufferCapacity(jout); uint8_t * out_ptr = static_cast<uint8_t *>( env->GetDirectBufferAddress(jout) ); if( 0 > out_cap || nullptr == out_ptr ) { - throw jau::IllegalArgumentException("out buffer access failure", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer access failure", E_FILE_LINE); } return (jint) ref->read(out_ptr + out_offset, out_cap - out_offset); } catch(...) { @@ -211,11 +211,11 @@ jint Java_org_jau_io_ByteInStream_1Feed_peek(JNIEnv *env, jobject obj, jbyteArra jau::jni::shared_ptr_ref<jau::io::ByteInStream_Feed> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jout); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * out_ptr = criticalArray.get(jout, criticalArray.Mode::UPDATE_AND_RELEASE); @@ -296,11 +296,11 @@ jboolean Java_org_jau_io_ByteInStream_1Feed_write0Impl(JNIEnv *env, jobject obj, jau::jni::shared_ptr_ref<jau::io::ByteInStream_Feed> ref(env, obj); // hold until done if( nullptr == jin ) { - throw jau::IllegalArgumentException("address null", E_FILE_LINE); + throw jau::IllegalArgumentError("address null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jin); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("input byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("input byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * in_ptr = criticalArray.get(jin, criticalArray.Mode::NO_UPDATE_AND_RELEASE); @@ -320,11 +320,11 @@ jboolean Java_org_jau_io_ByteInStream_1Feed_write1Impl(JNIEnv *env, jobject obj, jau::jni::shared_ptr_ref<jau::io::ByteInStream_Feed> ref(env, obj); // hold until done if( nullptr == jin ) { - throw jau::IllegalArgumentException("address null", E_FILE_LINE); + throw jau::IllegalArgumentError("address null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jin); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("input byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("input byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * in_ptr = criticalArray.get(jin, criticalArray.Mode::NO_UPDATE_AND_RELEASE); @@ -343,11 +343,11 @@ jboolean Java_org_jau_io_ByteInStream_1Feed_write2Impl(JNIEnv *env, jobject obj, jau::jni::shared_ptr_ref<jau::io::ByteInStream_Feed> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } uint8_t * out_ptr = static_cast<uint8_t *>( env->GetDirectBufferAddress(jout) ); if( nullptr == out_ptr ) { - throw jau::IllegalArgumentException("out buffer access failure", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer access failure", E_FILE_LINE); } return ref->write(out_ptr + out_offset, out_limit - out_offset) ? JNI_TRUE : JNI_FALSE; } catch(...) { diff --git a/java_jni/jni/jau/ByteInStream_File.cxx b/java_jni/jni/jau/ByteInStream_File.cxx index e0ba463..420fb29 100644 --- a/java_jni/jni/jau/ByteInStream_File.cxx +++ b/java_jni/jni/jau/ByteInStream_File.cxx @@ -223,11 +223,11 @@ jint Java_org_jau_io_ByteInStream_1File_read(JNIEnv *env, jobject obj, jbyteArra jau::jni::shared_ptr_ref<jau::io::ByteInStream_File> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jout); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * out_ptr = criticalArray.get(jout, criticalArray.Mode::UPDATE_AND_RELEASE); @@ -246,12 +246,12 @@ jint Java_org_jau_io_ByteInStream_1File_read2Impl(JNIEnv *env, jobject obj, jobj jau::jni::shared_ptr_ref<jau::io::ByteInStream_File> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const jlong out_cap = env->GetDirectBufferCapacity(jout); uint8_t * out_ptr = static_cast<uint8_t *>( env->GetDirectBufferAddress(jout) ); if( 0 > out_cap || nullptr == out_ptr ) { - throw jau::IllegalArgumentException("out buffer access failure", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer access failure", E_FILE_LINE); } return (jint) ref->read(out_ptr + out_offset, out_cap - out_offset); } catch(...) { @@ -265,11 +265,11 @@ jint Java_org_jau_io_ByteInStream_1File_peek(JNIEnv *env, jobject obj, jbyteArra jau::jni::shared_ptr_ref<jau::io::ByteInStream_File> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jout); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * out_ptr = criticalArray.get(jout, criticalArray.Mode::UPDATE_AND_RELEASE); diff --git a/java_jni/jni/jau/ByteInStream_URL.cxx b/java_jni/jni/jau/ByteInStream_URL.cxx index f0e7297..73dd540 100644 --- a/java_jni/jni/jau/ByteInStream_URL.cxx +++ b/java_jni/jni/jau/ByteInStream_URL.cxx @@ -169,11 +169,11 @@ jint Java_org_jau_io_ByteInStream_1URL_read(JNIEnv *env, jobject obj, jbyteArray jau::jni::shared_ptr_ref<jau::io::ByteInStream_URL> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jout); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * out_ptr = criticalArray.get(jout, criticalArray.Mode::UPDATE_AND_RELEASE); @@ -192,12 +192,12 @@ jint Java_org_jau_io_ByteInStream_1URL_read2Impl(JNIEnv *env, jobject obj, jobje jau::jni::shared_ptr_ref<jau::io::ByteInStream_URL> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const jlong out_cap = env->GetDirectBufferCapacity(jout); uint8_t * out_ptr = static_cast<uint8_t *>( env->GetDirectBufferAddress(jout) ); if( 0 > out_cap || nullptr == out_ptr ) { - throw jau::IllegalArgumentException("out buffer access failure", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer access failure", E_FILE_LINE); } return (jint) ref->read(out_ptr + out_offset, out_cap - out_offset); } catch(...) { @@ -211,11 +211,11 @@ jint Java_org_jau_io_ByteInStream_1URL_peek(JNIEnv *env, jobject obj, jbyteArray jau::jni::shared_ptr_ref<jau::io::ByteInStream_URL> ref(env, obj); // hold until done if( nullptr == jout ) { - throw jau::IllegalArgumentException("out buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("out buffer null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jout); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("output byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * out_ptr = criticalArray.get(jout, criticalArray.Mode::UPDATE_AND_RELEASE); diff --git a/java_jni/jni/jau/ByteOutStream_File.cxx b/java_jni/jni/jau/ByteOutStream_File.cxx index 241f7ea..ec885c7 100644 --- a/java_jni/jni/jau/ByteOutStream_File.cxx +++ b/java_jni/jni/jau/ByteOutStream_File.cxx @@ -199,11 +199,11 @@ jint Java_org_jau_io_ByteOutStream_1File_write(JNIEnv *env, jobject obj, jbyteAr jau::jni::shared_ptr_ref<jau::io::ByteOutStream_File> ref(env, obj); // hold until done if( nullptr == jin ) { - throw jau::IllegalArgumentException("in buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("in buffer null", E_FILE_LINE); } const size_t in_size = env->GetArrayLength(jin); if( (size_t)joffset + (size_t)jlength > in_size ) { - throw jau::IllegalArgumentException("input byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); + throw jau::IllegalArgumentError("input byte size "+std::to_string(in_size)+" < "+std::to_string(joffset)+" + "+std::to_string(jlength), E_FILE_LINE); } jau::jni::JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release uint8_t * in_ptr = criticalArray.get(jin, criticalArray.Mode::NO_UPDATE_AND_RELEASE); @@ -222,14 +222,14 @@ jint Java_org_jau_io_ByteOutStream_1File_write2Impl(JNIEnv *env, jobject obj, jo jau::jni::shared_ptr_ref<jau::io::ByteOutStream_File> ref(env, obj); // hold until done if( nullptr == jin ) { - throw jau::IllegalArgumentException("in buffer null", E_FILE_LINE); + throw jau::IllegalArgumentError("in buffer null", E_FILE_LINE); } if( 0 > in_limit) { - throw jau::IllegalArgumentException("invalid negative limit", E_FILE_LINE); + throw jau::IllegalArgumentError("invalid negative limit", E_FILE_LINE); } uint8_t * in_ptr = static_cast<uint8_t *>( env->GetDirectBufferAddress(jin) ); if( nullptr == in_ptr ) { - throw jau::IllegalArgumentException("in buffer access failure", E_FILE_LINE); + throw jau::IllegalArgumentError("in buffer access failure", E_FILE_LINE); } return (jint) ref->write(in_ptr + out_offset, in_limit - out_offset); } catch(...) { diff --git a/java_jni/jni/jau/jau_fs_FileUtil.cxx b/java_jni/jni/jau/jau_fs_FileUtil.cxx index b92036a..97cea09 100644 --- a/java_jni/jni/jau/jau_fs_FileUtil.cxx +++ b/java_jni/jni/jau/jau_fs_FileUtil.cxx @@ -60,7 +60,7 @@ jlong Java_org_jau_fs_FileStats_ctorImpl1(JNIEnv *env, jclass clazz, jstring jpa (void)clazz; try { if( nullptr == jpath ) { - throw jau::IllegalArgumentException("path null", E_FILE_LINE); + throw jau::IllegalArgumentError("path null", E_FILE_LINE); } std::string path = jau::jni::from_jstring_to_string(env, jpath); @@ -78,7 +78,7 @@ jlong Java_org_jau_fs_FileStats_ctorImpl2(JNIEnv *env, jclass clazz, jstring jdi (void)clazz; try { if( nullptr == jdirname || nullptr == jbasename ) { - throw jau::IllegalArgumentException("path null", E_FILE_LINE); + throw jau::IllegalArgumentError("path null", E_FILE_LINE); } std::string dirname = jau::jni::from_jstring_to_string(env, jdirname); std::string basename = jau::jni::from_jstring_to_string(env, jbasename); diff --git a/java_jni/jni/jau/jau_sys_Clock.cxx b/java_jni/jni/jau/jau_sys_Clock.cxx index dde56de..5482d52 100644 --- a/java_jni/jni/jau/jau_sys_Clock.cxx +++ b/java_jni/jni/jau/jau_sys_Clock.cxx @@ -42,11 +42,11 @@ void Java_org_jau_sys_Clock_getMonotonicTimeImpl(JNIEnv *env, jclass clazz, jlon (void)clazz; try { if( nullptr == jval ) { - throw jau::IllegalArgumentException("val null", E_FILE_LINE); + throw jau::IllegalArgumentError("val null", E_FILE_LINE); } const size_t jval_size = env->GetArrayLength(jval); if( 2 > jval_size ) { - throw jau::IllegalArgumentException("val size "+std::to_string(jval_size)+" < 2", E_FILE_LINE); + throw jau::IllegalArgumentError("val size "+std::to_string(jval_size)+" < 2", E_FILE_LINE); } // Avoid GetPrimitiveArrayCritical(), which occasionally hangs on system call ::clock_gettime() struct timespec t { 0, 0 }; @@ -63,11 +63,11 @@ void Java_org_jau_sys_Clock_getWallClockTimeImpl(JNIEnv *env, jclass clazz, jlon (void)clazz; try { if( nullptr == jval ) { - throw jau::IllegalArgumentException("val null", E_FILE_LINE); + throw jau::IllegalArgumentError("val null", E_FILE_LINE); } const size_t jval_size = env->GetArrayLength(jval); if( 2 > jval_size ) { - throw jau::IllegalArgumentException("val size "+std::to_string(jval_size)+" < 2", E_FILE_LINE); + throw jau::IllegalArgumentError("val size "+std::to_string(jval_size)+" < 2", E_FILE_LINE); } // Avoid GetPrimitiveArrayCritical(), which occasionally hangs on system call ::clock_gettime() struct timespec t { 0, 0 }; diff --git a/java_jni/jni/jni_mem.cxx b/java_jni/jni/jni_mem.cxx index 86f53a0..e849ebf 100644 --- a/java_jni/jni/jni_mem.cxx +++ b/java_jni/jni/jni_mem.cxx @@ -207,13 +207,13 @@ JNIGlobalRef::~JNIGlobalRef() noexcept { } catch (jau::ExceptionBase &e0) { if( root_environment::is_terminating() ) { if( jau::environment::get().debug ) { - fprintf(stderr, "JNIGlobalRef::dtor: Caught at exit %s\n", e0.what()); + fprintf(stderr, "JNIGlobalRef::dtor: Caught at exit %s\n", e0.whole_message().c_str()); } else { // Be brief @ exit, as its expected at JVM shutdown - fprintf(stderr, "JNIGlobalRef::dtor: Caught at exit %s\n", e0.message().c_str()); + fprintf(stderr, "JNIGlobalRef::dtor: Caught at exit %s\n", e0.brief_message().c_str()); } } else { - fprintf(stderr, "JNIGlobalRef::dtor: Caught %s\n", e0.what()); + fprintf(stderr, "JNIGlobalRef::dtor: Caught %s\n", e0.whole_message().c_str()); } } catch (std::exception &e) { if( root_environment::is_terminating() ) { @@ -235,7 +235,7 @@ jobjectRefType JNIGlobalRef::getObjectRefType() const noexcept { std::unique_lock<std::mutex> lock(mtx); return env->GetObjectRefType(object); } catch (const jau::ExceptionBase &e) { - ERR_PRINT("%s", e.message().c_str()); + ERR_PRINT("%s", e.brief_message().c_str()); } catch (...) { ERR_PRINT("Unknown exception"); } @@ -268,7 +268,7 @@ bool JNIGlobalRef::operator==(const JNIGlobalRef& rhs) const noexcept { res = JNI_TRUE == env->IsSameObject(object, rhs.object); DBG_JNI_PRINT("JNIGlobalRef::== %d: %p == %p (IsSameObject)", res, object, rhs.object); } catch (const jau::ExceptionBase &e) { - ERR_PRINT("%s", e.message().c_str()); + ERR_PRINT("%s", e.brief_message().c_str()); } catch (...) { ERR_PRINT("Unknown exception"); } diff --git a/src/basic_types.cpp b/src/basic_types.cpp index c44c9c6..15d219b 100644 --- a/src/basic_types.cpp +++ b/src/basic_types.cpp @@ -247,10 +247,11 @@ std::cv_status jau::wait_for(std::condition_variable& cv, std::unique_lock<std:: } } -jau::ExceptionBase::ExceptionBase(std::string type, std::string const& m, const char* file, int line) noexcept -: msg_( std::move( type.append(" @ ").append(file).append(":").append(std::to_string(line)).append(": ").append(m) ) ), +jau::ExceptionBase::ExceptionBase(const std::string &type, std::string const& m, const char* file, int line) noexcept // NOLINT(modernize-pass-by-value) +: msg_( type ), backtrace_( jau::get_backtrace(true /* skip_anon_frames */) ) { + msg_.append(" @ ").append(file).append(":").append(std::to_string(line)).append(": ").append(m); what_ = msg_; what_.append("\nNative backtrace:\n"); what_.append(backtrace_); @@ -310,7 +311,7 @@ uint128dp_t jau::merge_uint128(uint16_t const uuid16, uint128dp_t const & base_u std::string msg("uuid16_le_octet_index "); msg.append(std::to_string(uuid16_le_octet_index)); msg.append(", not within [0..14]"); - throw IllegalArgumentException(msg, E_FILE_LINE); + throw IllegalArgumentError(msg, E_FILE_LINE); } uint128dp_t dest = base_uuid; @@ -345,7 +346,7 @@ uint128dp_t jau::merge_uint128(uint32_t const uuid32, uint128dp_t const & base_u std::string msg("uuid32_le_octet_index "); msg.append(std::to_string(uuid32_le_octet_index)); msg.append(", not within [0..12]"); - throw IllegalArgumentException(msg, E_FILE_LINE); + throw IllegalArgumentError(msg, E_FILE_LINE); } uint128dp_t dest = base_uuid; @@ -636,11 +637,13 @@ bool jau::to_fraction_i64(fraction_i64& result, const std::string & value, const std::string jau::math::to_string(const jau::math::math_error_t v) noexcept { switch(v) { + case jau::math::math_error_t::none: return "none"; case jau::math::math_error_t::invalid: return "invalid"; case jau::math::math_error_t::div_by_zero: return "div_by_zero"; case jau::math::math_error_t::overflow: return "overflow"; case jau::math::math_error_t::underflow: return "underflow"; case jau::math::math_error_t::inexact: return "inexact"; + case jau::math::math_error_t::undefined: return "undefined"; } - return "unknown"; + return "undef"; } diff --git a/src/eui48.cpp b/src/eui48.cpp index 05cc205..8f34385 100644 --- a/src/eui48.cpp +++ b/src/eui48.cpp @@ -108,7 +108,7 @@ bool EUI48Sub::scanEUI48Sub(const std::string& str, EUI48Sub& dest, std::string& EUI48Sub::EUI48Sub(const std::string& str) { std::string errmsg; if( !scanEUI48Sub(str, *this, errmsg) ) { - throw jau::IllegalArgumentException(errmsg, E_FILE_LINE); + throw jau::IllegalArgumentError(errmsg, E_FILE_LINE); } } @@ -227,7 +227,7 @@ bool EUI48::scanEUI48(const std::string& str, EUI48& dest, std::string& errmsg) EUI48::EUI48(const std::string& str) { std::string errmsg; if( !scanEUI48(str, *this, errmsg) ) { - throw jau::IllegalArgumentException(errmsg, E_FILE_LINE); + throw jau::IllegalArgumentError(errmsg, E_FILE_LINE); } } diff --git a/src/uuid.cpp b/src/uuid.cpp index d30d89f..a9d1f5b 100644 --- a/src/uuid.cpp +++ b/src/uuid.cpp @@ -50,7 +50,7 @@ uuid_t::TypeSize uuid_t::toTypeSize(const jau::nsize_t size) { case TypeSize::UUID32_SZ: return TypeSize::UUID32_SZ; case TypeSize::UUID128_SZ: return TypeSize::UUID128_SZ; } - throw jau::IllegalArgumentException("Given size "+std::to_string(size)+", not matching uuid16_t, uuid32_t or uuid128_t", E_FILE_LINE); + throw jau::IllegalArgumentError("Given size "+std::to_string(size)+", not matching uuid16_t, uuid32_t or uuid128_t", E_FILE_LINE); } std::unique_ptr<uuid_t> uuid_t::create(TypeSize t, uint8_t const * const buffer, lb_endian_t const le_or_be) { @@ -61,7 +61,7 @@ std::unique_ptr<uuid_t> uuid_t::create(TypeSize t, uint8_t const * const buffer, } else if( TypeSize::UUID128_SZ == t ) { return std::make_unique<uuid128_t>(buffer, le_or_be); } - throw jau::IllegalArgumentException("Unknown Type "+std::to_string(static_cast<jau::nsize_t>(t)), E_FILE_LINE); + throw jau::IllegalArgumentError("Unknown Type "+std::to_string(static_cast<jau::nsize_t>(t)), E_FILE_LINE); } std::unique_ptr<uuid_t> uuid_t::create(const std::string& str) { const size_t len = str.length(); @@ -76,7 +76,7 @@ std::unique_ptr<uuid_t> uuid_t::create(const std::string& str) { std::string msg("UUID string not of length 4, 8 or 36 but "); msg.append(std::to_string(str.length())); msg.append(": "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); + throw jau::IllegalArgumentError(msg, E_FILE_LINE); } } } @@ -224,11 +224,11 @@ uuid16_t::uuid16_t(const std::string& str) std::string msg("UUID16 string not of length 4 but "); msg.append(std::to_string(str.length())); msg.append(": "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); + throw jau::IllegalArgumentError(msg, E_FILE_LINE); } if ( sscanf(str.c_str(), "%04hx", &part0) != 1 ) { std::string msg("UUID16 string not in format '0000' but "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); + throw jau::IllegalArgumentError(msg, E_FILE_LINE); } // sscanf provided host data type, in which we store the values, // hence no endian conversion @@ -244,12 +244,12 @@ uuid32_t::uuid32_t(const std::string& str) std::string msg("UUID32 string not of length 8 but "); msg.append(std::to_string(str.length())); msg.append(": "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); + throw jau::IllegalArgumentError(msg, E_FILE_LINE); } // if ( sscanf(str.c_str(), "%08x-%04hx-%04hx-%04hx-%08x%04hx", if ( sscanf(str.c_str(), "%08x", &part0) != 1 ) { std::string msg("UUID32 string not in format '00000000' but "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); + throw jau::IllegalArgumentError(msg, E_FILE_LINE); } // sscanf provided host data type, in which we store the values, // hence no endian conversion @@ -266,13 +266,13 @@ uuid128_t::uuid128_t(const std::string& str) std::string msg("UUID128 string not of length 36 but "); msg.append(std::to_string(str.length())); msg.append(": "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); + throw jau::IllegalArgumentError(msg, E_FILE_LINE); } if ( sscanf(str.c_str(), "%08x-%04hx-%04hx-%04hx-%08x%04hx", &part0, &part1, &part2, &part3, &part4, &part5) != 6 ) { std::string msg("UUID128 string not in format '00000000-0000-1000-8000-00805F9B34FB' but "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); + throw jau::IllegalArgumentError(msg, E_FILE_LINE); } // sscanf provided host data type, in which we store the values, diff --git a/test/test_big_int01.hpp b/test/test_big_int01.hpp index 0c767dd..e229890 100644 --- a/test/test_big_int01.hpp +++ b/test/test_big_int01.hpp @@ -255,7 +255,7 @@ TEST_CASE( "MP Big Int Dec Test 11", "[big_int_t][inout][math]" ) { } } } -TEST_CASE( "MP Big Int Error Handling Test 88", "[big_int_t][error][arithmetic][math]" ) { +TEST_CASE( "MP Big Int Error Handling Test 88", "[big_int_t][exceptions][error][arithmetic][math]" ) { { BigInt a = 1, b = 0, r; REQUIRE_THROWS_MATCHES( r = a / b, jau::math::MathDivByZeroError, Catch::Matchers::ContainsSubstring("div_by_zero") ); diff --git a/test/test_exceptions01.cpp b/test/test_exceptions01.cpp new file mode 100644 index 0000000..bd4d8fd --- /dev/null +++ b/test/test_exceptions01.cpp @@ -0,0 +1,264 @@ +/* + * Author: Sven Gothel <[email protected]> + * Copyright (c) 2024 Gothel Software e.K. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <cstring> +#include <exception> +#include <stdexcept> +#include <system_error> + +#include <jau/test/catch2_ext.hpp> + +#include <jau/basic_types.hpp> +#include <jau/math/math_error.hpp> +#include <jau/mp/big_int.hpp> + +using namespace jau; + +static void throwOutOfMemoryError() { + throw jau::OutOfMemoryError("test", E_FILE_LINE); +} +static void throwRuntimeException() { + throw jau::RuntimeException("test", E_FILE_LINE); +} +static void throwLogicError() { + throw jau::LogicError("test", E_FILE_LINE); +} +static void throwIndexOutOfBoundsError() { + throw jau::IndexOutOfBoundsError(10, 0, E_FILE_LINE); +} +static void throwIllegalArgumentError() { + throw jau::IllegalArgumentError("test", E_FILE_LINE); +} +static void throwIllegalStateError() { + throw jau::IllegalStateError("test", E_FILE_LINE); +} +static void throwRuntimeSystemException() { + throw jau::RuntimeSystemException(std::error_code(), "test", E_FILE_LINE); +} +static void throwIOError() { + throw jau::IOError("test", E_FILE_LINE); +} +static void throwInternalError() { + throw jau::InternalError("test", E_FILE_LINE); +} +static void throwNotImplementedException() { + throw jau::NotImplementedException("test", E_FILE_LINE); +} +static void throwNullPointerException() { + throw jau::NullPointerException("test", E_FILE_LINE); +} +static void throwUnsupportedOperationException() { + throw jau::UnsupportedOperationException("test", E_FILE_LINE); +} + +TEST_CASE( "Exception 00", "[exceptions][error]" ) { + static_assert( true == std::is_base_of_v<jau::ExceptionBase, jau::OutOfMemoryError>); + static_assert( true == std::is_base_of_v<std::bad_alloc, jau::OutOfMemoryError>); + static_assert( true == std::is_base_of_v<std::exception, jau::OutOfMemoryError>); + REQUIRE_THROWS_MATCHES( throwOutOfMemoryError(), jau::OutOfMemoryError, Catch::Matchers::ContainsSubstring("OutOfMemoryError") ); + REQUIRE_THROWS_AS( throwOutOfMemoryError(), jau::ExceptionBase); + REQUIRE_THROWS_AS( throwOutOfMemoryError(), std::bad_alloc); + REQUIRE_THROWS_AS( throwOutOfMemoryError(), std::exception); + + static_assert( true == std::is_base_of_v<jau::ExceptionBase, jau::RuntimeExceptionBase>); + static_assert( true == std::is_base_of_v<jau::RuntimeExceptionBase, jau::RuntimeException>); + static_assert( true == std::is_base_of_v<std::runtime_error, jau::RuntimeException>); + static_assert( true == std::is_base_of_v<std::exception, jau::RuntimeException>); + REQUIRE_THROWS_MATCHES( throwRuntimeException(), jau::RuntimeException, Catch::Matchers::ContainsSubstring("RuntimeException") ); + REQUIRE_THROWS_AS( throwRuntimeException(), jau::RuntimeExceptionBase); + REQUIRE_THROWS_AS( throwRuntimeException(), std::runtime_error); + REQUIRE_THROWS_AS( throwRuntimeException(), std::exception); + + static_assert( true == std::is_base_of_v<jau::ExceptionBase, jau::LogicErrorBase>); + static_assert( true == std::is_base_of_v<jau::LogicErrorBase, jau::LogicError>); + static_assert( true == std::is_base_of_v<std::logic_error, jau::LogicError>); + static_assert( true == std::is_base_of_v<std::exception, jau::LogicError>); + REQUIRE_THROWS_MATCHES( throwLogicError(), jau::LogicError, Catch::Matchers::ContainsSubstring("LogicError") ); + REQUIRE_THROWS_AS( throwLogicError(), jau::LogicErrorBase); + REQUIRE_THROWS_AS( throwLogicError(), std::logic_error); + REQUIRE_THROWS_AS( throwLogicError(), std::exception); + + static_assert( true == std::is_base_of_v<std::out_of_range, jau::IndexOutOfBoundsError>); + static_assert( true == std::is_base_of_v<jau::LogicErrorBase, jau::IndexOutOfBoundsError>); + static_assert( true == std::is_base_of_v<std::logic_error, jau::IndexOutOfBoundsError>); + REQUIRE_THROWS_MATCHES( throwIndexOutOfBoundsError(), jau::IndexOutOfBoundsError, Catch::Matchers::ContainsSubstring("IndexOutOfBoundsError") ); + REQUIRE_THROWS_AS( throwIndexOutOfBoundsError(), std::out_of_range); + REQUIRE_THROWS_MATCHES( throwIndexOutOfBoundsError(), jau::LogicErrorBase, Catch::Matchers::ContainsSubstring("IndexOutOfBoundsError") ); + REQUIRE_THROWS_AS( throwIndexOutOfBoundsError(), std::logic_error); + REQUIRE_THROWS_AS( throwIndexOutOfBoundsError(), std::exception); + + static_assert( true == std::is_base_of_v<std::invalid_argument, jau::IllegalArgumentError>); + static_assert( true == std::is_base_of_v<jau::LogicErrorBase, jau::IllegalArgumentError>); + static_assert( true == std::is_base_of_v<std::logic_error, jau::IllegalArgumentError>); + REQUIRE_THROWS_MATCHES( throwIllegalArgumentError(), jau::IllegalArgumentError, Catch::Matchers::ContainsSubstring("IllegalArgumentError") ); + REQUIRE_THROWS_AS( throwIllegalArgumentError(), std::invalid_argument); + REQUIRE_THROWS_MATCHES( throwIllegalArgumentError(), jau::LogicErrorBase, Catch::Matchers::ContainsSubstring("IllegalArgumentError") ); + REQUIRE_THROWS_AS( throwIllegalArgumentError(), std::logic_error); + REQUIRE_THROWS_AS( throwIllegalArgumentError(), std::exception); + + static_assert( true == std::is_base_of_v<std::domain_error, jau::IllegalStateError>); + static_assert( true == std::is_base_of_v<jau::LogicErrorBase, jau::IllegalStateError>); + static_assert( true == std::is_base_of_v<std::logic_error, jau::IllegalStateError>); + REQUIRE_THROWS_MATCHES( throwIllegalStateError(), jau::IllegalStateError, Catch::Matchers::ContainsSubstring("IllegalStateError") ); + REQUIRE_THROWS_AS( throwIllegalStateError(), std::domain_error); + REQUIRE_THROWS_MATCHES( throwIllegalStateError(), jau::LogicErrorBase, Catch::Matchers::ContainsSubstring("IllegalStateError") ); + REQUIRE_THROWS_AS( throwIllegalStateError(), std::logic_error); + REQUIRE_THROWS_AS( throwIllegalStateError(), std::exception); + + static_assert( true == std::is_base_of_v<jau::RuntimeExceptionBase, jau::RuntimeSystemExceptionBase>); + static_assert( true == std::is_base_of_v<jau::ExceptionBase, jau::RuntimeSystemExceptionBase>); + static_assert( true == std::is_base_of_v<jau::RuntimeSystemExceptionBase, jau::RuntimeSystemException>); + static_assert( true == std::is_base_of_v<std::system_error, jau::RuntimeSystemException>); + static_assert( true == std::is_base_of_v<std::runtime_error, jau::RuntimeSystemException>); + static_assert( true == std::is_base_of_v<std::exception, jau::RuntimeSystemException>); + REQUIRE_THROWS_MATCHES( throwRuntimeSystemException(), jau::RuntimeSystemExceptionBase, Catch::Matchers::ContainsSubstring("RuntimeSystemException") ); + REQUIRE_THROWS_AS( throwRuntimeSystemException(), std::system_error); + REQUIRE_THROWS_MATCHES( throwRuntimeSystemException(), jau::RuntimeExceptionBase, Catch::Matchers::ContainsSubstring("RuntimeSystemException") ); + REQUIRE_THROWS_AS( throwRuntimeSystemException(), std::runtime_error); + REQUIRE_THROWS_AS( throwRuntimeSystemException(), std::exception); + + static_assert( true == std::is_base_of_v<std::ios_base::failure, jau::IOError>); + static_assert( true == std::is_base_of_v<jau::RuntimeSystemExceptionBase, jau::IOError>); + static_assert( true == std::is_base_of_v<std::system_error, jau::IOError>); + static_assert( true == std::is_base_of_v<jau::RuntimeExceptionBase, jau::IOError>); + static_assert( true == std::is_base_of_v<std::runtime_error, jau::IOError>); + REQUIRE_THROWS_MATCHES( throwIOError(), jau::IOError, Catch::Matchers::ContainsSubstring("IOError") ); + REQUIRE_THROWS_AS( throwIOError(), std::ios_base::failure ); + REQUIRE_THROWS_MATCHES( throwIOError(), jau::RuntimeSystemExceptionBase, Catch::Matchers::ContainsSubstring("IOError") ); + REQUIRE_THROWS_AS( throwIOError(), std::system_error); + REQUIRE_THROWS_MATCHES( throwIOError(), jau::RuntimeExceptionBase, Catch::Matchers::ContainsSubstring("IOError") ); + REQUIRE_THROWS_AS( throwIOError(), std::runtime_error ); + REQUIRE_THROWS_AS( throwIOError(), std::exception ); + + REQUIRE_THROWS_MATCHES( throwInternalError(), jau::RuntimeExceptionBase, Catch::Matchers::ContainsSubstring("InternalError") ); + REQUIRE_THROWS_AS( throwInternalError(), std::runtime_error ); + REQUIRE_THROWS_MATCHES( throwInternalError(), jau::InternalError, Catch::Matchers::ContainsSubstring("InternalError") ); + REQUIRE_THROWS_AS( throwInternalError(), std::exception ); + + REQUIRE_THROWS_MATCHES( throwNotImplementedException(), jau::RuntimeExceptionBase, Catch::Matchers::ContainsSubstring("NotImplementedException") ); + REQUIRE_THROWS_AS( throwNotImplementedException(), std::runtime_error ); + REQUIRE_THROWS_MATCHES( throwNotImplementedException(), jau::NotImplementedException, Catch::Matchers::ContainsSubstring("NotImplementedException") ); + REQUIRE_THROWS_AS( throwNotImplementedException(), std::exception ); + + REQUIRE_THROWS_MATCHES( throwNullPointerException(), jau::RuntimeExceptionBase, Catch::Matchers::ContainsSubstring("NullPointerException") ); + REQUIRE_THROWS_AS( throwNullPointerException(), std::runtime_error ); + REQUIRE_THROWS_MATCHES( throwNullPointerException(), jau::NullPointerException, Catch::Matchers::ContainsSubstring("NullPointerException") ); + REQUIRE_THROWS_AS( throwNullPointerException(), std::exception ); + + REQUIRE_THROWS_MATCHES( throwUnsupportedOperationException(), jau::RuntimeExceptionBase, Catch::Matchers::ContainsSubstring("UnsupportedOperationException") ); + REQUIRE_THROWS_AS( throwUnsupportedOperationException(), std::runtime_error ); + REQUIRE_THROWS_MATCHES( throwUnsupportedOperationException(), jau::UnsupportedOperationException, Catch::Matchers::ContainsSubstring("UnsupportedOperationException") ); + REQUIRE_THROWS_AS( throwUnsupportedOperationException(), std::exception ); +} + +static void throwMathError() { + throw jau::math::MathError(jau::math::math_error_t::undefined, "test", E_FILE_LINE); +} +static void throwMathInexactError() { + throw jau::math::MathInexactError("test", E_FILE_LINE); +} +static void throwMathDomainError() { + throw jau::math::MathDomainError("test", E_FILE_LINE); +} +static void throwMathDivByZeroError() { + throw jau::math::MathDivByZeroError("test", E_FILE_LINE); +} +static void throwMathOverflowError() { + throw jau::math::MathOverflowError("test", E_FILE_LINE); +} +static void throwMathUnderflowError() { + throw jau::math::MathUnderflowError("test", E_FILE_LINE); +} + +TEST_CASE( "Exception 10 Math", "[big_int_t][exceptions][error][math]" ) { + // MathError + static_assert( true == std::is_base_of_v<jau::math::MathErrorBase, jau::math::MathError>); + static_assert( true == std::is_base_of_v<std::exception, jau::math::MathError>); + REQUIRE_THROWS_MATCHES( throwMathError(), jau::math::MathErrorBase, Catch::Matchers::ContainsSubstring("MathError(undefined)") ); + REQUIRE_THROWS_AS( throwMathError(), std::exception); + + static_assert( true == std::is_base_of_v<jau::math::MathRuntimeErrorBase, jau::math::MathInexactError>); + static_assert( true == std::is_base_of_v<jau::math::MathErrorBase, jau::math::MathInexactError>); + static_assert( true == std::is_base_of_v<std::runtime_error, jau::math::MathInexactError>); + static_assert( true == std::is_base_of_v<std::exception, jau::math::MathInexactError>); + REQUIRE_THROWS_MATCHES( throwMathInexactError(), jau::math::MathInexactError, Catch::Matchers::ContainsSubstring("MathError(inexact)") ); + REQUIRE_THROWS_AS( throwMathInexactError(), jau::math::MathRuntimeErrorBase); + REQUIRE_THROWS_AS( throwMathInexactError(), jau::math::MathErrorBase); + REQUIRE_THROWS_AS( throwMathInexactError(), std::runtime_error); + REQUIRE_THROWS_AS( throwMathInexactError(), std::exception); + + static_assert( true == std::is_base_of_v<jau::math::MathRuntimeErrorBase, jau::math::MathOverflowError>); + static_assert( true == std::is_base_of_v<jau::math::MathErrorBase, jau::math::MathOverflowError>); + static_assert( true == std::is_base_of_v<std::overflow_error, jau::math::MathOverflowError>); + static_assert( true == std::is_base_of_v<std::runtime_error, jau::math::MathOverflowError>); + static_assert( true == std::is_base_of_v<std::exception, jau::math::MathOverflowError>); + REQUIRE_THROWS_MATCHES( throwMathOverflowError(), jau::math::MathOverflowError, Catch::Matchers::ContainsSubstring("MathError(overflow)") ); + REQUIRE_THROWS_AS( throwMathOverflowError(), jau::math::MathRuntimeErrorBase); + REQUIRE_THROWS_AS( throwMathOverflowError(), jau::math::MathErrorBase); + REQUIRE_THROWS_AS( throwMathOverflowError(), std::overflow_error); + REQUIRE_THROWS_AS( throwMathOverflowError(), std::runtime_error); + REQUIRE_THROWS_AS( throwMathOverflowError(), std::exception); + + static_assert( true == std::is_base_of_v<jau::math::MathRuntimeErrorBase, jau::math::MathUnderflowError>); + static_assert( true == std::is_base_of_v<jau::math::MathErrorBase, jau::math::MathUnderflowError>); + static_assert( true == std::is_base_of_v<std::underflow_error, jau::math::MathUnderflowError>); + static_assert( true == std::is_base_of_v<std::runtime_error, jau::math::MathUnderflowError>); + static_assert( true == std::is_base_of_v<std::exception, jau::math::MathUnderflowError>); + REQUIRE_THROWS_MATCHES( throwMathUnderflowError(), jau::math::MathUnderflowError, Catch::Matchers::ContainsSubstring("MathError(underflow)") ); + REQUIRE_THROWS_AS( throwMathUnderflowError(), jau::math::MathRuntimeErrorBase); + REQUIRE_THROWS_AS( throwMathUnderflowError(), jau::math::MathErrorBase); + REQUIRE_THROWS_AS( throwMathUnderflowError(), std::underflow_error); + REQUIRE_THROWS_AS( throwMathUnderflowError(), std::runtime_error); + REQUIRE_THROWS_AS( throwMathUnderflowError(), std::exception); + + static_assert( true == std::is_base_of_v<jau::math::MathErrorBase, jau::math::MathDomainError>); + static_assert( true == std::is_base_of_v<std::domain_error, jau::math::MathDomainError>); + static_assert( true == std::is_base_of_v<std::exception, jau::math::MathDomainError>); + REQUIRE_THROWS_MATCHES( throwMathDomainError(), jau::math::MathDomainError, Catch::Matchers::ContainsSubstring("MathError(invalid)") ); + REQUIRE_THROWS_AS( throwMathDomainError(), jau::math::MathErrorBase); + REQUIRE_THROWS_AS( throwMathDomainError(), std::domain_error); + REQUIRE_THROWS_AS( throwMathDomainError(), std::exception); + + static_assert( true == std::is_base_of_v<jau::math::MathErrorBase, jau::math::MathDivByZeroError>); + static_assert( true == std::is_base_of_v<jau::math::MathDomainError, jau::math::MathDivByZeroError>); + static_assert( true == std::is_base_of_v<std::domain_error, jau::math::MathDivByZeroError>); + static_assert( true == std::is_base_of_v<std::exception, jau::math::MathDivByZeroError>); + REQUIRE_THROWS_MATCHES( throwMathDivByZeroError(), jau::math::MathDivByZeroError, Catch::Matchers::ContainsSubstring("MathError(div_by_zero)") ); + REQUIRE_THROWS_AS( throwMathDivByZeroError(), jau::math::MathDomainError); + REQUIRE_THROWS_AS( throwMathDivByZeroError(), jau::math::MathErrorBase); + REQUIRE_THROWS_AS( throwMathDivByZeroError(), std::domain_error); + REQUIRE_THROWS_AS( throwMathDivByZeroError(), std::exception); + REQUIRE_THROWS_AS( throwMathDivByZeroError(), std::exception); +} + +TEST_CASE( "Exception 11 Math", "[big_int_t][exceptions][error][arithmetic][math]" ) { + { + jau::mp::BigInt a = 1, b = 0, r; + REQUIRE_THROWS_MATCHES( r = a / b, jau::math::MathDivByZeroError, Catch::Matchers::ContainsSubstring("div_by_zero") ); + REQUIRE_THROWS_MATCHES( r = a % b, jau::math::MathDivByZeroError, Catch::Matchers::ContainsSubstring("div_by_zero") ); + } + { + jau::mp::BigInt a = jau::mp::BigInt::from_s32(-1), b = jau::mp::BigInt::from_s32(-1), r; + REQUIRE_THROWS_MATCHES( r = a % b, jau::math::MathDomainError, Catch::Matchers::ContainsSubstring("invalid") ); + } +} |