1010
1111#include < algorithm>
1212#include < cassert>
13+ #include < cstddef>
1314#include < deque>
1415#include < iterator>
1516#include < list>
@@ -26,66 +27,66 @@ auto compute_median(auto first, auto last) {
2627 return *middle;
2728}
2829
29- template <class Container , bool Partitioned, class Operation >
30- void bm (std::string operation_name, Operation is_partitioned) {
31- auto bench = [is_partitioned](auto & st) {
32- auto const size = st.range (0 );
33- using ValueType = typename Container::value_type;
34- Container c;
35- std::generate_n (std::back_inserter (c), size, [] { return Generate<ValueType>::random (); });
36-
37- // Partition the container in two equally-sized halves, ensuring the median
38- // value appears in the left half. Note that the median value isn't located
39- // in the middle -- this isn't std::nth_element.
40- ValueType median = compute_median (c.begin (), c.end ());
41- auto pred = [median](auto const & element) { return element <= median; };
42- std::partition (c.begin (), c.end (), pred);
43- assert (std::is_partitioned (c.begin (), c.end (), pred));
44-
45- if constexpr (!Partitioned) {
46- // De-partition the container by swapping the element containing the median
47- // value with the last one.
48- auto median_it = std::find (c.begin (), c.end (), median);
49- auto last_it = std::next (c.begin (), c.size () - 1 );
50- std::iter_swap (median_it, last_it);
51- assert (!std::is_partitioned (c.begin (), c.end (), pred));
52- }
53-
54- for ([[maybe_unused]] auto _ : st) {
55- auto result = is_partitioned (c.begin (), c.end (), pred);
56- benchmark::DoNotOptimize (result);
57- benchmark::DoNotOptimize (c);
58- benchmark::ClobberMemory ();
59- }
60- };
61- benchmark::RegisterBenchmark (operation_name, bench)->Arg (32 )->Arg (1024 )->Arg (8192 );
62- }
63-
6430int main (int argc, char ** argv) {
65- auto std_is_partitioned = [](auto first, auto last, auto pred) { return std::is_partitioned (first, last, pred); };
66- auto ranges_is_partitioned = [](auto first, auto last, auto pred) {
67- return std::ranges::is_partitioned (first, last, pred);
31+ auto std_is_partitioned = [](auto first, auto last, auto pred) { return std::is_partitioned (first, last, pred); };
32+
33+ auto bm = []<class Container , bool Partitioned>(std::string name, auto is_partitioned) {
34+ benchmark::RegisterBenchmark (
35+ name,
36+ [is_partitioned](auto & st) {
37+ std::size_t const size = st.range (0 );
38+ using ValueType = typename Container::value_type;
39+ Container c;
40+ std::generate_n (std::back_inserter (c), size, [] { return Generate<ValueType>::random (); });
41+
42+ // Partition the container in two equally-sized halves, ensuring the median
43+ // value appears in the left half. Note that the median value isn't located
44+ // in the middle -- this isn't std::nth_element.
45+ ValueType median = compute_median (c.begin (), c.end ());
46+ auto pred = [median](auto const & element) { return element <= median; };
47+ std::partition (c.begin (), c.end (), pred);
48+ assert (std::is_partitioned (c.begin (), c.end (), pred));
49+
50+ if constexpr (!Partitioned) {
51+ // De-partition the container by swapping the element containing the median
52+ // value with the last one.
53+ auto median_it = std::find (c.begin (), c.end (), median);
54+ auto last_it = std::next (c.begin (), c.size () - 1 );
55+ std::iter_swap (median_it, last_it);
56+ assert (!std::is_partitioned (c.begin (), c.end (), pred));
57+ }
58+
59+ for ([[maybe_unused]] auto _ : st) {
60+ benchmark::DoNotOptimize (c);
61+ auto result = is_partitioned (c.begin (), c.end (), pred);
62+ benchmark::DoNotOptimize (result);
63+ }
64+ })
65+ ->Arg (32 )
66+ ->Arg (1024 )
67+ ->Arg (8192 );
6868 };
6969
7070 // std::is_partitioned
71- bm<std::vector<int >, true >(" std::is_partitioned(vector<int>) (partitioned)" , std_is_partitioned);
72- bm<std::vector<int >, false >(" std::is_partitioned(vector<int>) (not partitioned )" , std_is_partitioned);
71+ bm. operator () <std::vector<int >, true >(" std::is_partitioned(vector<int>) (partitioned)" , std_is_partitioned);
72+ bm. operator () <std::vector<int >, false >(" std::is_partitioned(vector<int>) (unpartitioned )" , std_is_partitioned);
7373
74- bm<std::deque<int >, true >(" std::is_partitioned(deque<int>) (partitioned)" , std_is_partitioned);
75- bm<std::deque<int >, false >(" std::is_partitioned(deque<int>) (not partitioned )" , std_is_partitioned);
74+ bm. operator () <std::deque<int >, true >(" std::is_partitioned(deque<int>) (partitioned)" , std_is_partitioned);
75+ bm. operator () <std::deque<int >, false >(" std::is_partitioned(deque<int>) (unpartitioned )" , std_is_partitioned);
7676
77- bm<std::list<int >, true >(" std::is_partitioned(list<int>) (partitioned)" , std_is_partitioned);
78- bm<std::list<int >, false >(" std::is_partitioned(list<int>) (not partitioned )" , std_is_partitioned);
77+ bm. operator () <std::list<int >, true >(" std::is_partitioned(list<int>) (partitioned)" , std_is_partitioned);
78+ bm. operator () <std::list<int >, false >(" std::is_partitioned(list<int>) (unpartitioned )" , std_is_partitioned);
7979
8080 // ranges::is_partitioned
81- bm<std::vector<int >, true >(" ranges::is_partitioned(vector<int>) (partitioned)" , ranges_is_partitioned);
82- bm<std::vector<int >, false >(" ranges::is_partitioned(vector<int>) (not partitioned)" , ranges_is_partitioned);
81+ bm.operator ()<std::vector<int >, true >(" rng::is_partitioned(vector<int>) (partitioned)" , std::ranges::is_partitioned);
82+ bm.operator ()<std::vector<int >, false >(
83+ " rng::is_partitioned(vector<int>) (unpartitioned)" , std::ranges::is_partitioned);
8384
84- bm<std::deque<int >, true >(" ranges ::is_partitioned(deque<int>) (partitioned)" , ranges_is_partitioned );
85- bm<std::deque<int >, false >(" ranges ::is_partitioned(deque<int>) (not partitioned )" , ranges_is_partitioned );
85+ bm. operator () <std::deque<int >, true >(" rng ::is_partitioned(deque<int>) (partitioned)" , std::ranges::is_partitioned );
86+ bm. operator () <std::deque<int >, false >(" rng ::is_partitioned(deque<int>) (unpartitioned )" , std::ranges::is_partitioned );
8687
87- bm<std::list<int >, true >(" ranges ::is_partitioned(list<int>) (partitioned)" , ranges_is_partitioned );
88- bm<std::list<int >, false >(" ranges ::is_partitioned(list<int>) (not partitioned )" , ranges_is_partitioned );
88+ bm. operator () <std::list<int >, true >(" rng ::is_partitioned(list<int>) (partitioned)" , std::ranges::is_partitioned );
89+ bm. operator () <std::list<int >, false >(" rng ::is_partitioned(list<int>) (unpartitioned )" , std::ranges::is_partitioned );
8990
9091 benchmark::Initialize (&argc, argv);
9192 benchmark::RunSpecifiedBenchmarks ();
0 commit comments