Skip to content

Commit

Permalink
Add new algorithm.hpp file.
Browse files Browse the repository at this point in the history
* Move emulation of std::lexicographical_compare_three_way to its own
  algorithm.hpp file.
  • Loading branch information
BenKaufmann authored and sjanel committed Apr 16, 2024
1 parent 4031546 commit 76b5b6f
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 51 deletions.
49 changes: 49 additions & 0 deletions include/amc/algorithm.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

#include <algorithm>

#include "config.hpp"

#if AMC_CXX20
#include <compare>
#endif

namespace amc {

#if AMC_CXX20
#if !defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 170000
using std::lexicographical_compare_three_way;
#else
// Adjusted from https://en.cppreference.com/w/cpp/algorithm/lexicographical_compare_three_way
template <class I1, class I2, class Cmp>
constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp comp) -> decltype(comp(*f1, *f2)) {
using ret_t = decltype(comp(*f1, *f2));
static_assert(std::disjunction_v<std::is_same<ret_t, std::strong_ordering>, std::is_same<ret_t, std::weak_ordering>,
std::is_same<ret_t, std::partial_ordering> >,
"The return type must be a comparison category type.");

for (; f1 != l1; ++f1, ++f2) {
if (f2 == l2) return std::strong_ordering::greater;
if (auto c = comp(*f1, *f2); c != 0) return c;
}
return (f2 == l2) <=> true;
}
#if _LIBCPP_VERSION >= 14000
using std::compare_three_way;
#else
struct compare_three_way {
using is_transparent = void;
template <class T, class U>
constexpr auto operator()(T&& t, U&& u) const noexcept(noexcept(std::declval<T>() <=> std::declval<U>())) {
return static_cast<T&&>(t) <=> static_cast<U&&>(u);
}
};
#endif
template <class I1, class I2>
constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2) {
return lexicographical_compare_three_way(f1, l1, f2, l2, amc::compare_three_way());
}
#endif
#endif

} // namespace amc
5 changes: 1 addition & 4 deletions include/amc/smallset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@
#include <utility>
#include <variant>

#include "algorithm.hpp"
#include "allocator.hpp"
#include "config.hpp"
#include "fixedcapacityvector.hpp"
#include "istransparent.hpp"
#include "memory.hpp"
#include "type_traits.hpp"

#ifdef AMC_CXX20
#include <compare>
#endif

namespace amc {

/**
Expand Down
44 changes: 0 additions & 44 deletions include/amc/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@

#include <utility>

#include "config.hpp"

#if AMC_CXX20
#include <algorithm>
#include <compare>
#endif

namespace amc {

// Provides emulation of std::exchange if C++14 is not supported.
Expand All @@ -22,41 +15,4 @@ T exchange(T &obj, U &&new_value) {
return old_value;
}
#endif

#if AMC_CXX20
#if !defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 170000
using std::lexicographical_compare_three_way;
#else
// Adjusted from https://en.cppreference.com/w/cpp/algorithm/lexicographical_compare_three_way
template <class I1, class I2, class Cmp>
constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp comp) -> decltype(comp(*f1, *f2)) {
using ret_t = decltype(comp(*f1, *f2));
static_assert(std::disjunction_v<std::is_same<ret_t, std::strong_ordering>, std::is_same<ret_t, std::weak_ordering>,
std::is_same<ret_t, std::partial_ordering> >,
"The return type must be a comparison category type.");

for (; f1 != l1; ++f1, ++f2) {
if (f2 == l2) return std::strong_ordering::greater;
if (auto c = comp(*f1, *f2); c != 0) return c;
}
return (f2 == l2) <=> true;
}
#if _LIBCPP_VERSION >= 14000
using std::compare_three_way;
#else
struct compare_three_way {
using is_transparent = void;
template <class T, class U>
constexpr auto operator()(T&& t, U&& u) const noexcept(noexcept(std::declval<T>() <=> std::declval<U>())) {
return static_cast<T&&>(t) <=> static_cast<U&&>(u);
}
};
#endif
template <class I1, class I2>
constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2) {
return lexicographical_compare_three_way(f1, l1, f2, l2, amc::compare_three_way());
}
#endif
#endif

} // namespace amc
4 changes: 1 addition & 3 deletions include/amc/vectorcommon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@
#include <limits>
#include <stdexcept>

#include "algorithm.hpp"
#include "config.hpp"
#include "memory.hpp"
#include "type_traits.hpp"
#include "utility.hpp"

#ifdef AMC_CXX14
#include <functional>
#ifdef AMC_CXX20
#include <compare>
#endif
#endif

namespace amc {
Expand Down

0 comments on commit 76b5b6f

Please sign in to comment.