Skip to content

Commit

Permalink
Merge pull request #197 from Morwenn/develop
Browse files Browse the repository at this point in the history
Release 1.12.1
  • Loading branch information
Morwenn committed Dec 16, 2021
2 parents f081ed4 + ce9b49e commit 3f4044e
Show file tree
Hide file tree
Showing 64 changed files with 944 additions and 439 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.8.0)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

project(cpp-sort VERSION 1.12.0 LANGUAGES CXX)
project(cpp-sort VERSION 1.12.1 LANGUAGES CXX)

include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
Expand Down
4 changes: 2 additions & 2 deletions README.md
@@ -1,5 +1,5 @@
[![Latest Release](https://img.shields.io/badge/release-1.12.0-blue.svg)](https://github.com/Morwenn/cpp-sort/releases/tag/1.12.0)
[![Conan Package](https://img.shields.io/badge/conan-cpp--sort%2F1.12.0-blue.svg)](https://conan.io/center/cpp-sort?version=1.12.0)
[![Latest Release](https://img.shields.io/badge/release-1.12.1-blue.svg)](https://github.com/Morwenn/cpp-sort/releases/tag/1.12.1)
[![Conan Package](https://img.shields.io/badge/conan-cpp--sort%2F1.12.1-blue.svg)](https://conan.io/center/cpp-sort?version=1.12.1)
[![Code Coverage](https://codecov.io/gh/Morwenn/cpp-sort/branch/develop/graph/badge.svg)](https://codecov.io/gh/Morwenn/cpp-sort)

> *It would be nice if only one or two of the sorting methods would dominate all of the others,
Expand Down
2 changes: 1 addition & 1 deletion conanfile.py
Expand Up @@ -10,7 +10,7 @@

class CppSortConan(ConanFile):
name = "cpp-sort"
version = "1.12.0"
version = "1.12.1"
description = "Additional sorting algorithms & related tools"
topics = "conan", "cpp-sort", "sorting", "algorithms"
url = "https://github.com/Morwenn/cpp-sort"
Expand Down
2 changes: 1 addition & 1 deletion docs/Home.md
@@ -1,4 +1,4 @@
Welcome to the **cpp-sort 1.12.0** documentation!
Welcome to the **cpp-sort 1.12.1** documentation!

You probably read the introduction in the README, so I won't repeat it here. This wiki contains documentation about the library: basic documentation about the many sorting tools and how to use them, documentation about the additional utilities provided by the library and even some detailed tutorials if you ever want to write your own sorters or sorter adapters. This main page explains a few general things that didn't quite fit in other parts of the documentation.

Expand Down
2 changes: 2 additions & 0 deletions docs/Miscellaneous-utilities.md
Expand Up @@ -247,6 +247,8 @@ using make_index_range = make_integer_range<std::size_t, Begin, End, Step>;

`size` is a function that can be used to get the size of an iterable. It is equivalent to the C++17 function [`std::size`][std-size] but has an additional tweak so that, if the iterable is not a fixed-size C array and doesn't have a `size` method, it calls `std::distance(std::begin(iter), std::end(iter))` on the iterable. Therefore, this function can also be used for `std::forward_list` as well as some implementations of ranges.

*Changed in version 1.12.1:* `utility::size()` now also works for collections that only provide non-`const` `begin()` and `end()`.

### Sorting network tools

```cpp
Expand Down
6 changes: 4 additions & 2 deletions docs/Sorters.md
Expand Up @@ -309,7 +309,7 @@ This sorter also has the following dedicated algorithms when used together with

None of the container-aware algorithms invalidates iterators.

### `slab_sort`
### `slab_sorter`

```cpp
#include <cpp-sort/sorters/slab_sorter.h>
Expand All @@ -319,12 +319,14 @@ Implements a variant of slabsort, a rather slow but highly adaptive algorithm de

| Best | Average | Worst | Memory | Stable | Iterators |
| ----------- | ----------- | ----------- | ----------- | ----------- | ------------- |
| n | n log n | n log n | n | No | Random-access |
| n | n log n | n log n | n | No | Bidirectional |

This algorithm actually uses a rather big amount of memory but scales better than other O(n log n) algorithms of the library described as "slow" when the collections get bigger.

*New in version 1.10.0*

*Changed in version 1.12.1:* `slab_sorter` now works with bidirectional iterators.

### `smooth_sorter`

```cpp
Expand Down
4 changes: 2 additions & 2 deletions docs/Tooling.md
Expand Up @@ -51,10 +51,10 @@ The same options exist without the `CPPSORT_` prefix exist, but are deprecated.
conan search cpp-sort --remote=conan-center
```

And then install any version to your local cache as follows (here with version 1.12.0):
And then install any version to your local cache as follows (here with version 1.12.1):

```sh
conan install cpp-sort/1.12.0
conan install cpp-sort/1.12.1
```

The packages downloaded from conan-center are minimal and only contain the files required to use **cpp-sort** as a library: the headers, CMake files and licensing information. If you need anything else you have to build your own package with the `conanfile.py` available in this repository.
Expand Down
206 changes: 111 additions & 95 deletions docs/Writing-a-bubble_sorter.md

Large diffs are not rendered by default.

39 changes: 17 additions & 22 deletions examples/bubble_sorter.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017 Morwenn
* Copyright (c) 2015-2021 Morwenn
* SPDX-License-Identifier: MIT
*/
#include <cstddef>
Expand All @@ -15,22 +15,18 @@

namespace detail
{
template<
typename ForwardIterator,
typename StrictWeakOrdering
>
auto bubble_sort(ForwardIterator first, std::size_t size,
StrictWeakOrdering compare)
template<typename ForwardIterator, typename Compare>
auto bubble_sort(ForwardIterator first, std::size_t size, Compare compare)
-> void
{
if (size < 2) return;

auto&& comp = cppsort::utility::as_function(compare);

while (--size) {
ForwardIterator current = first;
ForwardIterator next = std::next(current);
for (std::size_t i = 0 ; i < size ; ++i) {
auto current = first;
auto next = std::next(current);
for (std::size_t i = 0; i < size; ++i) {
if (comp(*next, *current)) {
using cppsort::utility::iter_swap;
iter_swap(current, next);
Expand All @@ -46,18 +42,17 @@ namespace detail
// Pair of iterators overload
template<
typename ForwardIterator,
typename StrictWeakOrdering = std::less<>,
typename Compare = std::less<>,
typename = std::enable_if_t<not cppsort::is_projection_iterator_v<
StrictWeakOrdering, ForwardIterator
Compare, ForwardIterator
>>
>
auto operator()(ForwardIterator first, ForwardIterator last,
StrictWeakOrdering compare={}) const
auto operator()(ForwardIterator first, ForwardIterator last, Compare compare={}) const
-> void
{
static_assert(
std::is_base_of<
std::forward_iterator_tag,
iterator_category,
typename std::iterator_traits<ForwardIterator>::iterator_category
>::value,
"bubble_sorter requires at least forward iterators"
Expand All @@ -70,17 +65,17 @@ namespace detail
// Iterable overload
template<
typename ForwardIterable,
typename StrictWeakOrdering = std::less<>,
typename Compare = std::less<>,
typename = std::enable_if_t<not cppsort::is_projection_v<
StrictWeakOrdering, ForwardIterable
Compare, ForwardIterable
>>
>
auto operator()(ForwardIterable&& iterable, StrictWeakOrdering compare={}) const
auto operator()(ForwardIterable&& iterable, Compare compare={}) const
-> void
{
static_assert(
std::is_base_of<
std::forward_iterator_tag,
iterator_category,
typename std::iterator_traits<decltype(std::begin(iterable))>::iterator_category
>::value,
"bubble_sorter requires at least forward iterators"
Expand Down Expand Up @@ -118,7 +113,7 @@ int main()

// Fill the collection in sorted order
std::array<int, 8> collection;
std::iota(std::begin(collection), std::end(collection), 0);
std::iota(collection.begin(), collection.end(), 0);

// Projection to sort in descending order
auto projection = [](int n) { return -n; };
Expand All @@ -130,6 +125,6 @@ int main()
// Bubble sort the collection
bubble_sort(to_sort, projection);
// Check that it is sorted in descending order
assert(std::is_sorted(std::begin(to_sort), std::end(to_sort), std::greater<>{}));
} while (std::next_permutation(std::begin(collection), std::end(collection)));
assert(std::is_sorted(to_sort.begin(), to_sort.end(), std::greater<>{}));
} while (std::next_permutation(collection.begin(), collection.end()));
}
2 changes: 1 addition & 1 deletion include/cpp-sort/adapters/verge_adapter.h
Expand Up @@ -51,7 +51,7 @@ namespace cppsort
{
static_assert(
std::is_base_of<
std::random_access_iterator_tag,
iterator_category,
iterator_category_t<RandomAccessIterator>
>::value,
"verge_adapter requires at least random-access iterators"
Expand Down
11 changes: 2 additions & 9 deletions include/cpp-sort/detail/associate_iterator.h
Expand Up @@ -196,7 +196,7 @@ namespace detail
auto operator*() const
-> decltype(*base())
{
return *base();
return *_it;
}

CPPSORT_ATTRIBUTE_NODISCARD
Expand Down Expand Up @@ -256,18 +256,11 @@ namespace detail
////////////////////////////////////////////////////////////
// Elements access operators

CPPSORT_ATTRIBUTE_NODISCARD
auto operator[](difference_type pos)
-> decltype(base()[pos])
{
return base()[pos];
}

CPPSORT_ATTRIBUTE_NODISCARD
auto operator[](difference_type pos) const
-> decltype(base()[pos])
{
return base()[pos];
return _it[pos];
}

////////////////////////////////////////////////////////////
Expand Down
15 changes: 13 additions & 2 deletions include/cpp-sort/detail/bitops.h
Expand Up @@ -11,13 +11,23 @@
#include <cstddef>
#include <limits>
#include <type_traits>
#include "../detail/attributes.h"
#include "../detail/config.h"
#include "../detail/type_traits.h"

namespace cppsort
{
namespace detail
{
// Cast signed value to unsigned one
template<typename Integer>
CPPSORT_ATTRIBUTE_NODISCARD
constexpr auto as_unsigned(Integer value)
-> std::make_unsigned_t<Integer>
{
return static_cast<std::make_unsigned_t<Integer>>(value);
}

// Returns 2^floor(log2(n)), assumes n > 0
template<typename Unsigned>
constexpr auto hyperfloor(Unsigned n)
Expand Down Expand Up @@ -96,7 +106,7 @@ namespace detail
constexpr auto half(Integer value)
-> detail::enable_if_t<std::is_integral<Integer>::value, Integer>
{
return static_cast<Integer>(static_cast<std::make_unsigned_t<Integer>>(value) / 2);
return static_cast<Integer>(as_unsigned(value) / 2);
}

template<typename T>
Expand All @@ -114,7 +124,8 @@ namespace detail
constexpr auto has_single_bit(Integer n) noexcept
-> bool
{
auto x = static_cast<std::make_unsigned_t<Integer>>(n);
CPPSORT_ASSERT(n >= 0);
auto x = as_unsigned(n);
return x != 0 && (x & (x - 1)) == 0;
}

Expand Down
5 changes: 3 additions & 2 deletions include/cpp-sort/detail/drop_merge_sort.h
Expand Up @@ -51,8 +51,9 @@ namespace detail
{
using utility::iter_move;

auto size = std::distance(begin, end);
if (size < 2) return;
if (begin == end || std::next(begin) == end) {
return;
}

auto&& comp = utility::as_function(compare);
auto&& proj = utility::as_function(projection);
Expand Down
2 changes: 1 addition & 1 deletion include/cpp-sort/detail/immovable_vector.h
Expand Up @@ -45,7 +45,7 @@ namespace detail
////////////////////////////////////////////////////////////
// Construction

immovable_vector(std::ptrdiff_t n):
explicit immovable_vector(std::ptrdiff_t n):
capacity_(n),
memory_(
static_cast<T*>(::operator new(n * sizeof(T)))
Expand Down
26 changes: 10 additions & 16 deletions include/cpp-sort/detail/merge_insertion_sort.h
Expand Up @@ -79,7 +79,7 @@ namespace detail
auto operator*() const
-> reference
{
return _it[_size - 1];
return *std::next(_it, _size - 1);
}

CPPSORT_ATTRIBUTE_NODISCARD
Expand Down Expand Up @@ -110,7 +110,7 @@ namespace detail
auto operator--()
-> group_iterator&
{
_it -= _size;
std::advance(_it, -_size);
return *this;
}

Expand All @@ -125,7 +125,7 @@ namespace detail
auto operator+=(difference_type increment)
-> group_iterator&
{
std::advance(_it, _size * increment);
_it += _size * increment;
return *this;
}

Expand All @@ -139,18 +139,11 @@ namespace detail
////////////////////////////////////////////////////////////
// Elements access operators

CPPSORT_ATTRIBUTE_NODISCARD
auto operator[](difference_type pos)
-> decltype(base()[pos * size() + size() - 1])
{
return base()[pos * size() + size() - 1];
}

CPPSORT_ATTRIBUTE_NODISCARD
auto operator[](difference_type pos) const
-> decltype(base()[pos * size() + size() - 1])
-> decltype(base()[pos])
{
return base()[pos * size() + size() - 1];
return _it[pos * _size + _size - 1];
}

////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -241,7 +234,7 @@ namespace detail
friend auto iter_swap(group_iterator lhs, group_iterator rhs)
-> void
{
detail::swap_ranges_inner(lhs.base(), lhs.base() + lhs.size(), rhs.base());
detail::swap_ranges_inner(lhs.base(), std::next(lhs.base(), lhs.size()), rhs.base());
}

private:
Expand All @@ -255,18 +248,19 @@ namespace detail

template<typename Iterator>
CPPSORT_ATTRIBUTE_NODISCARD
auto make_group_iterator(Iterator it, difference_type_t<group_iterator<Iterator>> size)
auto make_group_iterator(Iterator it, difference_type_t<Iterator> size)
-> group_iterator<Iterator>
{
return { it, size };
}

template<typename Iterator>
CPPSORT_ATTRIBUTE_NODISCARD
auto make_group_iterator(group_iterator<Iterator> it, difference_type_t<group_iterator<Iterator>> size)
auto make_group_iterator(group_iterator<Iterator> it, difference_type_t<Iterator> size)
-> group_iterator<Iterator>
{
return { it.base(), size * it.size() };
size *= it.size();
return { it.base(), size };
}

////////////////////////////////////////////////////////////
Expand Down
9 changes: 4 additions & 5 deletions include/cpp-sort/detail/poplar_sort.h
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2020 Morwenn
* Copyright (c) 2016-2021 Morwenn
* SPDX-License-Identifier: MIT
*/
#ifndef CPPSORT_DETAIL_POPLAR_SORT_H_
Expand Down Expand Up @@ -104,8 +104,7 @@ namespace detail
Compare compare, Projection projection)
-> void
{
using poplar_size_t = std::make_unsigned_t<difference_type_t<RandomAccessIterator>>;
poplar_size_t size = last - first;
auto size = as_unsigned(last - first);
if (size < 16) {
// A sorted collection is a valid poplar heap;
// when the heap is small, using insertion sort
Expand Down Expand Up @@ -176,7 +175,7 @@ namespace detail
if (poplars.back().size == 1) return;
auto& back = poplars.back();
auto old_end = back.end;
auto new_size = (back.size - 1) / 2;
poplar_size_t new_size = (back.size - 1) / 2;
auto middle = back.begin + new_size;
back.end = middle;
back.size = new_size;
Expand All @@ -185,7 +184,7 @@ namespace detail
} else {
auto& back = poplars.back();
auto old_end = back.end;
auto new_size = (back.size - 1) / 2;
poplar_size_t new_size = (back.size - 1) / 2;
auto middle = back.begin + new_size;
back.end = middle;
back.size = new_size;
Expand Down

0 comments on commit 3f4044e

Please sign in to comment.