Skip to content

Commit 44ed223

Browse files
committed
Core/Utils: restored advstd changes that went missing in last revert
1 parent 266d1d7 commit 44ed223

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

src/common/Utilities/advstd.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,91 @@
1818
#ifndef TRINITY_ADVSTD_H
1919
#define TRINITY_ADVSTD_H
2020

21+
#include <version>
22+
23+
#ifdef __cpp_lib_bit_cast
24+
#include <bit>
25+
#else
26+
#include <cstring> // for memcpy
27+
#endif
28+
#include <compare>
29+
2130
// this namespace holds implementations of upcoming stdlib features that our c++ version doesn't have yet
2231
namespace advstd
2332
{
33+
// libc++ is missing these two
34+
[[nodiscard]] constexpr bool is_eq(std::partial_ordering cmp) noexcept { return cmp == 0; }
35+
[[nodiscard]] constexpr bool is_neq(std::partial_ordering cmp) noexcept { return cmp != 0; }
36+
37+
#ifdef __cpp_lib_bit_cast
38+
using std::bit_cast;
39+
#else
40+
// libstdc++ v10 is missing this
41+
template <typename To, typename From,
42+
std::enable_if_t<std::conjunction_v<
43+
std::bool_constant<sizeof(To) == sizeof(From)>,
44+
std::is_trivially_copyable<To>,
45+
std::is_trivially_copyable<From>>, int> = 0>
46+
[[nodiscard]] constexpr To bit_cast(From const& from) noexcept
47+
{
48+
To to;
49+
std::memcpy(&to, &from, sizeof(To));
50+
return to;
51+
}
52+
#endif
53+
}
54+
55+
// std::forward_like
56+
#ifdef __cpp_lib_forward_like
57+
#include <utility>
58+
namespace advstd
59+
{
60+
using std::forward_like;
61+
}
62+
#else
63+
namespace advstd
64+
{
65+
template <class T, class U>
66+
[[nodiscard]] constexpr decltype(auto) forward_like(U&& value) noexcept
67+
{
68+
using ValueU = std::remove_reference_t<U>;
69+
using ValueConstU = std::conditional_t<std::is_const_v<std::remove_reference_t<T>>, ValueU const, ValueU>;
70+
return static_cast<std::conditional_t<std::is_rvalue_reference_v<T&&>, ValueConstU&&, ValueConstU&>>(value);
71+
}
72+
}
73+
#endif
74+
75+
// std::ranges::contains
76+
#include <algorithm>
77+
#ifndef __cpp_lib_ranges_contains
78+
#include <functional> // for std::ranges::equal_to, std::identity
79+
#include <iterator> // for std::input_iterator, std::sentinel_for, std::projected
80+
#endif
81+
82+
namespace advstd::ranges
83+
{
84+
#ifndef __cpp_lib_ranges_contains
85+
struct Contains
86+
{
87+
template<std::input_iterator I, std::sentinel_for<I> S, class T, class Proj = std::identity>
88+
requires std::indirect_binary_predicate<std::ranges::equal_to, std::projected<I, Proj>, T const*>
89+
[[nodiscard]] inline constexpr bool operator()(I first, S last, T const& value, Proj proj = {}) const
90+
{
91+
return std::ranges::find(std::move(first), last, value, proj) != last;
92+
}
93+
94+
template<std::ranges::input_range R, class T, class Proj = std::identity>
95+
requires std::indirect_binary_predicate<std::ranges::equal_to, std::projected<std::ranges::iterator_t<R>, Proj>, T const*>
96+
[[nodiscard]] inline constexpr bool operator()(R&& r, T const& value, Proj proj = {}) const
97+
{
98+
auto first = std::ranges::begin(r);
99+
auto last = std::ranges::end(r);
100+
return std::ranges::find(std::move(first), last, value, proj) != last;
101+
}
102+
} inline constexpr contains;
103+
#else
104+
using std::ranges::contains;
105+
#endif
24106
}
25107

26108
#endif

0 commit comments

Comments
 (0)