Skip to content

Commit 6cbfeda

Browse files
committed
Add an audit option to verify is_sorted (off by default)
1 parent 12db113 commit 6cbfeda

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ conan install timsort/1.2.2
130130

131131
A few configuration macros allow `gfx::timsort` and `gfx::timmerge` to emit diagnostic, which might be helpful to diagnose issues:
132132
* Defining `GFX_TIMSORT_ENABLE_ASSERT` inserts assertions in key locations in the algorithm to avoid logic errors.
133+
* Defining `GFX_TIMSORT_ENABLE_AUDIT` inserts assertions that verify pre- and postconditions. These verifications can slow the
134+
algorithm down significantly. Enable the audit only while testing or debugging.
133135
* Defining `GFX_TIMSORT_ENABLE_LOG` inserts logs in key locations, which allow to follow more closely the flow of the algorithm.
134136

135137
**cpp-TimSort** follows semantic versioning and provides the following macros to retrieve the current major, minor

include/gfx/timsort.hpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,22 @@
4444

4545
// Diagnostic selection macros
4646

47-
#ifdef GFX_TIMSORT_ENABLE_ASSERT
47+
#if defined(GFX_TIMSORT_ENABLE_ASSERT) || defined(GFX_TIMSORT_ENABLE_AUDIT)
4848
# include <cassert>
49+
#endif
50+
51+
#ifdef GFX_TIMSORT_ENABLE_ASSERT
4952
# define GFX_TIMSORT_ASSERT(expr) assert(expr)
5053
#else
5154
# define GFX_TIMSORT_ASSERT(expr) ((void)0)
5255
#endif
5356

57+
#ifdef GFX_TIMSORT_ENABLE_AUDIT
58+
# define GFX_TIMSORT_AUDIT(expr) assert(expr)
59+
#else
60+
# define GFX_TIMSORT_AUDIT(expr) ((void)0)
61+
#endif
62+
5463
#ifdef GFX_TIMSORT_ENABLE_LOG
5564
# include <iostream>
5665
# define GFX_TIMSORT_LOG(expr) (std::clog << "# " << __func__ << ": " << expr << std::endl)
@@ -770,7 +779,10 @@ void timmerge(RandomAccessIterator first, RandomAccessIterator middle,
770779
RandomAccessIterator last, Compare compare, Projection projection) {
771780
typedef detail::projection_compare<Compare, Projection> compare_t;
772781
compare_t comp(compare, projection);
782+
GFX_TIMSORT_AUDIT(std::is_sorted(first, middle, comp) && "Precondition");
783+
GFX_TIMSORT_AUDIT(std::is_sorted(middle, last, comp) && "Precondition");
773784
detail::TimSort<RandomAccessIterator, compare_t>::merge(first, middle, last, comp);
785+
GFX_TIMSORT_AUDIT(std::is_sorted(first, last, comp) && "Postcondition");
774786
}
775787

776788
/**
@@ -801,6 +813,7 @@ void timsort(RandomAccessIterator const first, RandomAccessIterator const last,
801813
typedef detail::projection_compare<Compare, Projection> compare_t;
802814
compare_t comp(compare, projection);
803815
detail::TimSort<RandomAccessIterator, compare_t>::sort(first, last, comp);
816+
GFX_TIMSORT_AUDIT(std::is_sorted(first, last, comp) && "Postcondition");
804817
}
805818

806819
/**
@@ -824,6 +837,8 @@ void timsort(RandomAccessIterator const first, RandomAccessIterator const last)
824837

825838
#undef GFX_TIMSORT_ENABLE_ASSERT
826839
#undef GFX_TIMSORT_ASSERT
840+
#undef GFX_TIMSORT_ENABLE_AUDIT
841+
#undef GFX_TIMSORT_AUDIT
827842
#undef GFX_TIMSORT_ENABLE_LOG
828843
#undef GFX_TIMSORT_LOG
829844
#undef GFX_TIMSORT_MOVE

0 commit comments

Comments
 (0)