based

Opinionated utility library
git clone git://git.dimitrijedobrota.com/based.git
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commitfa32c0655ebccdccc6a4e47a88618f87d3ae14fb
parentb532664244ab0b6c5ba6bf872a1526da2b5af1c7
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateTue, 1 Apr 2025 10:37:37 +0200

Utilize std::iterator_traits for proper handling

Diffstat:
Minclude/based/algorithm.hpp|++++++++-------
Minclude/based/type_traits.hpp|++++++++++++++-

2 files changed, 22 insertions(+), 8 deletions(-)


diff --git a/include/based/algorithm.hpp b/include/based/algorithm.hpp

@@ -16,6 +16,7 @@ decltype(auto) min(T&& lhs, U&& rhs, R r)

return r(rhs, lhs) ? std::forward<U>(rhs) : std::forward<T>(lhs);
}
// returns min element, first if equal
template<BareRegular T, BareRegular U>
requires BareSameAs<T, U>
decltype(auto) min(T&& lhs, U&& rhs)

@@ -26,7 +27,7 @@ decltype(auto) min(T&& lhs, U&& rhs)

// return first min element
template<RegularIterator I, Relation R>
requires std::same_as<typename I::value_type, domain_t<R>>
requires SameAs<iter_value_t<I>, domain_t<R>>
I min_element(I first, I last, R r)
{
if (first == last) {

@@ -46,7 +47,7 @@ I min_element(I first, I last, R r)

template<RegularIterator I>
I min_element(I first, I last)
{
return based::min_element(first, last, std::less<typename I::value_type>());
return based::min_element(first, last, std::less<iter_value_t<I>>());
}
// returns max element, second if equal

@@ -57,6 +58,7 @@ decltype(auto) max(T&& lhs, U&& rhs, R r)

return r(rhs, lhs) ? std::forward<T>(lhs) : std::forward<U>(rhs);
}
// returns max element, second if equal
template<BareRegular T, BareRegular U>
requires BareSameAs<T, U>
decltype(auto) max(T&& lhs, U&& rhs)

@@ -67,7 +69,7 @@ decltype(auto) max(T&& lhs, U&& rhs)

// return last max element
template<RegularIterator I, Relation R>
requires std::same_as<typename I::value_type, domain_t<R>>
requires std::same_as<iter_value_t<I>, domain_t<R>>
I max_element(I first, I last, R r)
{
if (first == last) {

@@ -87,12 +89,12 @@ I max_element(I first, I last, R r)

template<RegularIterator I>
I max_element(I first, I last)
{
return based::max_element(first, last, std::less<typename I::value_type>());
return based::max_element(first, last, std::less<iter_value_t<I>>());
}
// return first min and last max element
template<RegularIterator I, Relation R>
requires std::same_as<typename I::value_type, domain_t<R>>
requires std::same_as<iter_value_t<I>, domain_t<R>>
std::pair<I, I> minmax_element(I first, I last, R r)
{
if (first == last) {

@@ -145,8 +147,7 @@ std::pair<I, I> minmax_element(I first, I last, R r)

template<RegularIterator I>
std::pair<I, I> minmax_element(I first, I last)
{
return based::minmax_element(
first, last, std::less<typename I::value_type>());
return based::minmax_element(first, last, std::less<iter_value_t<I>>());
}
} // namespace based

diff --git a/include/based/type_traits.hpp b/include/based/type_traits.hpp

@@ -1,6 +1,7 @@

#pragma once
#include <cstdint>
#include <iterator>
#include <tuple>
#include <type_traits>

@@ -27,13 +28,25 @@ template<typename T>

using bare_t = std::remove_cvref_t<T>;
template<typename T>
using iter_value_t = std::iterator_traits<T>::value_type;
template<typename T>
using iter_diff_t = std::iterator_traits<T>::difference_type;
template<typename T>
using iter_ptr_t = std::iterator_traits<T>::pointer;
template<typename T>
using iter_ref_t = std::iterator_traits<T>::reference;
template<typename T>
concept Regular = std::regular<T>;
template<typename T>
concept BareRegular = std::regular<bare_t<T>>;
template<typename T>
concept RegularIterator = std::regular<typename T::value_type>;
concept RegularIterator = std::regular<iter_value_t<T>>;
template<typename T, typename U>
concept SameAs = std::is_same_v<T, U> && std::is_same_v<U, T>;