chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:18:05 +08:00
commit acd8e21031
297 changed files with 56514 additions and 0 deletions
@@ -0,0 +1,39 @@
#pragma once
#include <initializer_list>
#include <ranges>
#include <vector>
namespace helpers::container {
template<typename R, typename V>
concept range_of = std::ranges::range<R> && std::same_as<std::ranges::range_value_t<R>, V>;
template<std::ranges::range T, std::ranges::range U>
requires std::same_as<std::ranges::range_value_t<T>, std::ranges::range_value_t<U>> &&
requires(T&& dst, U&& src) {
#if __cpp_lib_containers_ranges
dst.append_range(std::forward<U>(src));
#else
dst.insert(dst.end(), src.begin(), src.end());
#endif
}
inline void append_range(T&& dst, U&& src) {
#if __cpp_lib_containers_ranges
dst.append_range(std::forward<U>(src));
#else
dst.insert(dst.end(), src.begin(), src.end());
#endif
}
template<std::ranges::range T>
requires requires(T&& dst, std::initializer_list<std::ranges::range_value_t<T>>&& src) {
#if __cpp_lib_containers_ranges
dst.append_range(std::move(src));
#else
dst.insert(dst.end(), src.begin(), src.end());
#endif
}
inline void append_range(T&& dst, std::initializer_list<std::ranges::range_value_t<T>>&& src) {
append_range<T, std::initializer_list<std::ranges::range_value_t<T>>&&>(std::forward<T>(dst), std::move(src));
}
} // namespace helpers::container
@@ -0,0 +1,135 @@
#pragma once
#include <concepts>
#include <cstddef>
#include <exception>
#include <functional>
#include <future>
#include <ranges>
#include <type_traits>
namespace helpers::future {
namespace detail {
template<typename T>
struct future_value;
template<typename T>
struct future_value<std::future<T>> {
using type = T;
};
template<typename T>
concept future_range = std::ranges::range<T> && requires {
typename future_value<std::ranges::range_value_t<std::remove_cvref_t<T>>>::type;
};
template<future_range T>
using future_range_value_t = future_value<std::ranges::range_value_t<std::remove_cvref_t<T>>>::type;
} // namespace detail
struct FailurePolicyDrainAll;
// Stops draining after the first observed failure. This does not cancel remaining
// work; use only when unfinished tasks do not depend on this stack frame.
struct FailurePolicyStopOnFirstFailure;
template<typename T>
concept future_failure_policy = std::same_as<T, FailurePolicyDrainAll> || std::same_as<T, FailurePolicyStopOnFirstFailure>;
template<future_failure_policy P = FailurePolicyDrainAll, detail::future_range T>
requires std::same_as<detail::future_range_value_t<T>, void>
void drain_futures(T&& futures) {
std::exception_ptr first_exception;
for (auto& future : futures) {
try {
future.get();
} catch (...) {
if (!first_exception) {
first_exception = std::current_exception();
}
if constexpr (std::is_same_v<P, FailurePolicyStopOnFirstFailure>) {
break;
}
}
}
if (first_exception) {
std::rethrow_exception(first_exception);
}
}
template<future_failure_policy P = FailurePolicyDrainAll, detail::future_range T, typename F>
requires std::same_as<detail::future_range_value_t<T>, void> &&
std::invocable<F&, size_t>
void drain_futures(T&& futures, F&& f) {
std::exception_ptr first_exception;
size_t index = 0;
for (auto& future : futures) {
try {
future.get();
std::invoke(f, index);
} catch (...) {
if (!first_exception) {
first_exception = std::current_exception();
}
if constexpr (std::is_same_v<P, FailurePolicyStopOnFirstFailure>) {
break;
}
}
index++;
}
if (first_exception) {
std::rethrow_exception(first_exception);
}
}
template<future_failure_policy P = FailurePolicyDrainAll, detail::future_range T, typename F>
requires(!std::same_as<detail::future_range_value_t<T>, void>) &&
std::invocable<F&, detail::future_range_value_t<T>&&>
void drain_futures(T&& futures, F&& f) {
std::exception_ptr first_exception;
for (auto& future : futures) {
try {
std::invoke(f, future.get());
} catch (...) {
if (!first_exception) {
first_exception = std::current_exception();
}
if constexpr (std::is_same_v<P, FailurePolicyStopOnFirstFailure>) {
break;
}
}
}
if (first_exception) {
std::rethrow_exception(first_exception);
}
}
template<future_failure_policy P = FailurePolicyDrainAll, detail::future_range T, typename F>
requires(!std::same_as<detail::future_range_value_t<T>, void>) &&
std::invocable<F&, detail::future_range_value_t<T>&&, size_t>
void drain_futures(T&& futures, F&& f) {
std::exception_ptr first_exception;
size_t index = 0;
for (auto& future : futures) {
try {
std::invoke(f, future.get(), index);
} catch (...) {
if (!first_exception) {
first_exception = std::current_exception();
}
if constexpr (std::is_same_v<P, FailurePolicyStopOnFirstFailure>) {
break;
}
}
index++;
}
if (first_exception) {
std::rethrow_exception(first_exception);
}
}
} // namespace helpers::future
@@ -0,0 +1,9 @@
#pragma once
#include <napi.h>
namespace node_api::imaging {
Napi::Value avif_encode_rgba(const Napi::CallbackInfo& info);
Napi::Value avif_encode_rgba_batched(const Napi::CallbackInfo& info);
Napi::Value avif_decode_rgba(const Napi::CallbackInfo& info);
Napi::Value avif_decode_rgba_batched(const Napi::CallbackInfo& info);
} // namespace node_api::imaging
@@ -0,0 +1,92 @@
#pragma once
#include <memory>
#include <napi.h>
#include <span>
#include <vector>
namespace node_api::buffer {
template<typename T, typename D = std::default_delete<T>>
class UniqueBufferFinalizer {
public:
UniqueBufferFinalizer() noexcept = default;
UniqueBufferFinalizer(const UniqueBufferFinalizer<T, D>& other) = delete;
UniqueBufferFinalizer(UniqueBufferFinalizer<T, D>&& other) noexcept = default;
UniqueBufferFinalizer(std::unique_ptr<T, D>&& ptr) noexcept : ptr(std::move(ptr)) {}
UniqueBufferFinalizer(T* ptr) noexcept : ptr(ptr) {}
void operator()(Napi::Env env, T* data) noexcept {}
inline static Napi::Buffer<T> make_buffer(Napi::Env& env, std::unique_ptr<T, D>&& ptr, size_t size) noexcept {
auto finalizer = UniqueBufferFinalizer(std::move(ptr));
auto data_ptr = finalizer.ptr.get();
return Napi::Buffer<T>::NewOrCopy(env, data_ptr, size, std::move(finalizer));
}
protected:
std::unique_ptr<T, D> ptr;
};
template<typename T, typename D = std::default_delete<std::vector<T>>>
class UniqueVecBufferFinalizer : public UniqueBufferFinalizer<std::vector<T>, D> {
public:
void operator()(Napi::Env env, T* data) noexcept {}
template<typename U>
inline static Napi::Buffer<T> make_buffer(Napi::Env& env, U&& data) noexcept {
auto finalizer = UniqueVecBufferFinalizer(std::forward<U>(data));
auto data_ptr = finalizer.ptr->data();
auto data_size = finalizer.ptr->size();
return Napi::Buffer<T>::NewOrCopy(env, data_ptr, data_size, std::move(finalizer));
}
};
template<typename T>
class SharedBufferFinalizer {
public:
SharedBufferFinalizer() noexcept = default;
SharedBufferFinalizer(const SharedBufferFinalizer<T>& other) noexcept = default;
SharedBufferFinalizer(SharedBufferFinalizer<T>&& other) noexcept = default;
SharedBufferFinalizer(const std::shared_ptr<T>& ptr) noexcept : ptr(ptr) {}
SharedBufferFinalizer(std::shared_ptr<T>&& ptr) noexcept : ptr(std::move(ptr)) {}
void operator()(Napi::Env env, T* data) noexcept {}
template<typename U>
requires std::is_same_v<std::remove_reference_t<U>, std::shared_ptr<T>>
inline static Napi::Buffer<T> make_buffer(Napi::Env& env, U&& ptr, size_t size) noexcept {
auto finalizer = SharedBufferFinalizer(std::forward<U>(ptr));
auto data_ptr = finalizer.ptr.get();
return Napi::Buffer<T>::NewOrCopy(env, data_ptr, size, std::move(finalizer));
}
template<typename U>
requires std::is_same_v<std::remove_reference_t<U>, std::shared_ptr<T>>
inline static Napi::Buffer<T> make_buffer(Napi::Env& env, U&& ptr, size_t offset, size_t size) noexcept {
auto finalizer = SharedBufferFinalizer(std::forward<U>(ptr));
auto data_ptr = finalizer.ptr.get();
return Napi::Buffer<T>::NewOrCopy(env, data_ptr + offset, size, std::move(finalizer));
}
protected:
std::shared_ptr<T> ptr;
};
template<typename T>
class SharedVecBufferFinalizer : public SharedBufferFinalizer<std::vector<T>> {
public:
void operator()(Napi::Env env, T* data) noexcept {}
template<typename U>
inline static Napi::Buffer<T> make_buffer(Napi::Env& env, U&& data) noexcept {
auto finalizer = SharedVecBufferFinalizer(std::forward<U>(data));
auto data_ptr = finalizer.ptr->data();
auto data_size = finalizer.ptr->size();
return Napi::Buffer<T>::NewOrCopy(env, data_ptr, data_size, std::move(finalizer));
}
template<typename U>
inline static Napi::Buffer<T> make_buffer(Napi::Env& env, U&& data, size_t offset, size_t size) noexcept {
auto finalizer = SharedVecBufferFinalizer(std::forward<U>(data));
auto data_ptr = finalizer.ptr->data();
return Napi::Buffer<T>::NewOrCopy(env, data_ptr + offset, size, std::move(finalizer));
}
};
} // namespace node_api::buffer
@@ -0,0 +1,6 @@
#pragma once
#include <napi.h>
namespace node_api::spatial {
Napi::Value cluster_average(const Napi::CallbackInfo& info);
}
@@ -0,0 +1,7 @@
#pragma once
#include <napi.h>
namespace node_api::splat {
Napi::Value generate_lod(const Napi::CallbackInfo& info);
Napi::Value split(const Napi::CallbackInfo& info);
} // namespace node_api::splat
@@ -0,0 +1,26 @@
#pragma once
#include <algorithm>
#include <bit>
#include <cstddef>
#include <napi.h>
#include <thread>
#include <thread_pool.h>
namespace node_api::threading {
class ThreadPool : public Napi::ObjectWrap<ThreadPool> {
public:
static Napi::FunctionReference Init(Napi::Env env, Napi::Object exports);
ThreadPool(const Napi::CallbackInfo& info);
::threading::ThreadPool& impl() noexcept;
ThreadPool() = delete;
private:
static size_t calc_thread_count(const Napi::CallbackInfo& info);
Napi::Value thread_count(const Napi::CallbackInfo& info);
Napi::Value task_count(const Napi::CallbackInfo& info);
::threading::ThreadPool impl_;
};
} // namespace node_api::threading
@@ -0,0 +1,8 @@
#pragma once
#include <napi.h>
namespace node_api::imaging {
Napi::Value webp_encode_rgba_lossless(const Napi::CallbackInfo& info);
Napi::Value webp_encode_rgba(const Napi::CallbackInfo& info);
Napi::Value webp_decode_rgba(const Napi::CallbackInfo& info);
} // namespace node_api::imaging
@@ -0,0 +1,60 @@
#pragma once
#include <array>
#include <eigen3/Eigen/Dense>
#include <memory>
#include <vector>
namespace splat {
class SH {
public:
SH() noexcept;
SH(size_t size);
SH(const SH& other);
SH(SH&& other) noexcept;
SH& operator=(const SH& other);
SH& operator=(SH&& other) noexcept;
void swap(SH& other) noexcept;
SH& set_zero() noexcept;
SH& add_multiplied(const SH& other, float scalar) noexcept;
const float& operator[](size_t index) const;
float& operator[](size_t index);
float* data() noexcept;
size_t size() const noexcept;
~SH() noexcept;
private:
void reset() noexcept;
size_t size_;
std::unique_ptr<float[]> ptr;
};
struct Gaussian {
Eigen::Vector3f mean;
Eigen::Vector3f scale;
Eigen::Vector4f rotation;
Eigen::Matrix3f covariance;
SH sh;
float opacity;
Eigen::AlignedBox3f bounding_box;
void compute_covariance();
void decompose_covariance();
void compute_bounding_box(float k = 3.0f);
float area() const;
};
struct Splat {
std::vector<Gaussian> gaussians;
Eigen::AlignedBox3f bounding_box;
void compute_bounding_box();
void compute_compact_bounding_box();
};
} // namespace splat
@@ -0,0 +1,17 @@
#pragma once
#include <splat/splat.h>
#include <type_traits>
#include <vector>
namespace splat::block {
namespace detail {
std::vector<Splat> split(const Splat& splat, size_t max_block_size);
} // namespace detail
template<typename T>
requires std::is_same_v<std::remove_reference_t<T>, Splat>
std::vector<Splat> split(T&& input, double precision) {
auto max_block_size = static_cast<size_t>(static_cast<double>(input.gaussians.size()) * precision);
return detail::split(input, max_block_size);
}
} // namespace splat::block
@@ -0,0 +1,43 @@
#pragma once
#include <container_helpers.h>
#include <cstdint>
#include <splat/splat.h>
#include <vector>
namespace splat::lod {
namespace detail {
Splat reduce_gaussians(size_t id, const Splat& splat, size_t target_count, float scale_boost, size_t max_step);
}
struct SplatLod {
std::vector<Splat> splats;
std::vector<uint32_t> levels;
};
struct SplatLevelParameters {
float precision;
float scale_boost;
};
template<typename T>
requires requires(T) {
requires helpers::container::range_of<T, SplatLevelParameters>;
}
inline void generate_lod(size_t id, SplatLod& lod, T&& parameters, size_t min_size, size_t max_step) {
auto base_count = lod.splats.back().gaussians.size();
for (auto& parameter : parameters) {
auto target_count = std::max<size_t>(static_cast<size_t>(std::floor(static_cast<double>(base_count) * parameter.precision)), 1);
auto& current = lod.splats.back();
if (current.gaussians.size() > min_size && target_count < current.gaussians.size()) {
auto generated = detail::reduce_gaussians(
id,
current,
target_count,
parameter.scale_boost,
max_step);
lod.splats.push_back(std::move(generated));
}
lod.levels.push_back(lod.splats.size() - 1);
}
}
} // namespace splat::lod
@@ -0,0 +1,122 @@
#pragma once
#include <atomic>
#include <concepts>
#include <condition_variable>
#include <functional>
#include <future>
#include <memory>
#include <mutex>
#include <queue>
#include <shared_mutex>
#include <stdexcept>
#include <thread>
#include <type_traits>
#include <utility>
#include <vector>
namespace threading {
class ThreadPool {
public:
ThreadPool(size_t thread_count = std::thread::hardware_concurrency());
ThreadPool(ThreadPool&& other) noexcept;
template<typename F, typename... Args,
typename ReturnType = std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>>
requires std::invocable<std::decay_t<F>, std::decay_t<Args>...>
std::future<ReturnType> submit_task(F&& f, Args&&... args);
size_t thread_count() const noexcept;
size_t task_count() const noexcept;
ThreadPool& operator=(ThreadPool&& other) noexcept;
void stop() noexcept;
~ThreadPool() noexcept;
ThreadPool(const ThreadPool& other) = delete;
ThreadPool& operator=(const ThreadPool& other) = delete;
private:
#ifdef __cpp_lib_move_only_function
using Task = std::move_only_function<void()>;
#else
using Task = std::function<void()>;
#endif
struct Worker {
std::atomic<bool> stopped { false };
std::thread thread;
void stop() noexcept;
void clean_up() noexcept;
~Worker() noexcept;
};
struct State {
std::vector<std::unique_ptr<Worker>> workers;
std::queue<Task> tasks;
mutable std::shared_mutex queue_mutex;
mutable std::shared_mutex worker_mutex;
std::condition_variable_any cv;
std::atomic<bool> stopped { false };
void stop() noexcept;
~State() noexcept;
};
static void worker_loop(State* state, Worker* worker);
std::unique_ptr<State> state;
};
template<typename F, typename... Args, typename ReturnType>
requires std::invocable<std::decay_t<F>, std::decay_t<Args>...>
std::future<ReturnType> ThreadPool::submit_task(F&& f, Args&&... args) {
auto* state = this->state.get();
if (state == nullptr || state->stopped.load(std::memory_order_relaxed)) {
throw std::runtime_error("Cannot submit tasks to stopped thread pool");
}
#ifdef __cpp_lib_move_only_function
auto promise = std::promise<ReturnType>();
auto future = promise.get_future();
{
auto lk = std::lock_guard(state->queue_mutex);
if (state->stopped.load(std::memory_order_relaxed)) {
throw std::runtime_error("Cannot submit tasks to stopped thread pool");
}
state->tasks.emplace([f = std::forward<F>(f), ... args = std::forward<Args>(args), promise = std::move(promise)]() mutable noexcept -> void {
try {
if constexpr (std::is_void_v<ReturnType>) {
std::invoke(std::move(f), std::move(args)...);
promise.set_value();
} else {
promise.set_value(std::invoke(std::move(f), std::move(args)...));
}
} catch (...) {
promise.set_exception(std::current_exception());
}
});
}
#else
auto promise = std::make_shared<std::promise<ReturnType>>();
auto future = promise->get_future();
{
auto lk = std::lock_guard(state->queue_mutex);
if (state->stopped.load(std::memory_order_relaxed)) {
throw std::runtime_error("Cannot submit tasks to stopped thread pool");
}
state->tasks.emplace([f = std::forward<F>(f), ... args = std::forward<Args>(args), promise = promise]() noexcept -> void {
try {
if constexpr (std::is_void_v<ReturnType>) {
std::invoke(std::move(f), std::move(args)...);
promise->set_value();
} else {
promise->set_value(std::invoke(std::move(f), std::move(args)...));
}
} catch (...) {
promise->set_exception(std::current_exception());
}
});
}
#endif
state->cv.notify_one();
return future;
}
} // namespace threading