#ifndef ASSISTANT_H #define ASSISTANT_H #include #include #include #include #include #ifdef USE_BOOST #include namespace fs = boost::filesystem; #else #include namespace fs = std::filesystem; #endif /** * @brief 比较两个文件的内容是否完全相同 * * @param filea 第一个文件路径 * @param fileb 第二个文件路径 * @return true 如果文件内容完全相同 * @return false 如果文件内容不同或无法读取文件 */ bool is_equal_filecontent(const std::string& filea, const std::string& fileb); bool random_file(const std::string& file, size_t size); /** * @brief 等待变量的值达到预期值 * * @tparam T 变量类型 * @tparam Compare 比较器类型 * @param value 变量的引用 * @param expected 预期值 * @param comparator 比较函数 (默认为 std::equal_to) * @param timeout_ms 超时时间(毫秒),0表示无限等待 * @param interval_ms 检查间隔(毫秒) * @return true 变量值符合预期 * @return false 超时或条件不满足 */ template > bool value_wait(const std::function& value_ref, const T& expected, Compare comparator = Compare(), unsigned long timeout_ms = 0, unsigned long interval_ms = 100) { auto start = std::chrono::steady_clock::now(); while (true) { T value = value_ref(); if (comparator(value, expected)) { return true; } if (timeout_ms > 0) { auto elapsed = std::chrono::duration_cast( std::chrono::steady_clock::now() - start) .count(); if (elapsed >= timeout_ms) { return false; } } std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms)); } } class ScopeExit { public: ScopeExit() = default; template ScopeExit(F&& f) : func_(std::forward(f)) { } ScopeExit(const ScopeExit&) = delete; ScopeExit& operator=(const ScopeExit&) = delete; ScopeExit(ScopeExit&& other) noexcept : func_(std::move(other.func_)) { other.func_ = nullptr; } ScopeExit& operator=(ScopeExit&& other) noexcept { if (this != &other) { if (func_) func_(); func_ = std::move(other.func_); other.func_ = nullptr; } return *this; } ~ScopeExit() { if (func_) func_(); } void dismiss() noexcept { func_ = nullptr; } private: std::function func_; }; #define _SCOPE_EXIT_CONCAT(a, b) a##b #define _MAKE_ON_SCOPE_EXIT(line) ScopeExit _SCOPE_EXIT_CONCAT(exit_defer_, line) = [&]() #define ON_SCOPE_EXIT _MAKE_ON_SCOPE_EXIT(__LINE__) #endif // ASSISTANT_H