From a02075278e54105d1efe79e2a3f159c86b7e4d45 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Sun, 30 May 2021 21:12:12 -0400 Subject: [PATCH 01/16] Optimize and add ability to configure error printing function --- include/cjdb/contracts.hpp | 51 +++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index b13c846..134d042 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -4,10 +4,47 @@ #ifndef CJDB_CONTRACTS_HPP #define CJDB_CONTRACTS_HPP -#include #include #include +#ifdef _MSC_VER + #define CJDB_PRETTY_FUNCTION __FUNCSIG__ + #define CJDB_FORCE_INLINE __forceinline +#else + #define CJDB_PRETTY_FUNCTION __PRETTY_FUNCTION__ + #define CJDB_FORCE_INLINE [[gnu::always_inline]] inline +#endif // _MSC_VER + +#ifndef CJDB_PRINT_ERROR + #ifdef CJDB_USE_STDIO + #include + + namespace cjdb::contracts_detail { + struct print_error_fn { + CJDB_FORCE_INLINE void operator()(std::string_view message) const noexcept + { + std::fwrite(message.data(), sizeof(char), message.size(), stderr); + } + }; + inline constexpr auto print_error = print_error_fn{}; + } // namespace cjdb::contracts_detail + #else + #include + + namespace cjdb::contracts_detail { + struct print_error_fn { + CJDB_FORCE_INLINE void operator()(std::string_view message) const noexcept + try { + std::cerr.write(message.data(), + static_cast(message.size())); + } catch(...) {} + }; + inline constexpr auto print_error = print_error_fn{}; + } // namespace cjdb::contracts_detail + #endif // CJDB_USE_STDIO + #define CJDB_PRINT_ERROR(MESSAGE) ::cjdb::contracts_detail::print_error(MESSAGE) +#endif // CJDB_PRINT_ERROR + // clang-tidy doesn't yet support this // // #ifndef __cpp_lib_is_constant_evaluated @@ -18,12 +55,6 @@ #define CJDB_ASSERT(...) CJDB_CONTRACT_IMPL("assertion", __VA_ARGS__) #define CJDB_ENSURES(...) CJDB_CONTRACT_IMPL("post-condition", __VA_ARGS__) -#ifdef _MSC_VER - #define CJDB_PRETTY_FUNCTION __FUNCSIG__ -#else - #define CJDB_PRETTY_FUNCTION __PRETTY_FUNCTION__ -#endif // _MSC_VER - namespace cjdb::contracts_detail { #ifdef NDEBUG inline constexpr auto is_debug = false; @@ -39,7 +70,9 @@ namespace cjdb::contracts_detail { if (not result) { if (not std::is_constant_evaluated()) { if constexpr (is_debug) { - std::fprintf(stderr, "%s in `%s`\n", message.data(), function.data()); + CJDB_PRINT_ERROR(message); + CJDB_PRINT_ERROR(function); + CJDB_PRINT_ERROR("`\n"); } } #ifdef _MSC_VER @@ -69,7 +102,7 @@ namespace cjdb::contracts_detail { #define CJDB_CONTRACT_IMPL(CJDB_KIND, ...) \ ::cjdb::contracts_detail::contract_impl(::cjdb::contracts_detail::matches_bool(__VA_ARGS__), \ - __FILE__ ":" CJDB_TO_STRING(__LINE__) ": " CJDB_KIND " `" #__VA_ARGS__ "` failed", \ + __FILE__ ":" CJDB_TO_STRING(__LINE__) ": " CJDB_KIND " `" #__VA_ARGS__ "` failed in `", \ CJDB_PRETTY_FUNCTION) From 6b3371d9e973dbe463826a9204da22d3a07bba78 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Sun, 30 May 2021 21:18:06 -0400 Subject: [PATCH 02/16] Optimize logging by concatenating strings before printing --- include/cjdb/contracts.hpp | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index 134d042..4c0851d 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -1,10 +1,11 @@ + // Copyright (c) Christopher Di Bella. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // #ifndef CJDB_CONTRACTS_HPP #define CJDB_CONTRACTS_HPP -#include +#include #include #ifdef _MSC_VER @@ -21,9 +22,10 @@ namespace cjdb::contracts_detail { struct print_error_fn { - CJDB_FORCE_INLINE void operator()(std::string_view message) const noexcept + template // NOLINTNEXTLINE(modernize-avoid-c-arrays) + CJDB_FORCE_INLINE void operator()(char const(&message)[N]) const noexcept { - std::fwrite(message.data(), sizeof(char), message.size(), stderr); + std::fwrite(message, sizeof(char), N - 1, stderr); } }; inline constexpr auto print_error = print_error_fn{}; @@ -33,10 +35,10 @@ namespace cjdb::contracts_detail { struct print_error_fn { - CJDB_FORCE_INLINE void operator()(std::string_view message) const noexcept + template // NOLINTNEXTLINE(modernize-avoid-c-arrays) + CJDB_FORCE_INLINE void operator()(char const(&message)[N]) const noexcept try { - std::cerr.write(message.data(), - static_cast(message.size())); + std::cerr.write(message, static_cast(N) - 1); } catch(...) {} }; inline constexpr auto print_error = print_error_fn{}; @@ -63,16 +65,24 @@ namespace cjdb::contracts_detail { #endif // NDEBUG struct contract_impl_fn { + template constexpr void operator()(bool const result, - std::string_view const message, - std::string_view const function) const noexcept + char const(&message)[N1], // NOLINT(modernize-avoid-c-arrays) + char const(&function)[N2]) const noexcept // NOLINT(modernize-avoid-c-arrays) { if (not result) { if (not std::is_constant_evaluated()) { - if constexpr (is_debug) { - CJDB_PRINT_ERROR(message); - CJDB_PRINT_ERROR(function); - CJDB_PRINT_ERROR("`\n"); + if constexpr (is_debug) { // NOLINT + constexpr auto& suffix = "`\n"; + constexpr auto message_size = N1 - 1; + constexpr auto function_size = N2 - 1; + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + char full_message[message_size + function_size + sizeof suffix]{}; + auto p = full_message; + std::memcpy(p, message, message_size); + std::memcpy(p += message_size, function, function_size); + std::memcpy(p += function_size, suffix, sizeof suffix); + CJDB_PRINT_ERROR(full_message); } } #ifdef _MSC_VER From ba09c4bd082193fccddd1fb8b6081f056857c751 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Sun, 30 May 2021 21:27:53 -0400 Subject: [PATCH 03/16] Make parameters to print functions const, for consistency --- include/cjdb/contracts.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index 134d042..316c0aa 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -21,7 +21,7 @@ namespace cjdb::contracts_detail { struct print_error_fn { - CJDB_FORCE_INLINE void operator()(std::string_view message) const noexcept + CJDB_FORCE_INLINE void operator()(std::string_view const message) const noexcept { std::fwrite(message.data(), sizeof(char), message.size(), stderr); } @@ -33,7 +33,7 @@ namespace cjdb::contracts_detail { struct print_error_fn { - CJDB_FORCE_INLINE void operator()(std::string_view message) const noexcept + CJDB_FORCE_INLINE void operator()(std::string_view const message) const noexcept try { std::cerr.write(message.data(), static_cast(message.size())); From 732627cc742eff1485139de1a40fab320a2da646 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Sun, 30 May 2021 21:39:40 -0400 Subject: [PATCH 04/16] Use operator<< instead of ostream::write for string_view --- include/cjdb/contracts.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index 316c0aa..e2dd161 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -35,8 +35,7 @@ struct print_error_fn { CJDB_FORCE_INLINE void operator()(std::string_view const message) const noexcept try { - std::cerr.write(message.data(), - static_cast(message.size())); + std::cerr << message; } catch(...) {} }; inline constexpr auto print_error = print_error_fn{}; From c36983179a72add0d8385a82bfcaa4fa2021b3ea Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Sun, 30 May 2021 23:44:39 -0400 Subject: [PATCH 05/16] 'invert' and eliminate repeated code in the stdio and iostream print_error implementations --- include/cjdb/contracts.hpp | 40 +++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index e2dd161..704be89 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -16,31 +16,27 @@ #endif // _MSC_VER #ifndef CJDB_PRINT_ERROR - #ifdef CJDB_USE_STDIO + #ifdef CJDB_USE_IOSTREAM + #include + #else #include + #endif // CJDB_USE_IOSTREAM - namespace cjdb::contracts_detail { - struct print_error_fn { - CJDB_FORCE_INLINE void operator()(std::string_view const message) const noexcept - { - std::fwrite(message.data(), sizeof(char), message.size(), stderr); - } - }; - inline constexpr auto print_error = print_error_fn{}; - } // namespace cjdb::contracts_detail + namespace cjdb::contracts_detail { + struct print_error_fn { + CJDB_FORCE_INLINE void operator()(std::string_view const message) const noexcept + #ifdef CJDB_USE_IOSTREAM + try { + std::clog << message; + } catch(...) {} #else - #include - - namespace cjdb::contracts_detail { - struct print_error_fn { - CJDB_FORCE_INLINE void operator()(std::string_view const message) const noexcept - try { - std::cerr << message; - } catch(...) {} - }; - inline constexpr auto print_error = print_error_fn{}; - } // namespace cjdb::contracts_detail - #endif // CJDB_USE_STDIO + { + std::fwrite(message.data(), sizeof(char), message.size(), stderr); + } + #endif // CJDB_USE_IOSTREAM + }; + inline constexpr auto print_error = print_error_fn{}; + } // namespace cjdb::contracts_detail #define CJDB_PRINT_ERROR(MESSAGE) ::cjdb::contracts_detail::print_error(MESSAGE) #endif // CJDB_PRINT_ERROR From e006adb89ced272aa52f063e79928537603ee1d5 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Sun, 30 May 2021 23:55:04 -0400 Subject: [PATCH 06/16] Switch back to ostream::write --- include/cjdb/contracts.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index 704be89..e731120 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -27,7 +27,7 @@ CJDB_FORCE_INLINE void operator()(std::string_view const message) const noexcept #ifdef CJDB_USE_IOSTREAM try { - std::clog << message; + std::clog.write(message.data(), static_cast(message.size())); } catch(...) {} #else { From 0d289335c9b769fdc06ebb3c563b87947f3b642a Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 19:33:39 -0400 Subject: [PATCH 07/16] Change error printing customization point to a variable (function pointer) instead of a macro --- include/cjdb/contracts.hpp | 78 ++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index e731120..441dbc3 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -7,38 +7,13 @@ #include #include -#ifdef _MSC_VER - #define CJDB_PRETTY_FUNCTION __FUNCSIG__ - #define CJDB_FORCE_INLINE __forceinline -#else - #define CJDB_PRETTY_FUNCTION __PRETTY_FUNCTION__ - #define CJDB_FORCE_INLINE [[gnu::always_inline]] inline -#endif // _MSC_VER - -#ifndef CJDB_PRINT_ERROR - #ifdef CJDB_USE_IOSTREAM - #include - #else - #include - #endif // CJDB_USE_IOSTREAM - - namespace cjdb::contracts_detail { - struct print_error_fn { - CJDB_FORCE_INLINE void operator()(std::string_view const message) const noexcept - #ifdef CJDB_USE_IOSTREAM - try { - std::clog.write(message.data(), static_cast(message.size())); - } catch(...) {} - #else - { - std::fwrite(message.data(), sizeof(char), message.size(), stderr); - } - #endif // CJDB_USE_IOSTREAM - }; - inline constexpr auto print_error = print_error_fn{}; - } // namespace cjdb::contracts_detail - #define CJDB_PRINT_ERROR(MESSAGE) ::cjdb::contracts_detail::print_error(MESSAGE) -#endif // CJDB_PRINT_ERROR +#ifdef CJDB_USE_IOSTREAM + #include +#elif !defined(CJDB_SKIP_STDIO) + #include + #include + #include +#endif // CJDB_USE_IOSTREAM // clang-tidy doesn't yet support this // @@ -50,7 +25,30 @@ #define CJDB_ASSERT(...) CJDB_CONTRACT_IMPL("assertion", __VA_ARGS__) #define CJDB_ENSURES(...) CJDB_CONTRACT_IMPL("post-condition", __VA_ARGS__) -namespace cjdb::contracts_detail { +#ifdef _MSC_VER + #define CJDB_PRETTY_FUNCTION __FUNCSIG__ +#else + #define CJDB_PRETTY_FUNCTION __PRETTY_FUNCTION__ +#endif // _MSC_VER + +namespace cjdb { + void(*print_error)(std::string_view) +#ifndef CJDB_SKIP_STDIO + = [](std::string_view message) { +#ifdef CJDB_USE_IOSTREAM + std::cerr.write(message.data(), static_cast(message.size())); +#else + if (auto const len = message.size(); + std::fwrite(message.data(), sizeof(char), len, stderr) < len) [[unlikely]] + { + throw std::system_error{errno, std::system_category()}; + } +#endif // CJDB_USE_IOSTREAM + } +#endif // !CJDB_SKIP_STDIO + ; + +namespace contracts_detail { #ifdef NDEBUG inline constexpr auto is_debug = false; #else @@ -60,14 +58,19 @@ namespace cjdb::contracts_detail { struct contract_impl_fn { constexpr void operator()(bool const result, std::string_view const message, - std::string_view const function) const noexcept + std::string_view const function) const noexcept(!is_debug) { if (not result) { if (not std::is_constant_evaluated()) { if constexpr (is_debug) { - CJDB_PRINT_ERROR(message); - CJDB_PRINT_ERROR(function); - CJDB_PRINT_ERROR("`\n"); + #ifdef _WIN32 + constexpr auto& suffix = "`\r\n"; + #else + constexpr auto& suffix = "`\n"; + #endif + ::cjdb::print_error(message); + ::cjdb::print_error(function); + ::cjdb::print_error(suffix); } } #ifdef _MSC_VER @@ -94,6 +97,7 @@ namespace cjdb::contracts_detail { }; inline constexpr auto matches_bool = matches_bool_fn{}; } // namespace cjdb::contracts_detail +} // namespace cjdb #define CJDB_CONTRACT_IMPL(CJDB_KIND, ...) \ ::cjdb::contracts_detail::contract_impl(::cjdb::contracts_detail::matches_bool(__VA_ARGS__), \ From 92914b26bff02baf7b2d72e6631c1c8166f722a2 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 19:57:30 -0400 Subject: [PATCH 08/16] Add tests for iostream output --- include/cjdb/contracts.hpp | 2 +- test/CMakeLists.txt | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index 441dbc3..dc64071 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -67,7 +67,7 @@ namespace contracts_detail { constexpr auto& suffix = "`\r\n"; #else constexpr auto& suffix = "`\n"; - #endif + #endif // _WIN32 ::cjdb::print_error(message); ::cjdb::print_error(function); ::cjdb::print_error(suffix); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9ae06ef..60fceda 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,15 +3,22 @@ # function(build_contract filename) set(target "${filename}") + set(target_ios "${filename}_ios") add_executable("${target}" "${filename}.cpp") + add_executable("${target_ios}" "${filename}.cpp") if(MSVC) target_compile_options("${target}" PRIVATE "/permissive-") + target_compile_options("${target_ios}" PRIVATE "/permissive-" "/DCJDB_USE_IOSTREAM") + else() + target_compile_options("${target_ios}" PRIVATE "-DCJDB_USE_IOSTREAM") endif() target_include_directories("${target}" PRIVATE "${CMAKE_SOURCE_DIR}/include") + target_include_directories("${target_ios}" PRIVATE "${CMAKE_SOURCE_DIR}/include") endfunction() build_contract(pass) add_test(test.pass pass) +add_test(test.pass_ios pass_ios) function(test_contract target expected_output) set(args "${CMAKE_SOURCE_DIR}/test/check-failure.py" @@ -23,6 +30,10 @@ function(test_contract target expected_output) add_test(NAME "test.${target}" COMMAND python3 ${args} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") + list(TRANSFORM args APPEND "_ios" AT 1) + add_test(NAME "test.${target}_ios" + COMMAND python3 ${args} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") endfunction() function(test_quiet_contract target expected_output) From 4264c1707dfe0d9b5b4692942a4bde12f3453b37 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 20:00:04 -0400 Subject: [PATCH 09/16] Make clang-tidy happy with namespace closing comment --- include/cjdb/contracts.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index dc64071..f8b59ef 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -96,7 +96,7 @@ namespace contracts_detail { } }; inline constexpr auto matches_bool = matches_bool_fn{}; -} // namespace cjdb::contracts_detail +} // namespace contracts_detail } // namespace cjdb #define CJDB_CONTRACT_IMPL(CJDB_KIND, ...) \ From 09d4baf8ff3b61b574381cd4a5bd8bf0fa9ce256 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 20:10:11 -0400 Subject: [PATCH 10/16] Make print_error an inline variable to silence clang-tidy warning --- include/cjdb/contracts.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index f8b59ef..2e2017c 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -32,7 +32,8 @@ #endif // _MSC_VER namespace cjdb { - void(*print_error)(std::string_view) + using print_error_fn = void(std::string_view); + inline print_error_fn *print_error #ifndef CJDB_SKIP_STDIO = [](std::string_view message) { #ifdef CJDB_USE_IOSTREAM From 43b4f9aad14f919ea56fb72d7e71ab35c1539e87 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 20:26:52 -0400 Subject: [PATCH 11/16] Define a stub for cjdb::print_error even when CJDB_SKIP_STDIO is defined, to avoid UB --- include/cjdb/contracts.hpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index 2e2017c..93b3892 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -34,20 +34,17 @@ namespace cjdb { using print_error_fn = void(std::string_view); inline print_error_fn *print_error -#ifndef CJDB_SKIP_STDIO = [](std::string_view message) { #ifdef CJDB_USE_IOSTREAM std::cerr.write(message.data(), static_cast(message.size())); -#else +#elif !defined(CJDB_SKIP_STDIO) if (auto const len = message.size(); std::fwrite(message.data(), sizeof(char), len, stderr) < len) [[unlikely]] { throw std::system_error{errno, std::system_category()}; } #endif // CJDB_USE_IOSTREAM - } -#endif // !CJDB_SKIP_STDIO - ; + }; namespace contracts_detail { #ifdef NDEBUG From 6977cc1198b91f793a95ded33ee08c0ad7574fcb Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 20:47:46 -0400 Subject: [PATCH 12/16] Update documentation --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2566ac8..f616ceb 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,8 @@ contracts are always checked at compile-time. If the contract's predicate isn't program won't compile. This is a huge advantage over using `` or the GSL's `Expects` and `Ensures` macros. -When optimisations are diabled and `NDEBUG` is not defined as a macro, the contract will check your -predicate at run-time. If the predicate fails, then a diagnostic will be emit, and the program will +When optimisations are disabled and `NDEBUG` is not defined as a macro, the contract will check your +predicate at run-time. If the predicate fails, then a diagnostic will be emitted, and the program will crash. When optimisations are enabled, and `NDEBUG` remains undefined, the program will emit a diagnostic @@ -196,7 +196,11 @@ generation than when the contract isn't used. [See for yourself][__builtin_unrea *Rudimentary testing has identified that neither GCC nor Clang perform optimisations before -the contract. +the contract.* + +### Configuring diagnostics + +By default, diagnostic messages are printed to `stderr` by `std::fwrite`. If `CJDB_USE_IOSTREAM` is defined as a macro, messages are printed with `std::cerr.write` instead. If `CJDB_SKIP_STDIO` is defined as a macro, there is no dependency on either `cstdio` or `iostream` and printing diagnostic messages is a no-op. If you would like to customize how diagnostics are printed, you may set the function pointer `cjdb::print_error` to any function or lambda with the signature `void(std::string_view)`. ### Assertions From d55331084d1a5fc7372c45a01bea13e0a1782faa Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 20:51:08 -0400 Subject: [PATCH 13/16] Minor formatting change --- include/cjdb/contracts.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index 93b3892..f863c64 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -33,8 +33,7 @@ namespace cjdb { using print_error_fn = void(std::string_view); - inline print_error_fn *print_error - = [](std::string_view message) { + inline print_error_fn *print_error = [](std::string_view message) { #ifdef CJDB_USE_IOSTREAM std::cerr.write(message.data(), static_cast(message.size())); #elif !defined(CJDB_SKIP_STDIO) From b8623f578c6b5e5cba77c4a95320b127c7434334 Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 20:57:42 -0400 Subject: [PATCH 14/16] Another formatting change --- include/cjdb/contracts.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index f863c64..a294e8d 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -60,11 +60,11 @@ namespace contracts_detail { if (not result) { if (not std::is_constant_evaluated()) { if constexpr (is_debug) { - #ifdef _WIN32 + #ifdef _WIN32 constexpr auto& suffix = "`\r\n"; - #else + #else constexpr auto& suffix = "`\n"; - #endif // _WIN32 + #endif // _WIN32 ::cjdb::print_error(message); ::cjdb::print_error(function); ::cjdb::print_error(suffix); From e2bc28def20e5a68cd15987292b6cb345a26847f Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 20:57:42 -0400 Subject: [PATCH 15/16] Another formatting change --- include/cjdb/contracts.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index f863c64..5a86058 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -33,7 +33,7 @@ namespace cjdb { using print_error_fn = void(std::string_view); - inline print_error_fn *print_error = [](std::string_view message) { + inline print_error_fn* print_error = [](std::string_view message) { #ifdef CJDB_USE_IOSTREAM std::cerr.write(message.data(), static_cast(message.size())); #elif !defined(CJDB_SKIP_STDIO) @@ -60,11 +60,11 @@ namespace contracts_detail { if (not result) { if (not std::is_constant_evaluated()) { if constexpr (is_debug) { - #ifdef _WIN32 + #ifdef _WIN32 constexpr auto& suffix = "`\r\n"; - #else + #else constexpr auto& suffix = "`\n"; - #endif // _WIN32 + #endif // _WIN32 ::cjdb::print_error(message); ::cjdb::print_error(function); ::cjdb::print_error(suffix); From 994e8c0e3ac12a6bd8a09d4ca98a38ab6707e26c Mon Sep 17 00:00:00 2001 From: Ray Hamel Date: Mon, 31 May 2021 22:32:31 -0400 Subject: [PATCH 16/16] Don't need to copy the whole suffix --- include/cjdb/contracts.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cjdb/contracts.hpp b/include/cjdb/contracts.hpp index 7801b03..7a2cf45 100644 --- a/include/cjdb/contracts.hpp +++ b/include/cjdb/contracts.hpp @@ -75,7 +75,7 @@ namespace contracts_detail { auto p = full_message; std::memcpy(p, message, message_size); std::memcpy(p += message_size, function, function_size); - std::memcpy(p += function_size, suffix, sizeof suffix); + std::memcpy(p += function_size, suffix, sizeof suffix - 1); ::cjdb::print_error(full_message); } }