Skip to content

Commit

Permalink
Add experimental support for libassert
Browse files Browse the repository at this point in the history
  • Loading branch information
Morwenn committed Aug 6, 2023
1 parent 3dd054a commit 733d4be
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 12 deletions.
23 changes: 22 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ option(CPPSORT_BUILD_TESTING "Build the cpp-sort test suite" ${BUILD_TESTING})
option(CPPSORT_BUILD_EXAMPLES "Build the cpp-sort examples" ${BUILD_EXAMPLES})
option(CPPSORT_ENABLE_AUDITS "Enable assertions in the library" OFF)
option(CPPSORT_ENABLE_ASSERTIONS "Enable assertions in the library" ${CPPSORT_ENABLE_AUDITS})
option(CPPSORT_USE_LIBASSERT "Use libassert for assertions (experimental)" OFF)

# Optionally use libassert for assertions
if (CPPSORT_USE_LIBASSERT)
include(DownloadProject)
download_project(PROJ libassert
GIT_REPOSITORY https://github.com/jeremy-rifkin/libassert
GIT_TAG v1.2
UPDATE_DISCONNECTED 1
)
add_subdirectory(${libassert_SOURCE_DIR} ${libassert_BINARY_DIR})
endif()

# Create cpp-sort library and configure it
add_library(cpp-sort INTERFACE)
Expand All @@ -29,7 +41,10 @@ target_compile_features(cpp-sort INTERFACE cxx_std_14)

# MSVC won't work without a stricter standard compliance
if (MSVC)
target_compile_options(cpp-sort INTERFACE /permissive-)
target_compile_options(cpp-sort INTERFACE
/permissive-
/Zc:preprocessor
)
endif()

# Handle diagnostic options
Expand All @@ -40,6 +55,12 @@ if (CPPSORT_ENABLE_AUDITS)
target_compile_definitions(cpp-sort INTERFACE CPPSORT_ENABLE_AUDITS)
endif()

# Optionally link to libassert
if (CPPSORT_USE_LIBASSERT)
target_link_libraries(cpp-sort INTERFACE assert)
target_compile_definitions(cpp-sort INTERFACE CPPSORT_USE_LIBASSERT)
endif()

add_library(cpp-sort::cpp-sort ALIAS cpp-sort)

# Install targets and files
Expand Down
11 changes: 11 additions & 0 deletions docs/Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ The macros `CPPSORT_ENABLE_ASSERTIONS` and `CPPSORT_ENABLE_AUDITS` can be config

*Changed in version 1.15.0*: defining `CPPSORT_ENABLE_AUDITS` now automatically defines `CPPSORT_ENABLE_ASSERTIONS`.

#### Rich assertions with libassert (experimental)

When defined, the macro `CPPSORT_USE_LIBASSERT` makes internal assertions use [libassert][libassert] instead of the standard `assert` macro. This allows assertions to provide additional information when an assertion fires, notably by displaying a full stack trace, and optionally to decompose the asserted expressions. See the library's README for more information.

This option can be enabled from CMake by setting the `CPPSORT_USE_LIBASSERT` to `ON`. See [the Tooling page][tooling-cmake] for more information.

*Note: the support for libassert is still experimental and has not been tested on all supported platforms. Errors are to be expected.*

*New in version 1.15.0*

## Miscellaneous

This wiki also includes a small section about the [original research][original-research] that happened during the conception of the library and the results of this research. While it is not needed to understand how the library works or how to use it, it may be of interest if you want to discover new things about sorting.
Expand All @@ -97,6 +107,7 @@ Hope you have fun!

[assume]: https://en.cppreference.com/w/cpp/language/attributes/assume
[benchmarks]: Benchmarks.md
[libassert]: https://github.com/jeremy-rifkin/libassert
[original-research]: Original-research.md
[quickstart]: Quickstart.md
[swappable]: https://en.cppreference.com/w/cpp/concepts/swappable
Expand Down
4 changes: 3 additions & 1 deletion docs/Tooling.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The project's CMake files offers some options, though they are mainly used to co
* `CPPSORT_STATIC_TESTS`: when `ON`, some tests are executed at compile time instead of runtime, defaults to `OFF`.
* `CPPSORT_ENABLE_ASSERTIONS`: when `ON`, defines the eponymous macro which enables debug assertions from the library's internals, defaults to the value of `CPPSORT_ENABLE_AUDITS`.
* `CPPSORT_ENABLE_AUDITS`: when `ON`, defines the eponymous macro which enables expensive debug assertions from the library's internals, defaults to `OFF`.
* `CPPSORT_USE_LIBASSERT` (experimental): when `ON`, internal assertions use [libassert][libassert] instead of the standard `assert` macro, providing additional information about the errors. Defaults to `OFF`.

Some of those options also exist without the `CPPSORT_` prefix, but they are deprecated. For compatibility reasons, the options with the `CPPSORT_` prefix default to the values of the equivalent unprefixed options.

Expand All @@ -44,7 +45,7 @@ Note: when `CPPSORT_ENABLE_AUDITS` is `ON`, assertions in the library are enable

*New in version 1.13.0:* added the option `CPPSORT_STATIC_TESTS`.

*New in version 1.15.0:* `CPPSORT_ENABLE_ASSERTIONS` and `CPPSORT_ENABLE_AUDITS`.
*New in version 1.15.0:* `CPPSORT_ENABLE_ASSERTIONS`, `CPPSORT_ENABLE_AUDITS` and `CPPSORT_USE_LIBASSERT`.

***WARNING:** options without a `CPPSORT_` prefixed are deprecated in version 1.9.0 and removed in version 2.0.0.*

Expand Down Expand Up @@ -89,3 +90,4 @@ Due to slight markup differences, some pages might not fully render correctly bu
[conan]: https://conan.io/
[conan-center]: https://conan.io/center/cpp-sort
[gollum]: https://github.com/gollum/gollum
[libassert]: https://github.com/jeremy-rifkin/libassert
27 changes: 20 additions & 7 deletions include/cpp-sort/detail/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@

#if defined(CPPSORT_ENABLE_ASSERTIONS)
# include <cassert>
# if defined(CPPSORT_USE_LIBASSERT)
# include <assert.hpp>
# endif
#endif

////////////////////////////////////////////////////////////
Expand All @@ -78,11 +81,21 @@
// explicitly enabled in cpp-sort

#if !defined(NDEBUG) && defined(CPPSORT_ENABLE_ASSERTIONS)
# ifndef CPPSORT_ASSERT
# define CPPSORT_ASSERT(...) assert((__VA_ARGS__))
# if !defined(CPPSORT_ASSERT)
# if defined(CPPSORT_USE_LIBASSERT)
# define CPPSORT_ASSERT(...) ASSERT(__VA_ARGS__)
# else
# define CPPSORT_ARG2(_0, _1, _2, ...) _2
# define CPPSORT_NARG2(...) CPPSORT_ARG2(__VA_ARGS__, 2, 1, 0)
# define CPPSORT_ONE_OR_TWO_ARGS_1(condition) assert(condition)
# define CPPSORT_ONE_OR_TWO_ARGS_2(condition, message) assert(condition && message)
# define CPPSORT_ONE_OR_TWO_ARGS_N(N, ...) CPPSORT_ONE_OR_TWO_ARGS_##N(__VA_ARGS__)
# define CPPSORT_ONE_OR_TWO_ARGS(N, ...) CPPSORT_ONE_OR_TWO_ARGS_N(N, __VA_ARGS__)
# define CPPSORT_ASSERT(...) CPPSORT_ONE_OR_TWO_ARGS(CPPSORT_NARG2(__VA_ARGS__), __VA_ARGS__)
# endif
# endif
#else
# define CPPSORT_ASSERT(...)
# define CPPSORT_ASSERT(...) ((void)0)
#endif

////////////////////////////////////////////////////////////
Expand All @@ -97,7 +110,7 @@
# define CPPSORT_AUDIT(...) CPPSORT_ASSERT(__VA_ARGS__)
# endif
#else
# define CPPSORT_AUDIT(...)
# define CPPSORT_AUDIT(...) ((void)0)
#endif

////////////////////////////////////////////////////////////
Expand All @@ -118,7 +131,7 @@
#elif defined(_MSC_VER)
# define CPPSORT_ASSUME(expression) __assume(expression)
#else
# define CPPSORT_ASSUME(cond)
# define CPPSORT_ASSUME(cond) ((void)0)
#endif

////////////////////////////////////////////////////////////
Expand All @@ -129,13 +142,13 @@
// reached

#if !defined(NDEBUG) && defined(CPPSORT_ENABLE_AUDITS)
# define CPPSORT_UNREACHABLE CPPSORT_ASSERT(false && "unreachable");
# define CPPSORT_UNREACHABLE CPPSORT_ASSERT(false, "unreachable")
#elif defined(__GNUC__) || defined(__clang__)
# define CPPSORT_UNREACHABLE __builtin_unreachable()
#elif defined(_MSC_VER)
# define CPPSORT_UNREACHABLE __assume(false)
#else
# define CPPSORT_UNREACHABLE
# define CPPSORT_UNREACHABLE ((void)0)
#endif

////////////////////////////////////////////////////////////
Expand Down
6 changes: 3 additions & 3 deletions include/cpp-sort/detail/timsort.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* - http://cr.openjdk.java.net/~martin/webrevs/openjdk7/timsort/raw_files/new/src/share/classes/java/util/TimSort.java
*
* Copyright (c) 2011 Fuji, Goro (gfx) <gfuji@cpan.org>.
* Copyright (c) 2015-2022 Morwenn.
* Copyright (c) 2015-2023 Morwenn.
* Copyright (c) 2021 Igor Kushnir <igorkuo@gmail.com>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down Expand Up @@ -565,7 +565,7 @@ namespace detail
dest[len2] = iter_move(cursor1);
}
else {
CPPSORT_ASSERT(len1 != 0 && "comparison function violates its general contract");
CPPSORT_ASSERT(len1 != 0, "comparison function violates its general contract");
CPPSORT_ASSERT(len2 == 0);
CPPSORT_ASSERT(len1 > 1);
detail::move(cursor1, cursor1 + len1, dest);
Expand Down Expand Up @@ -715,7 +715,7 @@ namespace detail
detail::move_backward(cursor1 - len1, cursor1, dest + (1 + len1));
*dest = iter_move(cursor2);
} else {
CPPSORT_ASSERT(len2 != 0 && "comparison function violates its general contract");
CPPSORT_ASSERT(len2 != 0, "comparison function violates its general contract");
CPPSORT_ASSERT(len1 == 0);
CPPSORT_ASSERT(len2 > 1);
detail::move(buffer.get(), buffer.get() + len2, dest - (len2 - 1));
Expand Down

0 comments on commit 733d4be

Please sign in to comment.