#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace reactor { #if defined(__GNUC__) || defined(__clang__) #define bswap_16(x) __builtin_bswap16(x) #define bswap_32(x) __builtin_bswap32(x) #define bswap_64(x) __builtin_bswap64(x) #else // Generic fallback implementations inline uint16_t bswap_16(uint16_t val) { return (val << 8) | (val >> 8); } inline uint32_t bswap_32(uint32_t val) { val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF); return (val << 16) | (val >> 16); } inline uint64_t bswap_64(uint64_t val) { uint64_t temp = val; char* ptr = reinterpret_cast(&temp); std::reverse(ptr, ptr + sizeof(uint64_t)); return temp; } #endif // C++20 Network byte order utilities inline uint16_t hton16(uint16_t host_uint16) { if constexpr (std::endian::native == std::endian::little) { return bswap_16(host_uint16); } else { return host_uint16; } } inline uint32_t hton32(uint32_t host_uint32) { if constexpr (std::endian::native == std::endian::little) { return bswap_32(host_uint32); } else { return host_uint32; } } inline uint64_t hton64(uint64_t host_uint64) { if constexpr (std::endian::native == std::endian::little) { return bswap_64(host_uint64); } else { return host_uint64; } } inline uint16_t ntoh16(uint16_t net_uint16) { return hton16(net_uint16); } inline uint32_t ntoh32(uint32_t net_uint32) { return hton32(net_uint32); } inline uint64_t ntoh64(uint64_t net_uint64) { return hton64(net_uint64); } // NonCopyable base class (unchanged, follows modern practice) class NonCopyable { protected: NonCopyable() = default; ~NonCopyable() = default; NonCopyable(const NonCopyable&) = delete; NonCopyable& operator=(const NonCopyable&) = delete; NonCopyable(NonCopyable&&) noexcept = default; NonCopyable& operator=(NonCopyable&&) noexcept = default; }; // Object Pool (unchanged, this is a standard pattern) template class ObjectPool : public NonCopyable, public std::enable_shared_from_this> { private: std::vector> objects_; std::mutex mutex_; public: std::shared_ptr getObject() { static_assert(!std::is_pointer_v, "ObjectPool type cannot be a pointer"); std::unique_ptr p = nullptr; { std::lock_guard lock(mutex_); if (!objects_.empty()) { p = std::move(objects_.back()); objects_.pop_back(); } } if (!p) { p = std::make_unique(); } std::weak_ptr> weakPtr = this->shared_from_this(); return std::shared_ptr(p.release(), [weakPtr](T* ptr) { auto self = weakPtr.lock(); if (self) { std::lock_guard lock(self->mutex_); self->objects_.push_back(std::unique_ptr(ptr)); } else { delete ptr; } }); } }; enum class LogLevel { TRACE, DEBUG, INFO, WARN, ERROR, FATAL }; class Logger : public NonCopyable { private: static inline LogLevel level_ = LogLevel::INFO; static inline std::unique_ptr file_; std::ostringstream stream_; LogLevel msgLevel_; static const char* levelString(LogLevel level) { switch (level) { case LogLevel::TRACE: return "TRACE"; case LogLevel::DEBUG: return "DEBUG"; case LogLevel::INFO: return "INFO "; case LogLevel::WARN: return "WARN "; case LogLevel::ERROR: return "ERROR"; case LogLevel::FATAL: return "FATAL"; } return "UNKNOWN"; } static std::string timestamp() { auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); auto ms = std::chrono::duration_cast( now.time_since_epoch()) % 1000; char buf[64]; std::strftime(buf, sizeof(buf), "%Y%m%d %H:%M:%S", std::localtime(&time_t)); return std::string(buf) + "." + std::to_string(ms.count()); } public: Logger(LogLevel level) : msgLevel_(level) { if (level >= level_) { stream_ << timestamp() << " " << levelString(level) << " "; } } ~Logger() { if (msgLevel_ >= level_) { stream_ << "\n"; // std::osyncstream handles synchronized, atomic writes if (file_ && file_->is_open()) { std::osyncstream(*file_) << stream_.str(); } else { std::osyncstream(std::cout) << stream_.str(); } } } template Logger& operator<<(const T& value) { if (msgLevel_ >= level_) { stream_ << value; } return *this; } static void setLevel(LogLevel level) { level_ = level; } static void setLogFile(const std::string& filename) { file_ = std::make_unique(filename, std::ios::app); } }; // C++20 Concurrent Task Queue using jthread and stop_token class ConcurrentTaskQueue : public NonCopyable { private: std::vector threads_; std::queue> taskQueue_; std::mutex mutex_; std::condition_variable_any taskCond_; std::stop_source stopSource_; std::string name_; void workerThread(std::stop_token token) { while (!token.stop_requested()) { std::function task; { std::unique_lock lock(mutex_); taskCond_.wait(lock, token, [this] { return !taskQueue_.empty(); }); if (token.stop_requested() && taskQueue_.empty()) { return; } task = std::move(taskQueue_.front()); taskQueue_.pop(); } task(); } } public: ConcurrentTaskQueue(size_t threadNum, const std::string& name = "ConcurrentTaskQueue") : name_(name) { for (size_t i = 0; i < threadNum; ++i) { threads_.emplace_back(&ConcurrentTaskQueue::workerThread, this, stopSource_.get_token()); } } ~ConcurrentTaskQueue() { stopSource_.request_stop(); taskCond_.notify_all(); // std::jthread destructors automatically join } template void runTaskInQueue(F&& task) { { std::lock_guard lock(mutex_); if (stopSource_.stop_requested()) return; taskQueue_.emplace(std::forward(task)); } taskCond_.notify_one(); } template void syncTaskInQueue(F&& task) { auto promise = std::make_shared>(); auto future = promise->get_future(); runTaskInQueue([promise, task = std::forward(task)]() mutable { task(); promise->set_value(); }); future.wait(); } std::string getName() const { return name_; } size_t getTaskCount() { std::lock_guard lock(mutex_); return taskQueue_.size(); } }; // Logging macros (unchanged) #define LOG_TRACE reactor::Logger(reactor::LogLevel::TRACE) #define LOG_DEBUG reactor::Logger(reactor::LogLevel::DEBUG) #define LOG_INFO reactor::Logger(reactor::LogLevel::INFO) #define LOG_WARN reactor::Logger(reactor::LogLevel::WARN) #define LOG_ERROR reactor::Logger(reactor::LogLevel::ERROR) #define LOG_FATAL reactor::Logger(reactor::LogLevel::FATAL) // Utility functions template void hashCombine(std::size_t& seed, const T& value) { std::hash hasher; seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } // C++20 string splitting using ranges inline std::vector splitString(const std::string& s, const std::string& delimiter) { std::vector result; for (const auto& range : std::views::split(s, delimiter)) { result.emplace_back(range.begin(), range.end()); } return result; } } // namespace reactor