华容道高性能计算引擎
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

111 lines
3.3 KiB

#pragma once
#include <bit>
#include <list>
#include <utility>
#include <cstdint>
#include <numeric>
#include <functional>
// ----------------------------------------------------------------------------------------- //
/// Mark target class as a singleton.
#define KLSK_INSTANCE(T) \
private: \
T() = default; \
public: \
T(T &&) = delete; \
T(const T &) = delete; \
T& operator=(T &&) = delete; \
T& operator=(const T &) = delete; \
static T& instance() { \
static T ins; \
return ins; \
}
/// Marking compiler assumptions.
#if defined(__clang__)
#define KLSK_ASSUME(expr) __builtin_assume(expr)
#elif defined(__GNUC__)
#define KLSK_ASSUME(expr) [[assume(expr)]]
#endif
#define KLSK_UNREACHABLE __builtin_unreachable() // TODO: using `std::unreachable`
/// Force function declaration to be inline.
#if defined(__clang__)
#define KLSK_INLINE __attribute__ ((always_inline))
#else
#define KLSK_INLINE // NOTE: make sure that function can be inline
#endif
#define KLSK_INLINE_H KLSK_INLINE inline
#define KLSK_INLINE_CE KLSK_INLINE constexpr
// TODO: using `#pragma GCC unroll`
/// Prevent reordering for both compiler and processor.
#define KLSK_MEM_BARRIER std::atomic_thread_fence(std::memory_order_seq_cst)
// ----------------------------------------------------------------------------------------- //
namespace klotski {
/// Calculate the sum of an array of integers.
template <typename T, size_t N>
requires std::is_integral_v<T>
consteval int array_sum(const std::array<T, N> &arr) {
return std::accumulate(arr.begin(), arr.end(), 0);
}
/// Calculate offset list of integer array with sizes.
template <typename T, size_t N>
requires std::is_integral_v<T> && (N > 0)
consteval std::array<T, N> to_offset(const std::array<T, N> &arr) {
std::array<T, N> offset {};
std::partial_sum(arr.begin(), arr.end() - 1, offset.begin() + 1);
return offset;
}
/// Flips the input u32 every two bits in low-high symmetry.
constexpr uint32_t range_reverse(uint32_t bin) {
bin = std::byteswap(bin);
bin = ((bin << 4) & 0xF0F0F0F0) | ((bin >> 4) & 0x0F0F0F0F);
return ((bin << 2) & 0xCCCCCCCC) | ((bin >> 2) & 0x33333333);
}
// ----------------------------------------------------------------------------------------- //
/// Empty function calls that generally used for callbacks.
typedef std::function<void()> Notifier;
/// Execute the passed function that generally used for concurrency.
typedef std::function<void(std::function<void()> &&)> Executor;
/// Perform multiple tasks without blocking and trigger callback upon completion.
class Worker final {
public:
using Task = std::function<void()>;
/// Construction based on executor.
explicit Worker(Executor executor);
/// Post new task into the queue.
void post(Task &&task);
/// Setting up callback entry.
void then(Notifier &&after);
/// Tasks will be triggered at destruction.
~Worker();
private:
Notifier after_;
Executor executor_;
std::list<Task> tasks_;
};
// ----------------------------------------------------------------------------------------- //
} // namespace klotski
#include "worker.inl"