Skip to content

Commit 31dd8e9

Browse files
authored
Merge pull request #216 from Morwenn/develop
Release 1.15.0
2 parents 29b593a + 6605d2c commit 31dd8e9

File tree

165 files changed

+16331
-962
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

165 files changed

+16331
-962
lines changed

.github/workflows/build-ubuntu.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2021 Morwenn
1+
# Copyright (c) 2021-2022 Morwenn
22
# SPDX-License-Identifier: MIT
33

44
name: Ubuntu Builds
@@ -23,13 +23,13 @@ on:
2323

2424
jobs:
2525
build:
26-
runs-on: ubuntu-18.04
26+
runs-on: ubuntu-20.04
2727

2828
strategy:
2929
fail-fast: false
3030
matrix:
3131
cxx:
32-
- g++-5
32+
- g++-7
3333
- clang++-6.0
3434
config:
3535
# Release build
@@ -46,8 +46,8 @@ jobs:
4646
- uses: actions/checkout@v3
4747

4848
- name: Install GCC
49-
if: ${{matrix.cxx == 'g++-5'}}
50-
run: sudo apt-get install -y g++-5
49+
if: ${{matrix.cxx == 'g++-7'}}
50+
run: sudo apt-get install -y g++-7
5151

5252
- name: Install Clang
5353
if: ${{matrix.cxx == 'clang++-6.0'}}

CMakeLists.txt

+35-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# Copyright (c) 2015-2022 Morwenn
1+
# Copyright (c) 2015-2023 Morwenn
22
# SPDX-License-Identifier: MIT
33

44
cmake_minimum_required(VERSION 3.8.0)
55

66
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
77

8-
project(cpp-sort VERSION 1.14.0 LANGUAGES CXX)
8+
project(cpp-sort VERSION 1.15.0 LANGUAGES CXX)
99

1010
include(CMakePackageConfigHelpers)
1111
include(GNUInstallDirs)
@@ -15,19 +15,50 @@ option(BUILD_TESTING "Build the cpp-sort test suite (deprecated, use CPPSORT_BUI
1515
option(BUILD_EXAMPLES "Build the cpp-sort examples (deprecated, use CPPSORT_BUILD_EXAMPLES)" OFF)
1616
option(CPPSORT_BUILD_TESTING "Build the cpp-sort test suite" ${BUILD_TESTING})
1717
option(CPPSORT_BUILD_EXAMPLES "Build the cpp-sort examples" ${BUILD_EXAMPLES})
18+
option(CPPSORT_ENABLE_AUDITS "Enable assertions in the library" OFF)
19+
option(CPPSORT_ENABLE_ASSERTIONS "Enable assertions in the library" ${CPPSORT_ENABLE_AUDITS})
20+
option(CPPSORT_USE_LIBASSERT "Use libassert for assertions (experimental)" OFF)
21+
22+
# Optionally use libassert for assertions
23+
if (CPPSORT_USE_LIBASSERT)
24+
include(DownloadProject)
25+
download_project(PROJ libassert
26+
GIT_REPOSITORY https://github.com/jeremy-rifkin/libassert
27+
GIT_TAG v1.2
28+
UPDATE_DISCONNECTED 1
29+
)
30+
add_subdirectory(${libassert_SOURCE_DIR} ${libassert_BINARY_DIR})
31+
endif()
1832

1933
# Create cpp-sort library and configure it
2034
add_library(cpp-sort INTERFACE)
2135
target_include_directories(cpp-sort INTERFACE
22-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
36+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
2337
$<INSTALL_INTERFACE:include>
2438
)
2539

2640
target_compile_features(cpp-sort INTERFACE cxx_std_14)
2741

2842
# MSVC won't work without a stricter standard compliance
2943
if (MSVC)
30-
target_compile_options(cpp-sort INTERFACE /permissive-)
44+
target_compile_options(cpp-sort INTERFACE
45+
/permissive-
46+
/Zc:preprocessor
47+
)
48+
endif()
49+
50+
# Handle diagnostic options
51+
if (CPPSORT_ENABLE_ASSERTIONS)
52+
target_compile_definitions(cpp-sort INTERFACE CPPSORT_ENABLE_ASSERTIONS)
53+
endif()
54+
if (CPPSORT_ENABLE_AUDITS)
55+
target_compile_definitions(cpp-sort INTERFACE CPPSORT_ENABLE_AUDITS)
56+
endif()
57+
58+
# Optionally link to libassert
59+
if (CPPSORT_USE_LIBASSERT)
60+
target_link_libraries(cpp-sort INTERFACE assert)
61+
target_compile_definitions(cpp-sort INTERFACE CPPSORT_USE_LIBASSERT)
3162
endif()
3263

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

README.md

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
![cpp-sort logo](docs/images/cpp-sort-logo.svg)
22

3-
[![Latest Release](https://img.shields.io/badge/release-1.14.0-blue.svg)](https://github.com/Morwenn/cpp-sort/releases/tag/1.14.0)
4-
[![Conan Package](https://img.shields.io/badge/conan-cpp--sort%2F1.14.0-blue.svg)](https://conan.io/center/cpp-sort?version=1.14.0)
3+
[![Latest Release](https://img.shields.io/badge/release-1.15.0-blue.svg)](https://github.com/Morwenn/cpp-sort/releases/tag/1.15.0)
4+
[![Conan Package](https://img.shields.io/badge/conan-cpp--sort%2F1.15.0-blue.svg)](https://conan.io/center/recipes/cpp-sort?version=1.15.0)
55
[![Code Coverage](https://codecov.io/gh/Morwenn/cpp-sort/branch/develop/graph/badge.svg)](https://codecov.io/gh/Morwenn/cpp-sort)
66
[![Pitchfork Layout](https://img.shields.io/badge/standard-PFL-orange.svg)](https://github.com/vector-of-bool/pitchfork)
77

@@ -122,23 +122,22 @@ page][benchmarks].
122122
![MacOS builds status](https://github.com/Morwenn/cpp-sort/workflows/MacOS%20Builds/badge.svg?branch=develop)
123123

124124
**cpp-sort** requires C++14 support, and should work with the following compilers:
125-
* g++5.5 or more recent. It is known not to work with some older g++5 versions.
126-
* clang++6.0 or more recent. It should work with clang++ versions all the way back to 3.8, but the CI pipeline doesn't have test for those anymore.
127-
* Visual Studio 2019 version 16.8.3 or more recent, only with `/permissive-`. A few features are still unavailable.
125+
* g++7 or more recent.
126+
* clang++6.0 or more recent (with both libstdc++ and libc++).
128127
* The versions of MinGW-w64 and AppleClang equivalent to the compilers mentioned above.
129-
* Clang is notably tested with both libstdc++ and libc++.
128+
* Visual Studio 2019 version 16.8.3 or more recent, only with `/permissive-`. A few features are unavailable.
129+
* clang-cl corresponding the the Visual Studio version above.
130130

131131
The compilers listed above are the ones used by the CI pipeline, and the library is also tested
132132
with the most recent versions of those compilers on a regular basis. All the other compiler
133133
versions in-between are untested, but should also work. Feel free to open an issue if it isn't the
134134
case.
135135

136136
The features in the library might differ depending on the C++ version used and on the compiler
137-
extensions enabled. Those changes [are documented](https://github.com/Morwenn/cpp-sort/wiki/Changelog)
138-
in the wiki.
137+
extensions enabled. Those changes are documented [in the wiki][changelog].
139138

140139
The main repository contains additional support for standard tooling such as CMake or Conan.
141-
You can read more about those [in the wiki](https://github.com/Morwenn/cpp-sort/wiki/Tooling).
140+
You can read more about those [in the wiki][tooling].
142141

143142
# Thanks
144143

@@ -217,7 +216,7 @@ slightly modified version of Matthew Bentley's [indiesort](https://github.com/ma
217216
comes from Danila Kutenin's [miniselect library](https://github.com/danlark1/miniselect) and uses
218217
Andrei Alexandrescu's [*AdaptiveQuickselect*](https://arxiv.org/abs/1606.00484) algorithm.
219218

220-
* The sorting networks used by `sorting_network_sorter` all come [from this list](http://users.telenet.be/bertdobbelaere/SorterHunter/sorting_networks.html)
219+
* The sorting networks used by `sorting_network_sorter` all come [from this list](https://bertdobbelaere.github.io/sorting_networks_extended.html)
221220
maintained by Bert Dobbelaere. The page has references to the sources of all of the sorting networks
222221
it lists.
223222

@@ -244,6 +243,8 @@ developed by Thøger Rivera-Thorsen.
244243

245244
[adaptive-sort]: https://en.wikipedia.org/wiki/Adaptive_sort
246245
[benchmarks]: https://github.com/Morwenn/cpp-sort/wiki/Benchmarks
246+
[changelog]: https://github.com/Morwenn/cpp-sort/wiki/Changelog
247247
[drop-merge-adapter]: https://github.com/Morwenn/cpp-sort/wiki/Sorter-adapters#drop_merge_adapter
248248
[heap-sorter]: https://github.com/Morwenn/cpp-sort/wiki/Sorters#heap_sorter
249249
[split-adapter]: https://github.com/Morwenn/cpp-sort/wiki/Sorter-adapters#split_adapter
250+
[tooling]: https://github.com/Morwenn/cpp-sort/wiki/Tooling
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2023 Morwenn
3+
* SPDX-License-Identifier: MIT
4+
*/
5+
#include <cstdint>
6+
#include <utility>
7+
#include <cpp-sort/utility/adapter_storage.h>
8+
#include <cpp-sort/utility/metrics_tools.h>
9+
#include <cpp-sort/detail/checkers.h>
10+
#include "rdtsc.h"
11+
12+
////////////////////////////////////////////////////////////
13+
// Tag
14+
15+
struct cpu_cycles_tag {};
16+
17+
////////////////////////////////////////////////////////////
18+
// Metric
19+
20+
template<typename Sorter>
21+
struct cpu_cycles:
22+
cppsort::utility::adapter_storage<Sorter>,
23+
cppsort::detail::check_iterator_category<Sorter>,
24+
cppsort::detail::check_is_always_stable<Sorter>
25+
{
26+
using tag_t = cpu_cycles_tag;
27+
using metric_t = cppsort::utility::metric<unsigned long long, tag_t>;
28+
29+
cpu_cycles() = default;
30+
31+
constexpr explicit cpu_cycles(Sorter sorter):
32+
cppsort::utility::adapter_storage<Sorter>(std::move(sorter))
33+
{}
34+
35+
template<typename... Args>
36+
auto operator()(Args&&... args) const
37+
-> decltype(
38+
this->get()(std::forward<Args>(args)...),
39+
metric_t(std::declval<unsigned long long>())
40+
)
41+
{
42+
auto start = ::rdtsc();
43+
this->get()(std::forward<Args>(args)...);
44+
auto stop = ::rdtsc();
45+
return metric_t(stop - start);
46+
}
47+
};
48+
49+
////////////////////////////////////////////////////////////
50+
// is_stable specialization
51+
52+
namespace cppsort
53+
{
54+
template<typename Sorter, typename... Args>
55+
struct is_stable<cpu_cycles<Sorter>(Args...)>:
56+
is_stable<Sorter(Args...)>
57+
{};
58+
}

benchmarks/benchmarking-tools/rdtsc.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626

2727
#ifdef _WIN32
2828
#include <intrin.h>
29-
#define rdtsc __rdtsc
29+
inline unsigned long long rdtsc() {
30+
return __rdtsc();
31+
}
3032
#else
3133
#ifdef __i586__
3234
static __inline__ unsigned long long rdtsc() {

benchmarks/errorbar-plot/bench.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020-2021 Morwenn
2+
* Copyright (c) 2020-2023 Morwenn
33
* SPDX-License-Identifier: MIT
44
*/
55
#include <algorithm>
@@ -16,6 +16,7 @@
1616
#include <string>
1717
#include <utility>
1818
#include <vector>
19+
#include <cpp-sort/metrics/running_time.h>
1920
#include <cpp-sort/sorters.h>
2021
#include "../benchmarking-tools/distributions.h"
2122
#include "../benchmarking-tools/filesystem.h"
@@ -36,7 +37,7 @@ using sort_f = void (*)(collection_t&);
3637
std::pair<std::string, sort_f> sorts[] = {
3738
{ "heap_sort", cppsort::heap_sort },
3839
{ "poplar_sort", cppsort::poplar_sort },
39-
{ "smooth_sort", cppsort::smooth_sort }
40+
{ "smooth_sort", cppsort::smooth_sort },
4041
};
4142

4243
// Distribution to benchmark against
@@ -95,11 +96,10 @@ int main(int argc, char** argv)
9596
while (total_end - total_start < max_run_time && times.size() < max_runs_per_size) {
9697
collection_t collection;
9798
distribution(std::back_inserter(collection), size);
98-
auto start = clock_type::now();
99-
sort.second(collection);
100-
auto end = clock_type::now();
99+
auto do_sort = cppsort::metrics::running_time<sort_f>(sort.second);
100+
auto duration = do_sort(collection);
101101
assert(std::is_sorted(std::begin(collection), std::end(collection)));
102-
times.push_back(std::chrono::duration<double, std::milli>(end - start).count());
102+
times.push_back(duration.value().count());
103103
total_end = clock_type::now();
104104
}
105105

benchmarks/inversions/inv-bench.cpp

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020-2022 Morwenn
2+
* Copyright (c) 2020-2023 Morwenn
33
* SPDX-License-Identifier: MIT
44
*/
55
#include <cassert>
@@ -13,10 +13,11 @@
1313
#include <string>
1414
#include <utility>
1515
#include <vector>
16+
#include <cpp-sort/adapters.h>
1617
#include <cpp-sort/sorters.h>
18+
#include "../benchmarking-tools/cpu_cycles.h"
1719
#include "../benchmarking-tools/distributions.h"
1820
#include "../benchmarking-tools/filesystem.h"
19-
#include "../benchmarking-tools/rdtsc.h"
2021

2122
using namespace std::chrono_literals;
2223

@@ -31,9 +32,9 @@ using collection_t = std::vector<value_t>;
3132
// Sorting algorithms to benchmark
3233
using sort_f = void (*)(collection_t&);
3334
std::pair<std::string, sort_f> sorts[] = {
34-
{ "drop_merge_sort", cppsort::drop_merge_sort },
35-
{ "pdq_sort", cppsort::pdq_sort },
36-
{ "split_sort", cppsort::split_sort },
35+
{ "heap_sort", cppsort::heap_sort },
36+
{ "drop_merge_adapter(heap_sort)", cppsort::drop_merge_adapter<cppsort::heap_sorter>{} },
37+
{ "split_adapter(heap_sort)", cppsort::split_adapter<cppsort::heap_sorter>{} },
3738
};
3839

3940
// Size of the collections to sort
@@ -92,15 +93,13 @@ int main(int argc, char* argv[])
9293

9394
auto total_start = clock_type::now();
9495
auto total_end = clock_type::now();
95-
while (std::chrono::duration_cast<std::chrono::seconds>(total_end - total_start) < max_run_time &&
96-
cycles.size() < max_runs_per_size) {
96+
while (total_end - total_start < max_run_time && cycles.size() < max_runs_per_size) {
9797
collection_t collection;
9898
distribution(std::back_inserter(collection), size);
99-
std::uint64_t start = rdtsc();
100-
sort.second(collection);
101-
std::uint64_t end = rdtsc();
99+
auto do_sort = cpu_cycles<sort_f>(sort.second);
100+
auto nb_cycles = do_sort(collection);
102101
assert(std::is_sorted(std::begin(collection), std::end(collection)));
103-
cycles.push_back(double(end - start) / size + 0.5);
102+
cycles.push_back(double(nb_cycles.value()) / size + 0.5);
104103
total_end = clock_type::now();
105104
}
106105

benchmarks/patterns/bars.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ def main():
6262
"pdq_sort",
6363
"quick_sort",
6464
"ska_sort",
65+
"spin_sort",
6566
"std_sort",
66-
"verge_sort",
6767
]
6868

6969
root = pathlib.Path(args.root)

benchmarks/patterns/bench.cpp

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015-2021 Morwenn
2+
* Copyright (c) 2015-2023 Morwenn
33
* SPDX-License-Identifier: MIT
44
*/
55

@@ -36,8 +36,8 @@
3636
#include <utility>
3737
#include <vector>
3838
#include <cpp-sort/sorters.h>
39+
#include "../benchmarking-tools/cpu_cycles.h"
3940
#include "../benchmarking-tools/distributions.h"
40-
#include "../benchmarking-tools/rdtsc.h"
4141

4242
// Type of data to sort during the benchmark
4343
using value_t = double;
@@ -77,8 +77,8 @@ int main()
7777
{ "pdq_sort", cppsort::pdq_sort },
7878
{ "quick_sort", cppsort::quick_sort },
7979
{ "ska_sort", cppsort::ska_sort },
80+
{ "spin_sort", cppsort::spin_sort },
8081
{ "std_sort", cppsort::std_sort },
81-
{ "verge_sort", cppsort::verge_sort },
8282
};
8383

8484
std::size_t sizes[] = { 1'000'000 };
@@ -94,26 +94,25 @@ int main()
9494
distributions_prng.seed(seed);
9595

9696
for (auto size: sizes) {
97-
std::vector<std::uint64_t> cycles;
97+
std::vector<std::uint64_t> cycles_per_element;
9898

9999
auto total_start = clock_type::now();
100100
auto total_end = clock_type::now();
101101
while (total_end - total_start < 5s) {
102102
collection_t collection;
103103
distribution.second(std::back_inserter(collection), size);
104-
std::uint64_t start = rdtsc();
105-
sort.second(collection);
106-
std::uint64_t end = rdtsc();
104+
auto do_sort = cpu_cycles<sort_f>(sort.second);
105+
auto nb_cycles = do_sort(collection);
107106
assert(std::is_sorted(std::begin(collection), std::end(collection)));
108-
cycles.push_back(double(end - start) / size + 0.5);
107+
cycles_per_element.push_back(double(nb_cycles.value()) / size + 0.5);
109108
total_end = clock_type::now();
110109
}
111110

112111
for (std::ostream* stream: {&std::cout, &std::cerr}) {
113112
(*stream) << size << ", " << distribution.first << ", " << sort.first << ", ";
114-
auto it = cycles.begin();
113+
auto it = cycles_per_element.begin();
115114
(*stream) << *it;
116-
while (++it != cycles.end()) {
115+
while (++it != cycles_per_element.end()) {
117116
(*stream) << ", " << *it;
118117
}
119118
(*stream) << std::endl;

0 commit comments

Comments
 (0)