# 函数：设置 C++ 标准及相关编译选项
# 参数 standard: 需要设置的 C++ 标准版本 (例如 11, 14, 17, 20, 23)
function(set_cpp_standard standard)
    # --- 参数验证 ---
    set(VALID_STANDARDS 11 14 17 20 23) # 定义支持的 C++ 标准列表
    list(FIND VALID_STANDARDS ${standard} _standard_index) # 查找 standard 是否在列表中
    if(_standard_index EQUAL -1) # 如果未找到
        message(WARNING "**非标准 C++ 版本**: ${standard}。支持的版本有: ${VALID_STANDARDS}")
        # 可选：可以设置为一个默认值或停止配置
        # message(FATAL_ERROR "不支持的 C++ 标准: ${standard}")
        # set(standard 17) # 或者设置为默认值，例如 C++17
        # message(WARNING "已将 C++ 标准设置为默认值: ${standard}")
    endif()

    # --- 设置 C++ 标准 ---
    # 指定需要的 C++ 标准，设置到父作用域，使其对调用者定义的 target 生效
    set(CMAKE_CXX_STANDARD ${standard} PARENT_SCOPE)
    # **强制要求此标准**，如果编译器不支持则配置时报错
    set(CMAKE_CXX_STANDARD_REQUIRED ON PARENT_SCOPE)
    # **禁用编译器特定的扩展**，使用更纯粹的标准 C++
    set(CMAKE_CXX_EXTENSIONS OFF PARENT_SCOPE)

    # --- 平台特定设置 ---
    if(WIN32 OR CYGWIN)
        # 为 Windows 定义 UNICODE 宏
        add_definitions(-DUNICODE -D_UNICODE)
        # 可选：添加 WIN32_LEAN_AND_MEAN 以减少 Windows 头文件包含，加快编译速度
        # add_definitions(-DWIN32_LEAN_AND_MEAN)
        message(STATUS "为 Windows 添加 UNICODE 定义")
    endif()

    # --- 编译器特定设置 ---
    if(MSVC)
        # **设置源代码和执行字符集为 UTF-8**
        add_compile_options(/utf-8)
        # **强制 MSVC 正确设置 __cplusplus 宏**，以便代码能准确判断 C++ 标准
        add_compile_options(/Zc:__cplusplus)
        # **设置警告级别为 W4** (较高警告级别)
        add_compile_options(/W4)
        # **禁用特定警告：C4100 未使用的形参** (有时用于接口兼容性)
        add_compile_options(/wd4100)
        # 禁用特定警告：C4996 使用了被标记为否决的函数或变量 (例如一些旧的 CRT 函数)
        add_compile_options(/wd4996)
        message(STATUS "为 MSVC 添加特定编译选项: /utf-8 /Zc:__cplusplus /W4 /wd4100 /wd4996")
    endif()

    # GCC/Clang 特定选项
    if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        # **启用常用警告**
        add_compile_options(-Wall -Wextra)
        # **禁用未使用参数的警告** (与 MSVC 的 /wd4100 对应)
        add_compile_options(-Wno-unused-parameter)
        # **设置输入和执行字符集为 UTF-8** (对应 MSVC 的 /utf-8)
        # 这有助于处理源代码中的 UTF-8 字符，并影响运行时字符编码，但控制台本身的显示需要环境配合
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finput-charset=UTF-8 -fexec-charset=UTF-8")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -finput-charset=UTF-8 -fexec-charset=UTF-8")

        # 根据 C++ 标准添加特定警告 (C++17 及以上)
        if(${standard} GREATER 14)
            # **启用阴影变量警告和非虚析构函数警告**
            add_compile_options(-Wshadow -Wnon-virtual-dtor)
            message(STATUS "为 GCC/Clang (C++${CMAKE_CXX_STANDARD}) 添加额外警告: -Wshadow -Wnon-virtual-dtor")
        endif()
        message(STATUS "为 GCC/Clang 添加特定编译选项: -Wall -Wextra -Wno-unused-parameter -finput-charset=UTF-8 -fexec-charset=UTF-8")
        # 注意: 控制台/终端的 UTF-8 输出显示通常还需要操作系统环境的配合 (例如 Linux/macOS 终端本身设置，Windows下 chcp 65001)
    endif()

    # MinGW 特定设置 (通常在 Windows 上使用 GCC 工具链)
    if(MINGW)
        message(STATUS "检测到 MinGW 编译器")
        # 如果使用了 C++17 或更高版本, 可能需要链接 libstdc++exp 以支持 <filesystem> 等特性
        if(${standard} GREATER 14)
            message(STATUS "**为 MinGW C++${CMAKE_CXX_STANDARD} 添加 libstdc++fs 库依赖** (用于 <filesystem>)")
            # 注意：较新版本的 MinGW 可能不再需要显式链接，或者需要链接的是 -lstdc++fs
            # link_libraries() 会影响后续所有 target，更推荐使用 target_link_libraries()
            # 这里暂时保留 link_libraries()，但建议后续根据具体 target 调整
            # 尝试链接 stdc++fs，这在较新的 MinGW 中更常见用于 <filesystem>
#            link_libraries(-lstdc++fs)
            # 如果链接 -lstdc++fs 失败，可以尝试回退到 -lstdc++exp
            link_libraries(-lstdc++exp)
        endif()
    endif()

    message(STATUS "**C++ 标准已设置为: c++${standard}**")
endfunction()
