summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/address_space.h7
-rw-r--r--src/common/alignment.h18
-rw-r--r--src/common/atomic_helpers.h2
-rw-r--r--src/common/bit_util.h6
-rw-r--r--src/common/concepts.h6
-rw-r--r--src/common/div_ceil.h4
-rw-r--r--src/common/expected.h60
-rw-r--r--src/common/input.h2
-rw-r--r--src/common/intrusive_red_black_tree.h20
-rw-r--r--src/common/make_unique_for_overwrite.h8
-rw-r--r--src/common/polyfill_ranges.h8
-rw-r--r--src/common/polyfill_thread.h123
-rw-r--r--src/common/settings.h12
-rw-r--r--src/common/string_util.cpp2
-rw-r--r--src/common/string_util.h3
-rw-r--r--src/common/tree.h74
-rw-r--r--src/common/vector_math.h16
17 files changed, 211 insertions, 160 deletions
diff --git a/src/common/address_space.h b/src/common/address_space.h
index 9222b2fdc..8683c23c3 100644
--- a/src/common/address_space.h
+++ b/src/common/address_space.h
@@ -12,7 +12,8 @@
namespace Common {
template <typename VaType, size_t AddressSpaceBits>
-concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >= AddressSpaceBits;
+concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >=
+AddressSpaceBits;
struct EmptyStruct {};
@@ -21,7 +22,7 @@ struct EmptyStruct {};
*/
template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa,
bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct>
-requires AddressSpaceValid<VaType, AddressSpaceBits>
+ requires AddressSpaceValid<VaType, AddressSpaceBits>
class FlatAddressSpaceMap {
public:
/// The maximum VA that this AS can technically reach
@@ -109,7 +110,7 @@ private:
* initial, fast linear pass and a subsequent slower pass that iterates until it finds a free block
*/
template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits>
-requires AddressSpaceValid<VaType, AddressSpaceBits>
+ requires AddressSpaceValid<VaType, AddressSpaceBits>
class FlatAllocator
: public FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits> {
private:
diff --git a/src/common/alignment.h b/src/common/alignment.h
index 7e897334b..fa715d497 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -10,7 +10,7 @@
namespace Common {
template <typename T>
-requires std::is_unsigned_v<T>
+ requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
auto mod{static_cast<T>(value % size)};
value -= mod;
@@ -18,31 +18,31 @@ requires std::is_unsigned_v<T>
}
template <typename T>
-requires std::is_unsigned_v<T>
+ requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) {
return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2);
}
template <typename T>
-requires std::is_unsigned_v<T>
+ requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
return static_cast<T>(value - value % size);
}
template <typename T>
-requires std::is_unsigned_v<T>
+ requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool Is4KBAligned(T value) {
return (value & 0xFFF) == 0;
}
template <typename T>
-requires std::is_unsigned_v<T>
+ requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool IsWordAligned(T value) {
return (value & 0b11) == 0;
}
template <typename T>
-requires std::is_integral_v<T>
+ requires std::is_integral_v<T>
[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) {
using U = typename std::make_unsigned_t<T>;
const U mask = static_cast<U>(alignment - 1);
@@ -50,7 +50,7 @@ requires std::is_integral_v<T>
}
template <typename T, typename U>
-requires std::is_integral_v<T>
+ requires std::is_integral_v<T>
[[nodiscard]] constexpr T DivideUp(T x, U y) {
return (x + (y - 1)) / y;
}
@@ -73,11 +73,11 @@ public:
constexpr AlignmentAllocator(const AlignmentAllocator<T2, Align>&) noexcept {}
[[nodiscard]] T* allocate(size_type n) {
- return static_cast<T*>(::operator new (n * sizeof(T), std::align_val_t{Align}));
+ return static_cast<T*>(::operator new(n * sizeof(T), std::align_val_t{Align}));
}
void deallocate(T* p, size_type n) {
- ::operator delete (p, n * sizeof(T), std::align_val_t{Align});
+ ::operator delete(p, n * sizeof(T), std::align_val_t{Align});
}
template <typename T2>
diff --git a/src/common/atomic_helpers.h b/src/common/atomic_helpers.h
index aef3b66a4..d997f10ba 100644
--- a/src/common/atomic_helpers.h
+++ b/src/common/atomic_helpers.h
@@ -75,7 +75,7 @@ extern "C" void AnnotateHappensAfter(const char*, int, void*);
#if defined(AE_VCPP) || defined(AE_ICC)
#define AE_FORCEINLINE __forceinline
#elif defined(AE_GCC)
-//#define AE_FORCEINLINE __attribute__((always_inline))
+// #define AE_FORCEINLINE __attribute__((always_inline))
#define AE_FORCEINLINE inline
#else
#define AE_FORCEINLINE inline
diff --git a/src/common/bit_util.h b/src/common/bit_util.h
index e4e6287f3..13368b439 100644
--- a/src/common/bit_util.h
+++ b/src/common/bit_util.h
@@ -45,19 +45,19 @@ template <typename T>
}
template <typename T>
-requires std::is_unsigned_v<T>
+ requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool IsPow2(T value) {
return std::has_single_bit(value);
}
template <typename T>
-requires std::is_integral_v<T>
+ requires std::is_integral_v<T>
[[nodiscard]] T NextPow2(T value) {
return static_cast<T>(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U)));
}
template <size_t bit_index, typename T>
-requires std::is_integral_v<T>
+ requires std::is_integral_v<T>
[[nodiscard]] constexpr bool Bit(const T value) {
static_assert(bit_index < BitSize<T>(), "bit_index must be smaller than size of T");
return ((value >> bit_index) & T(1)) == T(1);
diff --git a/src/common/concepts.h b/src/common/concepts.h
index a9acff3e7..61df1d32a 100644
--- a/src/common/concepts.h
+++ b/src/common/concepts.h
@@ -16,9 +16,9 @@ concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>;
// is available on all supported platforms.
template <typename Derived, typename Base>
concept DerivedFrom = requires {
- std::is_base_of_v<Base, Derived>;
- std::is_convertible_v<const volatile Derived*, const volatile Base*>;
-};
+ std::is_base_of_v<Base, Derived>;
+ std::is_convertible_v<const volatile Derived*, const volatile Base*>;
+ };
// TODO: Replace with std::convertible_to when libc++ implements it.
template <typename From, typename To>
diff --git a/src/common/div_ceil.h b/src/common/div_ceil.h
index eebc279c2..c12477d42 100644
--- a/src/common/div_ceil.h
+++ b/src/common/div_ceil.h
@@ -10,14 +10,14 @@ namespace Common {
/// Ceiled integer division.
template <typename N, typename D>
-requires std::is_integral_v<N> && std::is_unsigned_v<D>
+ requires std::is_integral_v<N> && std::is_unsigned_v<D>
[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
}
/// Ceiled integer division with logarithmic divisor in base 2
template <typename N, typename D>
-requires std::is_integral_v<N> && std::is_unsigned_v<D>
+ requires std::is_integral_v<N> && std::is_unsigned_v<D>
[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
}
diff --git a/src/common/expected.h b/src/common/expected.h
index 6e6c86ee7..5fccfbcbd 100644
--- a/src/common/expected.h
+++ b/src/common/expected.h
@@ -64,7 +64,7 @@ struct no_init_t {
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E, bool = std::is_trivially_destructible_v<T>>
-requires std::is_trivially_destructible_v<E>
+ requires std::is_trivially_destructible_v<E>
struct expected_storage_base {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
@@ -111,7 +111,7 @@ struct expected_storage_base {
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E>
-requires std::is_trivially_destructible_v<E>
+ requires std::is_trivially_destructible_v<E>
struct expected_storage_base<T, E, true> {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
@@ -251,7 +251,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E, bool = std::is_trivially_copy_constructible_v<T>>
-requires std::is_trivially_copy_constructible_v<E>
+ requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
};
@@ -261,7 +261,7 @@ struct expected_copy_base : expected_operations_base<T, E> {
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E>
-requires std::is_trivially_copy_constructible_v<E>
+ requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
@@ -289,7 +289,7 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E, bool = std::is_trivially_move_constructible_v<T>>
-requires std::is_trivially_move_constructible_v<E>
+ requires std::is_trivially_move_constructible_v<E>
struct expected_move_base : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
};
@@ -299,7 +299,7 @@ struct expected_move_base : expected_copy_base<T, E> {
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E>
-requires std::is_trivially_move_constructible_v<E>
+ requires std::is_trivially_move_constructible_v<E>
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
@@ -330,9 +330,9 @@ template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_copy_assignable<T>,
std::is_trivially_copy_constructible<T>,
std::is_trivially_destructible<T>>>
-requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
- std::is_trivially_copy_constructible<E>,
- std::is_trivially_destructible<E>>
+ requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
+ std::is_trivially_copy_constructible<E>,
+ std::is_trivially_destructible<E>>
struct expected_copy_assign_base : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
};
@@ -342,9 +342,9 @@ struct expected_copy_assign_base : expected_move_base<T, E> {
* Additionally, this requires E to be trivially copy assignable
*/
template <typename T, typename E>
-requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
- std::is_trivially_copy_constructible<E>,
- std::is_trivially_destructible<E>>
+ requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
+ std::is_trivially_copy_constructible<E>,
+ std::is_trivially_destructible<E>>
struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
@@ -371,9 +371,9 @@ template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_move_assignable<T>,
std::is_trivially_move_constructible<T>,
std::is_trivially_destructible<T>>>
-requires std::conjunction_v<std::is_trivially_move_assignable<E>,
- std::is_trivially_move_constructible<E>,
- std::is_trivially_destructible<E>>
+ requires std::conjunction_v<std::is_trivially_move_assignable<E>,
+ std::is_trivially_move_constructible<E>,
+ std::is_trivially_destructible<E>>
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
};
@@ -383,9 +383,9 @@ struct expected_move_assign_base : expected_copy_assign_base<T, E> {
* Additionally, this requires E to be trivially move assignable
*/
template <typename T, typename E>
-requires std::conjunction_v<std::is_trivially_move_assignable<E>,
- std::is_trivially_move_constructible<E>,
- std::is_trivially_destructible<E>>
+ requires std::conjunction_v<std::is_trivially_move_assignable<E>,
+ std::is_trivially_move_constructible<E>,
+ std::is_trivially_destructible<E>>
struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
@@ -412,7 +412,7 @@ struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E>
*/
template <typename T, typename E, bool EnableCopy = std::is_copy_constructible_v<T>,
bool EnableMove = std::is_move_constructible_v<T>>
-requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
+ requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
@@ -422,7 +422,7 @@ struct expected_delete_ctor_base {
};
template <typename T, typename E>
-requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
+ requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, true, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
@@ -432,7 +432,7 @@ struct expected_delete_ctor_base<T, E, true, false> {
};
template <typename T, typename E>
-requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
+ requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, true> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
@@ -442,7 +442,7 @@ struct expected_delete_ctor_base<T, E, false, true> {
};
template <typename T, typename E>
-requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
+ requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
@@ -460,8 +460,8 @@ template <
typename T, typename E,
bool EnableCopy = std::conjunction_v<std::is_copy_constructible<T>, std::is_copy_assignable<T>>,
bool EnableMove = std::conjunction_v<std::is_move_constructible<T>, std::is_move_assignable<T>>>
-requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
- std::is_copy_assignable<E>, std::is_move_assignable<E>>
+ requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
+ std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -471,8 +471,8 @@ struct expected_delete_assign_base {
};
template <typename T, typename E>
-requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
- std::is_copy_assignable<E>, std::is_move_assignable<E>>
+ requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
+ std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, true, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -482,8 +482,8 @@ struct expected_delete_assign_base<T, E, true, false> {
};
template <typename T, typename E>
-requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
- std::is_copy_assignable<E>, std::is_move_assignable<E>>
+ requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
+ std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, true> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -493,8 +493,8 @@ struct expected_delete_assign_base<T, E, false, true> {
};
template <typename T, typename E>
-requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
- std::is_copy_assignable<E>, std::is_move_assignable<E>>
+ requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
+ std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
diff --git a/src/common/input.h b/src/common/input.h
index d61cd7ca8..b5748a6c8 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -130,6 +130,8 @@ struct ButtonStatus {
bool inverted{};
// Press once to activate, press again to release
bool toggle{};
+ // Spams the button when active
+ bool turbo{};
// Internal lock for the toggle status
bool locked{};
};
diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h
index 93046615e..5f6b34e82 100644
--- a/src/common/intrusive_red_black_tree.h
+++ b/src/common/intrusive_red_black_tree.h
@@ -242,19 +242,21 @@ public:
template <typename T>
concept HasRedBlackKeyType = requires {
- { std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>;
-};
+ {
+ std::is_same<typename T::RedBlackKeyType, void>::value
+ } -> std::convertible_to<bool>;
+ };
namespace impl {
- template <typename T, typename Default>
- consteval auto* GetRedBlackKeyType() {
- if constexpr (HasRedBlackKeyType<T>) {
- return static_cast<typename T::RedBlackKeyType*>(nullptr);
- } else {
- return static_cast<Default*>(nullptr);
- }
+template <typename T, typename Default>
+consteval auto* GetRedBlackKeyType() {
+ if constexpr (HasRedBlackKeyType<T>) {
+ return static_cast<typename T::RedBlackKeyType*>(nullptr);
+ } else {
+ return static_cast<Default*>(nullptr);
}
+}
} // namespace impl
diff --git a/src/common/make_unique_for_overwrite.h b/src/common/make_unique_for_overwrite.h
index c7413cf51..17f81bba4 100644
--- a/src/common/make_unique_for_overwrite.h
+++ b/src/common/make_unique_for_overwrite.h
@@ -9,17 +9,19 @@
namespace Common {
template <class T>
-requires(!std::is_array_v<T>) std::unique_ptr<T> make_unique_for_overwrite() {
+ requires(!std::is_array_v<T>)
+std::unique_ptr<T> make_unique_for_overwrite() {
return std::unique_ptr<T>(new T);
}
template <class T>
-requires std::is_unbounded_array_v<T> std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
+ requires std::is_unbounded_array_v<T>
+std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]);
}
template <class T, class... Args>
-requires std::is_bounded_array_v<T>
+ requires std::is_bounded_array_v<T>
void make_unique_for_overwrite(Args&&...) = delete;
} // namespace Common
diff --git a/src/common/polyfill_ranges.h b/src/common/polyfill_ranges.h
index ca44bfaef..512dbcbcb 100644
--- a/src/common/polyfill_ranges.h
+++ b/src/common/polyfill_ranges.h
@@ -18,9 +18,9 @@ namespace ranges {
template <typename T>
concept range = requires(T& t) {
- begin(t);
- end(t);
-};
+ begin(t);
+ end(t);
+ };
template <typename T>
concept input_range = range<T>;
@@ -421,7 +421,7 @@ struct generate_fn {
}
template <typename R, std::copy_constructible F>
- requires std::invocable<F&> && ranges::output_range<R>
+ requires std::invocable<F&> && ranges::output_range<R>
constexpr ranges::iterator_t<R> operator()(R&& r, F gen) const {
return operator()(ranges::begin(r), ranges::end(r), std::move(gen));
}
diff --git a/src/common/polyfill_thread.h b/src/common/polyfill_thread.h
index 5a8d1ce08..b5ef055db 100644
--- a/src/common/polyfill_thread.h
+++ b/src/common/polyfill_thread.h
@@ -11,6 +11,8 @@
#ifdef __cpp_lib_jthread
+#include <chrono>
+#include <condition_variable>
#include <stop_token>
#include <thread>
@@ -21,23 +23,36 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred&& pred) {
cv.wait(lock, token, std::move(pred));
}
+template <typename Rep, typename Period>
+bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
+ std::condition_variable_any cv;
+ std::mutex m;
+
+ // Perform the timed wait.
+ std::unique_lock lk{m};
+ return !cv.wait_for(lk, token, rel_time, [&] { return token.stop_requested(); });
+}
+
} // namespace Common
#else
#include <atomic>
+#include <chrono>
+#include <condition_variable>
#include <functional>
-#include <list>
+#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <thread>
#include <type_traits>
+#include <utility>
namespace std {
namespace polyfill {
-using stop_state_callbacks = list<function<void()>>;
+using stop_state_callback = size_t;
class stop_state {
public:
@@ -45,61 +60,69 @@ public:
~stop_state() = default;
bool request_stop() {
- stop_state_callbacks callbacks;
+ unique_lock lk{m_lock};
- {
- scoped_lock lk{m_lock};
+ if (m_stop_requested) {
+ // Already set, nothing to do.
+ return false;
+ }
- if (m_stop_requested.load()) {
- // Already set, nothing to do
- return false;
- }
+ // Mark stop requested.
+ m_stop_requested = true;
- // Set as requested
- m_stop_requested = true;
+ while (!m_callbacks.empty()) {
+ // Get an iterator to the first element.
+ const auto it = m_callbacks.begin();
- // Copy callback list
- callbacks = m_callbacks;
- }
+ // Move the callback function out of the map.
+ function<void()> f;
+ swap(it->second, f);
+
+ // Erase the now-empty map element.
+ m_callbacks.erase(it);
- for (auto callback : callbacks) {
- callback();
+ // Run the callback.
+ if (f) {
+ f();
+ }
}
return true;
}
bool stop_requested() const {
- return m_stop_requested.load();
+ unique_lock lk{m_lock};
+ return m_stop_requested;
}
- stop_state_callbacks::const_iterator insert_callback(function<void()> f) {
- stop_state_callbacks::const_iterator ret{};
- bool should_run{};
-
- {
- scoped_lock lk{m_lock};
- should_run = m_stop_requested.load();
- m_callbacks.push_front(f);
- ret = m_callbacks.begin();
- }
+ stop_state_callback insert_callback(function<void()> f) {
+ unique_lock lk{m_lock};
- if (should_run) {
- f();
+ if (m_stop_requested) {
+ // Stop already requested. Don't insert anything,
+ // just run the callback synchronously.
+ if (f) {
+ f();
+ }
+ return 0;
}
+ // Insert the callback.
+ stop_state_callback ret = ++m_next_callback;
+ m_callbacks.emplace(ret, move(f));
return ret;
}
- void remove_callback(stop_state_callbacks::const_iterator it) {
- scoped_lock lk{m_lock};
- m_callbacks.erase(it);
+ void remove_callback(stop_state_callback cb) {
+ unique_lock lk{m_lock};
+ m_callbacks.erase(cb);
}
private:
- mutex m_lock;
- atomic<bool> m_stop_requested;
- stop_state_callbacks m_callbacks;
+ mutable recursive_mutex m_lock;
+ map<stop_state_callback, function<void()>> m_callbacks;
+ stop_state_callback m_next_callback{0};
+ bool m_stop_requested{false};
};
} // namespace polyfill
@@ -190,7 +213,7 @@ public:
using callback_type = Callback;
template <typename C>
- requires constructible_from<Callback, C>
+ requires constructible_from<Callback, C>
explicit stop_callback(const stop_token& st,
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
: m_stop_state(st.m_stop_state) {
@@ -199,7 +222,7 @@ public:
}
}
template <typename C>
- requires constructible_from<Callback, C>
+ requires constructible_from<Callback, C>
explicit stop_callback(stop_token&& st,
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
: m_stop_state(move(st.m_stop_state)) {
@@ -209,7 +232,7 @@ public:
}
~stop_callback() {
if (m_stop_state && m_callback) {
- m_stop_state->remove_callback(*m_callback);
+ m_stop_state->remove_callback(m_callback);
}
}
@@ -220,7 +243,7 @@ public:
private:
shared_ptr<polyfill::stop_state> m_stop_state;
- optional<polyfill::stop_state_callbacks::const_iterator> m_callback;
+ polyfill::stop_state_callback m_callback;
};
template <typename Callback>
@@ -318,6 +341,28 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred pred) {
cv.wait(lock, [&] { return pred() || token.stop_requested(); });
}
+template <typename Rep, typename Period>
+bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
+ if (token.stop_requested()) {
+ return false;
+ }
+
+ bool stop_requested = false;
+ std::condition_variable cv;
+ std::mutex m;
+
+ std::stop_callback cb(token, [&] {
+ // Wake up the waiting thread.
+ std::unique_lock lk{m};
+ stop_requested = true;
+ cv.notify_one();
+ });
+
+ // Perform the timed wait.
+ std::unique_lock lk{m};
+ return !cv.wait_for(lk, rel_time, [&] { return stop_requested; });
+}
+
} // namespace Common
#endif
diff --git a/src/common/settings.h b/src/common/settings.h
index 4b4da4da2..64db66f37 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -131,7 +131,8 @@ public:
* @param default_val Intial value of the setting, and default value of the setting
* @param name Label for the setting
*/
- explicit Setting(const Type& default_val, const std::string& name) requires(!ranged)
+ explicit Setting(const Type& default_val, const std::string& name)
+ requires(!ranged)
: value{default_val}, default_value{default_val}, label{name} {}
virtual ~Setting() = default;
@@ -144,7 +145,8 @@ public:
* @param name Label for the setting
*/
explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val,
- const std::string& name) requires(ranged)
+ const std::string& name)
+ requires(ranged)
: value{default_val},
default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {}
@@ -232,7 +234,8 @@ public:
* @param default_val Intial value of the setting, and default value of the setting
* @param name Label for the setting
*/
- explicit SwitchableSetting(const Type& default_val, const std::string& name) requires(!ranged)
+ explicit SwitchableSetting(const Type& default_val, const std::string& name)
+ requires(!ranged)
: Setting<Type>{default_val, name} {}
virtual ~SwitchableSetting() = default;
@@ -245,7 +248,8 @@ public:
* @param name Label for the setting
*/
explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val,
- const std::string& name) requires(ranged)
+ const std::string& name)
+ requires(ranged)
: Setting<Type, true>{default_val, min_val, max_val, name} {}
/**
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index b26db4796..e0b6180c5 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -30,7 +30,7 @@ std::string ToUpper(std::string str) {
return str;
}
-std::string StringFromBuffer(const std::vector<u8>& data) {
+std::string StringFromBuffer(std::span<const u8> data) {
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
}
diff --git a/src/common/string_util.h b/src/common/string_util.h
index ce18a33cf..f8aecc875 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -5,6 +5,7 @@
#pragma once
#include <cstddef>
+#include <span>
#include <string>
#include <vector>
#include "common/common_types.h"
@@ -17,7 +18,7 @@ namespace Common {
/// Make a string uppercase
[[nodiscard]] std::string ToUpper(std::string str);
-[[nodiscard]] std::string StringFromBuffer(const std::vector<u8>& data);
+[[nodiscard]] std::string StringFromBuffer(std::span<const u8> data);
[[nodiscard]] std::string StripSpaces(const std::string& s);
[[nodiscard]] std::string StripQuotes(const std::string& s);
diff --git a/src/common/tree.h b/src/common/tree.h
index f77859209..f4fc43de3 100644
--- a/src/common/tree.h
+++ b/src/common/tree.h
@@ -103,12 +103,12 @@ concept IsRBEntry = CheckRBEntry<T>::value;
template <typename T>
concept HasRBEntry = requires(T& t, const T& ct) {
- { t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
- { ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
-};
+ { t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
+ { ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
+ };
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
class RBHead {
private:
T* m_rbh_root = nullptr;
@@ -130,90 +130,90 @@ public:
};
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr RBEntry<T>& RB_ENTRY(T* t) {
return t->GetRBEntry();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr const RBEntry<T>& RB_ENTRY(const T* t) {
return t->GetRBEntry();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_LEFT(T* t) {
return RB_ENTRY(t).Left();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_LEFT(const T* t) {
return RB_ENTRY(t).Left();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_RIGHT(T* t) {
return RB_ENTRY(t).Right();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_RIGHT(const T* t) {
return RB_ENTRY(t).Right();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_PARENT(T* t) {
return RB_ENTRY(t).Parent();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_PARENT(const T* t) {
return RB_ENTRY(t).Parent();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_SET_LEFT(T* t, T* e) {
RB_ENTRY(t).SetLeft(e);
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_SET_RIGHT(T* t, T* e) {
RB_ENTRY(t).SetRight(e);
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_SET_PARENT(T* t, T* e) {
RB_ENTRY(t).SetParent(e);
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr bool RB_IS_BLACK(const T* t) {
return RB_ENTRY(t).IsBlack();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr bool RB_IS_RED(const T* t) {
return RB_ENTRY(t).IsRed();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
[[nodiscard]] constexpr RBColor RB_COLOR(const T* t) {
return RB_ENTRY(t).Color();
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_SET_COLOR(T* t, RBColor c) {
RB_ENTRY(t).SetColor(c);
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_SET(T* elm, T* parent) {
auto& rb_entry = RB_ENTRY(elm);
rb_entry.SetParent(parent);
@@ -223,14 +223,14 @@ constexpr void RB_SET(T* elm, T* parent) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_SET_BLACKRED(T* black, T* red) {
RB_SET_COLOR(black, RBColor::RB_BLACK);
RB_SET_COLOR(red, RBColor::RB_RED);
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
tmp = RB_RIGHT(elm);
if (RB_SET_RIGHT(elm, RB_LEFT(tmp)); RB_RIGHT(elm) != nullptr) {
@@ -252,7 +252,7 @@ constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
tmp = RB_LEFT(elm);
if (RB_SET_LEFT(elm, RB_RIGHT(tmp)); RB_LEFT(elm) != nullptr) {
@@ -274,7 +274,7 @@ constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
T* tmp;
while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head.Root()) {
@@ -358,7 +358,7 @@ constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
T* child = nullptr;
T* parent = nullptr;
@@ -451,7 +451,7 @@ constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
T *parent = nullptr, *tmp = nullptr;
while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) {
@@ -499,7 +499,7 @@ constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
}
template <typename T, typename Compare>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
T* parent = nullptr;
T* tmp = head.Root();
@@ -534,7 +534,7 @@ constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename Compare>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
@@ -553,7 +553,7 @@ constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename Compare>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
T* res = nullptr;
@@ -574,7 +574,7 @@ constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename U, typename Compare>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
@@ -593,7 +593,7 @@ constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T, typename U, typename Compare>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
T* res = nullptr;
@@ -614,7 +614,7 @@ constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T, typename Compare>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
@@ -631,7 +631,7 @@ constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename U, typename Compare>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
@@ -648,7 +648,7 @@ constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_NEXT(T* elm) {
if (RB_RIGHT(elm)) {
elm = RB_RIGHT(elm);
@@ -669,7 +669,7 @@ constexpr T* RB_NEXT(T* elm) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_PREV(T* elm) {
if (RB_LEFT(elm)) {
elm = RB_LEFT(elm);
@@ -690,7 +690,7 @@ constexpr T* RB_PREV(T* elm) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_MIN(RBHead<T>& head) {
T* tmp = head.Root();
T* parent = nullptr;
@@ -704,7 +704,7 @@ constexpr T* RB_MIN(RBHead<T>& head) {
}
template <typename T>
-requires HasRBEntry<T>
+ requires HasRBEntry<T>
constexpr T* RB_MAX(RBHead<T>& head) {
T* tmp = head.Root();
T* parent = nullptr;
diff --git a/src/common/vector_math.h b/src/common/vector_math.h
index e62eeea2e..0e2095c45 100644
--- a/src/common/vector_math.h
+++ b/src/common/vector_math.h
@@ -348,9 +348,7 @@ public:
// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all
// component names (x<->r) and permutations (xy<->yx)
#define _DEFINE_SWIZZLER2(a, b, name) \
- [[nodiscard]] constexpr Vec2<T> name() const { \
- return Vec2<T>(a, b); \
- }
+ [[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
_DEFINE_SWIZZLER2(a, b, a##b); \
_DEFINE_SWIZZLER2(a, b, a2##b2); \
@@ -543,9 +541,7 @@ public:
// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and
// permutations (xy<->yx)
#define _DEFINE_SWIZZLER2(a, b, name) \
- [[nodiscard]] constexpr Vec2<T> name() const { \
- return Vec2<T>(a, b); \
- }
+ [[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
#define DEFINE_SWIZZLER2_COMP1(a, a2) \
_DEFINE_SWIZZLER2(a, a, a##a); \
_DEFINE_SWIZZLER2(a, a, a2##a2)
@@ -570,9 +566,7 @@ public:
#undef _DEFINE_SWIZZLER2
#define _DEFINE_SWIZZLER3(a, b, c, name) \
- [[nodiscard]] constexpr Vec3<T> name() const { \
- return Vec3<T>(a, b, c); \
- }
+ [[nodiscard]] constexpr Vec3<T> name() const { return Vec3<T>(a, b, c); }
#define DEFINE_SWIZZLER3_COMP1(a, a2) \
_DEFINE_SWIZZLER3(a, a, a, a##a##a); \
_DEFINE_SWIZZLER3(a, a, a, a2##a2##a2)
@@ -641,8 +635,8 @@ template <typename T>
// linear interpolation via float: 0.0=begin, 1.0=end
template <typename X>
-[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{})
- Lerp(const X& begin, const X& end, const float t) {
+[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end,
+ const float t) {
return begin * (1.f - t) + end * t;
}