mirror of
https://github.com/gulrak/filesystem.git
synced 2025-12-07 01:06:38 +08:00
Compare commits
No commits in common. "master" and "v1.4.0" have entirely different histories.
27
.cirrus.yml
27
.cirrus.yml
@ -1,6 +1,6 @@
|
|||||||
freebsd_task:
|
freebsd_task:
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-14-0
|
image_family: freebsd-12-1
|
||||||
install_script: |
|
install_script: |
|
||||||
pkg install -y cmake
|
pkg install -y cmake
|
||||||
pw groupadd testgrp
|
pw groupadd testgrp
|
||||||
@ -11,24 +11,25 @@ freebsd_task:
|
|||||||
test_script: |
|
test_script: |
|
||||||
sudo -u testuser .ci/unix-test.sh
|
sudo -u testuser .ci/unix-test.sh
|
||||||
|
|
||||||
rockylinux8_task:
|
centos7_task:
|
||||||
container:
|
container:
|
||||||
image: docker.io/rockylinux:8
|
image: centos:7
|
||||||
install_script: |
|
install_script: |
|
||||||
dnf group install -y "Development Tools"
|
yum install -y centos-release-scl
|
||||||
dnf install cmake -y
|
yum install -y devtoolset-9
|
||||||
|
curl -L https://github.com/Kitware/CMake/releases/download/v3.16.4/cmake-3.16.4-Linux-x86_64.tar.gz | tar xzvf - -C /usr/local --strip-components 1
|
||||||
build_script: |
|
build_script: |
|
||||||
.ci/unix-build.sh
|
source /opt/rh/devtoolset-9/enable && PATH=$PATH:/usr/local/bin .ci/unix-build.sh
|
||||||
test_script: |
|
test_script: |
|
||||||
.ci/unix-test.sh
|
PATH=$PATH:/usr/local/bin .ci/unix-test.sh
|
||||||
|
|
||||||
rockylinux9_task:
|
centos8_task:
|
||||||
container:
|
container:
|
||||||
image: docker.io/rockylinux:9
|
image: centos:8
|
||||||
install_script: |
|
install_script: |
|
||||||
dnf group install -y "Development Tools"
|
yum group install -y "Development Tools"
|
||||||
dnf install cmake -y
|
curl -L https://github.com/Kitware/CMake/releases/download/v3.16.4/cmake-3.16.4-Linux-x86_64.tar.gz | tar xzvf - -C /usr/local --strip-components 1
|
||||||
build_script: |
|
build_script: |
|
||||||
.ci/unix-build.sh
|
PATH=$PATH:/usr/local/bin .ci/unix-build.sh
|
||||||
test_script: |
|
test_script: |
|
||||||
.ci/unix-test.sh
|
PATH=$PATH:/usr/local/bin .ci/unix-test.sh
|
||||||
170
.github/workflows/build_cmake.yml
vendored
170
.github/workflows/build_cmake.yml
vendored
@ -1,170 +0,0 @@
|
|||||||
name: CMake Build Matrix
|
|
||||||
|
|
||||||
on: [ push, pull_request ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: ${{ matrix.config.name }}
|
|
||||||
runs-on: ${{ matrix.config.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
config:
|
|
||||||
- name: "Ubuntu 22.04 GCC 11"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
build_type: Release
|
|
||||||
packages: ninja-build
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: gcc
|
|
||||||
cxx: g++
|
|
||||||
|
|
||||||
- name: "Ubuntu 22.04 Clang 13.0"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
build_type: Release
|
|
||||||
packages: ninja-build libc++-13-dev libc++abi-13-dev
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: clang-13
|
|
||||||
cxx: clang++-13
|
|
||||||
|
|
||||||
- name: "Ubuntu 22.04 Clang 15.0"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
build_type: Release
|
|
||||||
packages: ninja-build libc++-15-dev libc++abi-15-dev
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: clang-15
|
|
||||||
cxx: clang++-15
|
|
||||||
|
|
||||||
- name: "Ubuntu 22.04 GCC 11 coverage"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
build_type: Debug
|
|
||||||
packages: ninja-build lcov
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: gcc
|
|
||||||
cxx: g++
|
|
||||||
|
|
||||||
- name: "Ubuntu 20.04 GCC 9.3"
|
|
||||||
os: ubuntu-20.04
|
|
||||||
build_type: Release
|
|
||||||
packages: ninja-build
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: gcc
|
|
||||||
cxx: g++
|
|
||||||
|
|
||||||
- name: "Ubuntu 20.04 Clang 10.0"
|
|
||||||
os: ubuntu-20.04
|
|
||||||
build_type: Release
|
|
||||||
packages: ninja-build
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: clang-10
|
|
||||||
cxx: clang++-10
|
|
||||||
|
|
||||||
- name: "Ubuntu 20.04 Clang 11.0"
|
|
||||||
os: ubuntu-20.04
|
|
||||||
build_type: Release
|
|
||||||
packages: ninja-build clang-11 libc++-11-dev libc++abi-11-dev
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: clang-11
|
|
||||||
cxx: clang++-11
|
|
||||||
|
|
||||||
- name: "Ubuntu 20.04 GCC 9.3 coverage"
|
|
||||||
os: ubuntu-20.04
|
|
||||||
build_type: Debug
|
|
||||||
packages: ninja-build lcov
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: gcc
|
|
||||||
cxx: g++
|
|
||||||
|
|
||||||
- name: "Windows MSVC 2019"
|
|
||||||
os: windows-2019
|
|
||||||
build_type: Release
|
|
||||||
packages: ninja
|
|
||||||
generator: "Visual Studio 16 2019"
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: cl
|
|
||||||
cxx: cl
|
|
||||||
|
|
||||||
- name: "macOS 13 AppleClang"
|
|
||||||
os: macos-13
|
|
||||||
build_type: Release
|
|
||||||
packages: ninja
|
|
||||||
generator: Ninja
|
|
||||||
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
|
|
||||||
cc: clang
|
|
||||||
cxx: clang++
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: print environment
|
|
||||||
run: |
|
|
||||||
echo github.event.action: ${{ github.event.action }}
|
|
||||||
echo github.event_name: ${{ github.event_name }}
|
|
||||||
|
|
||||||
- name: Install dependencies on Ubuntu
|
|
||||||
if: startsWith(matrix.config.os, 'ubuntu')
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install ${{ matrix.config.packages }}
|
|
||||||
|
|
||||||
- name: Install dependencies on windows
|
|
||||||
if: startsWith(matrix.config.os, 'windows')
|
|
||||||
run: |
|
|
||||||
choco install ${{ matrix.config.packages }}
|
|
||||||
|
|
||||||
- name: Install dependencies on macOS
|
|
||||||
if: startsWith(matrix.config.os, 'macos')
|
|
||||||
run: |
|
|
||||||
brew install ${{ matrix.config.packages }}
|
|
||||||
|
|
||||||
- name: Configure project
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
export CC=${{ matrix.config.cc }}
|
|
||||||
export CXX=${{ matrix.config.cxx }}
|
|
||||||
ninja --version
|
|
||||||
cmake --version
|
|
||||||
mkdir build
|
|
||||||
mkdir install
|
|
||||||
if [[ "${{ matrix.config.build_type }}" == "Debug" ]]; then
|
|
||||||
cmake -G "${{ matrix.config.generator }}" -S . -B build -DCMAKE_BUILD_TYPE=Debug -DGHC_COVERAGE=ON -DGHC_FILESYSTEM_TEST_COMPILE_FEATURES="${{ matrix.config.compatibility }}" -DCMAKE_INSTALL_PREFIX:PATH=install
|
|
||||||
else
|
|
||||||
cmake -G "${{ matrix.config.generator }}" -S . -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} -DGHC_FILESYSTEM_TEST_COMPILE_FEATURES="${{ matrix.config.compatibility }}" -DCMAKE_INSTALL_PREFIX:PATH=install
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Build project
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
cmake --build build --config ${{ matrix.config.build_type }}
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: |
|
|
||||||
cd build && ctest -C ${{ matrix.config.build_type }}
|
|
||||||
|
|
||||||
- name: Collect coverage info
|
|
||||||
if: startsWith(matrix.config.build_type, 'Debug')
|
|
||||||
run: |
|
|
||||||
cd build
|
|
||||||
lcov --compat-libtool --directory . --capture --output-file coverage_output.info
|
|
||||||
lcov --remove coverage_output.info '/usr/*' '*/c++/*' '*.h' '*/catch.hpp' -o coverage.info
|
|
||||||
# sed -i 's|SF:/.*/filesystem/|SF:../|g' coverage.info
|
|
||||||
|
|
||||||
- name: Upload coverage info
|
|
||||||
if: startsWith(matrix.config.build_type, 'Debug')
|
|
||||||
env:
|
|
||||||
COVERALLS_DEBUG: true
|
|
||||||
NODE_COVERALLS_DEBUG: 1
|
|
||||||
uses: coverallsapp/github-action@master
|
|
||||||
with:
|
|
||||||
path-to-lcov: ${{ github.workspace }}/build/coverage.info
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
100
.travis.yml
Normal file
100
.travis.yml
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
language: cpp
|
||||||
|
|
||||||
|
dist: xenial # default distribution
|
||||||
|
os: linux # default os
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
include:
|
||||||
|
- env: MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["g++-5"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["g++-6"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["g++-7"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && GENERATOR='Unix Makefiles' && CONFIG=Debug && GHC_COVERAGE=1"
|
||||||
|
addons: { apt: { packages: ["g++-7", "lcov"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=gcc-8 && CXX=g++-8 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["g++-8"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=gcc-9 && CXX=g++-9 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["g++-9"], sources: ["ubuntu-toolchain-r-test"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["clang-5.0"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["clang-6.0"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=clang-7 && CXX=clang++-7 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["clang-7", "libc++-7-dev", "libc++abi-7-dev"], sources: ["llvm-toolchain-xenial-7"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=clang-8 && CXX=clang++-8 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["clang-8", "libc++-8-dev", "libc++abi-8-dev"], sources: ["llvm-toolchain-xenial-8"] } }
|
||||||
|
|
||||||
|
- env: MATRIX_EVAL="CC=clang-9 && CXX=clang++-9 && GENERATOR='Unix Makefiles' && CONFIG=Release"
|
||||||
|
addons: { apt: { packages: ["clang-9", "libc++-9-dev", "libc++abi-9-dev"], sources: [{sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main', key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'}] } }
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
|
||||||
|
osx_image: xcode9.2
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
|
||||||
|
osx_image: xcode10.1
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
|
||||||
|
osx_image: xcode11.3
|
||||||
|
|
||||||
|
install:
|
||||||
|
- eval "${MATRIX_EVAL}"
|
||||||
|
- |
|
||||||
|
if [ "${GHC_COVERAGE}" = "1" ]; then
|
||||||
|
gem install coveralls-lcov
|
||||||
|
fi
|
||||||
|
- $CC --version
|
||||||
|
- $CXX --version
|
||||||
|
- cmake --version
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- eval "${MATRIX_EVAL}"
|
||||||
|
- mkdir build
|
||||||
|
- cd build
|
||||||
|
- export VERBOSE=1
|
||||||
|
- |
|
||||||
|
if [ "${CONFIG}" = "Debug" ]; then
|
||||||
|
cmake -G"${GENERATOR}" -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} -DCMAKE_BUILD_TYPE=${CONFIG} -DGHC_COVERAGE=ON ..
|
||||||
|
else
|
||||||
|
cmake -G"${GENERATOR}" -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} -DCMAKE_BUILD_TYPE=${CONFIG} ..
|
||||||
|
fi
|
||||||
|
|
||||||
|
script:
|
||||||
|
- export VERBOSE=1
|
||||||
|
- cmake --build . --config ${CONFIG} --target filesystem_test
|
||||||
|
- |
|
||||||
|
if [ "${GHC_COVERAGE}" = "1" ]; then
|
||||||
|
cmake --build . --config ${CONFIG} --target filesystem_test
|
||||||
|
test/filesystem_test
|
||||||
|
else
|
||||||
|
cmake --build . --config ${CONFIG}
|
||||||
|
ctest -C ${CONFIG} -E Windows
|
||||||
|
if [ -f "test/std_filesystem_test" ]; then
|
||||||
|
test/std_filesystem_test || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- |
|
||||||
|
if [ "${GHC_COVERAGE}" = "1" ]; then
|
||||||
|
lcov --compat-libtool --directory . --capture --output-file coverage_output.info
|
||||||
|
lcov --remove coverage_output.info '/usr/*' '*/c++/*' '*.h' '*/catch.hpp' -o coverage.info
|
||||||
|
sed -i 's|SF:/.*/filesystem/|SF:../|g' coverage.info
|
||||||
|
coveralls-lcov coverage.info
|
||||||
|
fi
|
||||||
@ -1,55 +1,41 @@
|
|||||||
cmake_minimum_required(VERSION 3.7.2)
|
cmake_minimum_required(VERSION 3.7.2)
|
||||||
project(
|
project(ghcfilesystem)
|
||||||
ghcfilesystem,
|
|
||||||
VERSION 1.5.15
|
|
||||||
)
|
|
||||||
|
|
||||||
if (POLICY CMP0077)
|
|
||||||
cmake_policy(SET CMP0077 NEW)
|
|
||||||
endif()
|
|
||||||
if(POLICY CMP0110)
|
if(POLICY CMP0110)
|
||||||
cmake_policy(SET CMP0110 NEW)
|
cmake_policy(PUSH)
|
||||||
|
cmake_policy(SET CMP0110 OLD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
include(CMakeDependentOption)
|
||||||
option(GHC_FILESYSTEM_BUILD_TESTING "Enable tests" ON)
|
|
||||||
option(GHC_FILESYSTEM_BUILD_EXAMPLES "Build examples" ON)
|
cmake_dependent_option(GHC_FILESYSTEM_BUILD_TESTING
|
||||||
option(GHC_FILESYSTEM_WITH_INSTALL "With install target" ON)
|
"Enable tests" ON
|
||||||
else()
|
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||||
option(GHC_FILESYSTEM_BUILD_EXAMPLES "Build examples" OFF)
|
cmake_dependent_option(GHC_FILESYSTEM_BUILD_EXAMPLES
|
||||||
option(GHC_FILESYSTEM_BUILD_TESTING "Enable tests" OFF)
|
"Build examples" ON
|
||||||
option(GHC_FILESYSTEM_WITH_INSTALL "With install target" OFF)
|
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||||
endif()
|
cmake_dependent_option(GHC_FILESYSTEM_WITH_INSTALL
|
||||||
option(GHC_FILESYSTEM_BUILD_STD_TESTING "Enable STD tests" ${GHC_FILESYSTEM_BUILD_TESTING})
|
"With install target" ON
|
||||||
if(NOT DEFINED GHC_FILESYSTEM_TEST_COMPILE_FEATURES)
|
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||||
set(GHC_FILESYSTEM_TEST_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT DEFINED CMAKE_CXX_STANDARD)
|
if(NOT DEFINED CMAKE_CXX_STANDARD)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
if(NOT CYGWIN)
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
if(CMAKE_CXX_STANDARD LESS 11)
|
if(CMAKE_CXX_STANDARD LESS 11)
|
||||||
message(FATAL_ERROR "CMAKE_CXX_STANDARD is less than 11, ghc::filesystem only works with C++11 and above.")
|
message(FATAL_ERROR "CMAKE_CXX_STANDARD is less than 11, ghc::filesystem only works with C++11 and above.")
|
||||||
endif()
|
endif()
|
||||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
|
||||||
message(STATUS "System name: ${CMAKE_SYSTEM_NAME}")
|
|
||||||
message(STATUS "Compiler ID: ${CMAKE_CXX_COMPILER_ID}")
|
|
||||||
message(STATUS "CMAKE_CXX_COMPILE_FEATURES: ${CMAKE_CXX_COMPILE_FEATURES}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(ghc_filesystem INTERFACE)
|
add_library(ghc_filesystem INTERFACE)
|
||||||
add_library(ghcFilesystem::ghc_filesystem ALIAS ghc_filesystem)
|
|
||||||
target_include_directories(ghc_filesystem INTERFACE
|
target_include_directories(ghc_filesystem INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<INSTALL_INTERFACE:include>)
|
$<INSTALL_INTERFACE:include>)
|
||||||
target_compile_options(ghc_filesystem INTERFACE "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
target_compile_options(ghc_filesystem INTERFACE "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
||||||
target_compile_options(ghc_filesystem INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
target_compile_options(ghc_filesystem INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
||||||
|
|
||||||
if(GHC_FILESYSTEM_BUILD_TESTING OR GHC_FILESYSTEM_BUILD_EXAMPLES)
|
get_directory_property(hasParent PARENT_DIRECTORY)
|
||||||
|
if(NOT hasParent)
|
||||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||||
include(GhcHelper)
|
include(GhcHelper)
|
||||||
@ -67,24 +53,12 @@ endif()
|
|||||||
if(GHC_FILESYSTEM_WITH_INSTALL)
|
if(GHC_FILESYSTEM_WITH_INSTALL)
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
install(TARGETS ghc_filesystem EXPORT ghc_filesystem-targets)
|
install(TARGETS ghc_filesystem EXPORT ghcFilesystemConfig)
|
||||||
install(EXPORT ghc_filesystem-targets NAMESPACE ghcFilesystem:: DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem")
|
install(EXPORT ghcFilesystemConfig NAMESPACE ghcFilesystem:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ghcFilesystem)
|
||||||
export(EXPORT ghc_filesystem-targets NAMESPACE ghcFilesystem:: FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/ghc_filesystem-targets.cmake")
|
endif()
|
||||||
configure_package_config_file(
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.cmake.in"
|
if(POLICY CMP0110)
|
||||||
"${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config.cmake"
|
cmake_policy(POP)
|
||||||
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem"
|
|
||||||
PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
|
|
||||||
write_basic_package_version_file(
|
|
||||||
"${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config-version.cmake"
|
|
||||||
VERSION ${PROJECT_VERSION}
|
|
||||||
COMPATIBILITY SameMinorVersion
|
|
||||||
)
|
|
||||||
install(
|
|
||||||
FILES
|
|
||||||
"${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config.cmake"
|
|
||||||
"${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config-version.cmake"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem"
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
642
README.md
642
README.md
@ -1,58 +1,25 @@
|
|||||||

|

|
||||||

|

|
||||||
[](https://github.com/gulrak/filesystem/actions/workflows/build_cmake.yml)
|
[](https://travis-ci.org/gulrak/filesystem)
|
||||||
[](https://ci.appveyor.com/project/gulrak/filesystem)
|
[](https://ci.appveyor.com/project/gulrak/filesystem)
|
||||||
[](https://cirrus-ci.com/github/gulrak/filesystem)
|
[](https://cirrus-ci.com/github/gulrak/filesystem)
|
||||||
|
[](https://cloud.drone.io/gulrak/filesystem)
|
||||||
[](https://coveralls.io/github/gulrak/filesystem?branch=master)
|
[](https://coveralls.io/github/gulrak/filesystem?branch=master)
|
||||||
[](https://github.com/gulrak/filesystem/tree/v1.5.14)
|
[](https://github.com/gulrak/filesystem/tree/v1.4.0)
|
||||||
<!-- [](https://cloud.drone.io/gulrak/filesystem) -->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- TOC -->
|
|
||||||
* [Filesystem](#filesystem)
|
|
||||||
* [Motivation](#motivation)
|
|
||||||
* [Why the namespace GHC?](#why-the-namespace-ghc)
|
|
||||||
* [Platforms](#platforms)
|
|
||||||
* [Tests](#tests)
|
|
||||||
* [Usage](#usage)
|
|
||||||
* [Downloads](#downloads)
|
|
||||||
* [Using it as Single-File-Header](#using-it-as-single-file-header)
|
|
||||||
* [Using it as Forwarding-/Implementation-Header](#using-it-as-forwarding-implementation-header)
|
|
||||||
* [Git Submodule and CMake](#git-submodule-and-cmake)
|
|
||||||
* [Versioning](#versioning)
|
|
||||||
* [Documentation](#documentation)
|
|
||||||
* [`ghc::filesystem::ifstream`, `ghc::filesystem::ofstream`, `ghc::filesystem::fstream`](#ghcfilesystemifstream--ghcfilesystemofstream--ghcfilesystemfstream)
|
|
||||||
* [`ghc::filesystem::u8arguments`](#ghcfilesystemu8arguments)
|
|
||||||
* [Differences](#differences)
|
|
||||||
* [LWG Defects](#lwg-defects)
|
|
||||||
* [Not Implemented on C++ before C++17](#not-implemented-on-c-before-c17)
|
|
||||||
* [Differences in API](#differences-in-api)
|
|
||||||
* [Differences of Specific Interfaces](#differences-of-specific-interfaces)
|
|
||||||
* [Differences in Behavior](#differences-in-behavior)
|
|
||||||
* [fs.path (ref)](#fspath--ref-)
|
|
||||||
* [Open Issues](#open-issues)
|
|
||||||
* [Windows](#windows)
|
|
||||||
* [Symbolic Links on Windows](#symbolic-links-on-windows)
|
|
||||||
* [Permissions](#permissions)
|
|
||||||
* [Release Notes](#release-notes)
|
|
||||||
<!-- TOC -->
|
|
||||||
|
|
||||||
# Filesystem
|
# Filesystem
|
||||||
|
|
||||||
This is a header-only single-file `std::filesystem` compatible helper library,
|
This is a header-only single-file std::filesystem compatible helper library,
|
||||||
based on the C++17 and C++20 specs, but implemented for C++11, C++14, C++17 or C++20
|
based on the C++17 and C++20 specs, but implemented for C++11, C++14, C++17 or C++20
|
||||||
(tightly following the C++17 standard with very few documented exceptions). It is currently tested on
|
(tightly following the C++17 standard with very few documented exceptions). It is currently tested on
|
||||||
macOS 10.12/10.14/10.15/11.6, Windows 10, Ubuntu 18.04, Ubuntu 20.04, CentOS 7, CentOS 8, FreeBSD 12,
|
macOS 10.12/10.14/10.15, Windows 10, Ubuntu 18.04, CentOS 7, CentOS 8, FreeBSD 12
|
||||||
Alpine ARM/ARM64 Linux and Solaris 10 but should work on other systems too, as long as you have
|
and Alpine ARM/ARM64 Linux but should work on other systems too, as long as you have
|
||||||
at least a C++11 compatible compiler. It should work with Android NDK, Emscripten and I even
|
at least a C++11 compatible compiler. It should work with Android NDK, Emscripten and I even
|
||||||
had reports of it being used on iOS (within sandboxing constraints) and with v1.5.6 there
|
had reports of it being used on iOS (within sandboxing constraints).
|
||||||
is experimental support for QNX. The support of Android NDK, Emscripten, QNX, and since 1.5.14
|
It is of course in its own namespace `ghc::filesystem` to not interfere with a regular `std::filesystem` should you use it in a mixed C++17
|
||||||
GNU/Hurd and Haiku is not backed up by automated testing but PRs and bug reports are welcome
|
environment (which is possible).
|
||||||
for those too and they are reported to work.
|
|
||||||
It is of course in its own namespace `ghc::filesystem` to not interfere with a regular `std::filesystem`
|
|
||||||
should you use it in a mixed C++17 environment (which is possible).
|
|
||||||
|
|
||||||
*Test coverage is well above 90%, and starting with v1.3.6 and in v1.5.0
|
*Test coverage is well above 90%, and starting with v1.3.6
|
||||||
more time was invested in benchmarking and optimizing parts of the library. I'll try
|
more time was invested in benchmarking and optimizing parts of the library. I'll try
|
||||||
to continue to optimize some parts and refactor others, striving
|
to continue to optimize some parts and refactor others, striving
|
||||||
to improve it as long as it doesn't introduce additional C++17/C++20 compatibility
|
to improve it as long as it doesn't introduce additional C++17/C++20 compatibility
|
||||||
@ -77,7 +44,7 @@ It is from after the standardization of C++17 but it contains the latest filesys
|
|||||||
interface changes compared to the
|
interface changes compared to the
|
||||||
[Working Draft N4659](https://github.com/cplusplus/draft/raw/master/papers/n4659.pdf).
|
[Working Draft N4659](https://github.com/cplusplus/draft/raw/master/papers/n4659.pdf).
|
||||||
Staring with v1.4.0, when compiled using C++20, it adapts to the changes according to path sorting order
|
Staring with v1.4.0, when compiled using C++20, it adapts to the changes according to path sorting order
|
||||||
and `std::u8string` handling from [Working Draft N4860](https://isocpp.org/files/papers/N4860.pdf).
|
and `std::u8string` handling from [Working Draft N4680](https://isocpp.org/files/papers/N4860.pdf).
|
||||||
|
|
||||||
I want to thank the people working on improving C++, I really liked how the language
|
I want to thank the people working on improving C++, I really liked how the language
|
||||||
evolved with C++11 and the following standards. Keep on the good work!
|
evolved with C++11 and the following standards. Keep on the good work!
|
||||||
@ -91,40 +58,36 @@ to do with Haskell**, sorry for the name clash).
|
|||||||
## Platforms
|
## Platforms
|
||||||
|
|
||||||
`ghc::filesystem` is developed on macOS but CI tested on macOS, Windows,
|
`ghc::filesystem` is developed on macOS but CI tested on macOS, Windows,
|
||||||
various Linux Distributions, FreeBSD and starting with v1.5.12 on Solaris.
|
various Linux Distributions and FreeBSD. It should work on any of these with a C++11-capable
|
||||||
It should work on any of these with a C++11-capable compiler. Also there are some
|
compiler. Also there are some checks to hopefully better work on Android, but
|
||||||
checks to hopefully better work on Android, but as I currently don't test with the
|
as I currently don't test with the Android NDK, I wouldn't call it a
|
||||||
Android NDK, I wouldn't call it a supported platform yet, same is valid for using
|
supported platform yet, same is valid for using it with Emscripten. It is now
|
||||||
it with Emscripten. It is now part of the detected platforms, I fixed the obvious
|
part of the detected platforms, I fixed the obvious issues and ran some tests with
|
||||||
issues and ran some tests with it, so it should be fine. All in all, I don't see it
|
it, so it should be fine. All in all, I don't see it replacing `std::filesystem`
|
||||||
replacing `std::filesystem` where full C++17 or C++20 is available, it doesn't try
|
where full C++17 or C++20 is available, it doesn't try to be a "better"
|
||||||
to be a "better" `std::filesystem`, just an almost drop-in if you can't use it
|
`std::filesystem`, just an almost drop-in if you can't use it (with the exception
|
||||||
(with the exception of the UTF-8 preference).
|
of the UTF-8 preference).
|
||||||
|
|
||||||
:information_source: **Important:** _This implementation is following the ["UTF-8 Everywhere" philosophy](https://utf8everywhere.org/) in that all
|
This implementation is following the ["UTF-8 Everywhere" philosophy](https://utf8everywhere.org/) in that all
|
||||||
`std::string` instances will be interpreted the same as `std::u8string` encoding
|
`std::string` instances will be interpreted the same as `std::u8string` encoding
|
||||||
wise and as being in UTF-8. The `std::u16string` will be seen as UTF-16. See *Differences in API*
|
wise and as being in UTF-8. The `std::u16string` will be seen as UTF-16. See *Differences in API*
|
||||||
for more information._
|
for more information.
|
||||||
|
|
||||||
Unit tests are currently run with:
|
Unit tests are currently run with:
|
||||||
|
|
||||||
* macOS 10.12: Xcode 9.2 (clang-900.0.39.2), GCC 9.2, Clang 9.0, macOS 10.13: Xcode 10.1, macOS 10.14: Xcode 11.2, macOS 10.15: Xcode 11.6, Xcode 12.4
|
* macOS 10.12: Xcode 9.2 (clang-900.0.39.2), GCC 9.2, Clang 9.0, macOS 10.13: Xcode 10.1, macOS 10.14: Xcode 11.2, macOS 10.15: Xcode 11.6
|
||||||
* Windows: Visual Studio 2017, Visual Studio 2015, Visual Studio 2019, MinGW GCC 6.3 (Win32), GCC 7.2 (Win64), Cygwin GCC 10.2 (no CI yet)
|
* Windows: Visual Studio 2017, Visual Studio 2015, Visual Studio 2019, MinGW GCC 6.3 (Win32), GCC 7.2 (Win64)
|
||||||
* Linux (Ubuntu): GCC (5.5, 6.5, 7.4, 8.3, 9.2), Clang (5.0, 6.0, 7.1, 8.0, 9.0)
|
* Linux (Ubuntu): GCC (5.5, 6.5, 7.4, 8.3, 9.2), Clang (5.0, 6.0, 7.1, 8.0, 9.0)
|
||||||
* ~~Linux (Alpine ARM/ARM64): GCC 9.2.0~~ (The Drone build scripts stopped working,
|
* Linux (Alpine ARM/ARM64): GCC 9.2.0
|
||||||
as they where a contribution, I couldn't figure out what went wrong, any help appreciated.)
|
|
||||||
* FreeBSD: Clang 8.0
|
* FreeBSD: Clang 8.0
|
||||||
* Solaris: GCC 5.5
|
|
||||||
|
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
The header comes with a set of unit-tests and uses [CMake](https://cmake.org/)
|
The header comes with a set of unit-tests and uses [CMake](https://cmake.org/)
|
||||||
as a build tool and [Catch2](https://github.com/catchorg/Catch2) as test framework.
|
as a build tool and [Catch2](https://github.com/catchorg/Catch2) as test framework.
|
||||||
All tests are registered with in CMake, so the [ctest](https://cmake.org/cmake/help/latest/manual/ctest.1.html)
|
|
||||||
commando can be used to run the tests.
|
|
||||||
|
|
||||||
All tests against this implementation should succeed, depending on your environment
|
All tests agains this implementation should succeed, depending on your environment
|
||||||
it might be that there are some warnings, e.g. if you have no rights to create
|
it might be that there are some warnings, e.g. if you have no rights to create
|
||||||
Symlinks on Windows or at least the test thinks so, but these are just informative.
|
Symlinks on Windows or at least the test thinks so, but these are just informative.
|
||||||
|
|
||||||
@ -135,11 +98,9 @@ mkdir build
|
|||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
make
|
make
|
||||||
ctest
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This generates the test binaries that run the tests and the last command executes
|
This generates `filesystem_test`, the binary that runs all tests.
|
||||||
them.
|
|
||||||
|
|
||||||
If the default compiler is a GCC 8 or newer, or Clang 7 or newer, it
|
If the default compiler is a GCC 8 or newer, or Clang 7 or newer, it
|
||||||
additionally tries to build a version of the test binary compiled against GCCs/Clangs
|
additionally tries to build a version of the test binary compiled against GCCs/Clangs
|
||||||
@ -154,90 +115,54 @@ in the standard, and there might be issues in these implementations too.
|
|||||||
|
|
||||||
### Downloads
|
### Downloads
|
||||||
|
|
||||||
The latest release version is [v1.5.14](https://github.com/gulrak/filesystem/tree/v1.5.14) and
|
The latest release version is [v1.4.0](https://github.com/gulrak/filesystem/tree/v1.4.0) and
|
||||||
source archives can be found [here](https://github.com/gulrak/filesystem/releases/tag/v1.5.14).
|
|
||||||
|
|
||||||
The latest pre-native-backend version is [v1.4.0](https://github.com/gulrak/filesystem/tree/v1.4.0) and
|
|
||||||
source archives can be found [here](https://github.com/gulrak/filesystem/releases/tag/v1.4.0).
|
source archives can be found [here](https://github.com/gulrak/filesystem/releases/tag/v1.4.0).
|
||||||
|
|
||||||
The latest pre-C++20-support release version is [v1.3.10](https://github.com/gulrak/filesystem/tree/v1.3.10) and
|
The latest pre-C++20 release version is [v1.3.10](https://github.com/gulrak/filesystem/tree/v1.3.10) and
|
||||||
source archives can be found [here](https://github.com/gulrak/filesystem/releases/tag/v1.3.10).
|
source archives can be found [here](https://github.com/gulrak/filesystem/releases/tag/v1.3.10).
|
||||||
|
|
||||||
Currently only the latest minor release version receives bugfixes, so if possible,
|
|
||||||
you should use the latest release.
|
|
||||||
|
|
||||||
### Using it as Single-File-Header
|
### Using it as Single-File-Header
|
||||||
|
|
||||||
As `ghc::filesystem` is at first a header-only library, it should be enough to copy the header
|
As `ghc::filesystem` is at first a header-only library, it should be enough to copy the header
|
||||||
or the `include/ghc` directory into your project folder or point your include path to this place and
|
or the `include/ghc` directory into your project folder oder point your include path to this place and
|
||||||
simply include the `filesystem.hpp` header (or `ghc/filesystem.hpp` if you use the subdirectory).
|
simply include the `filesystem.hpp` header (or `ghc/filesystem.hpp` if you use the subdirectory).
|
||||||
|
|
||||||
Everything is in the namespace `ghc::filesystem`, so one way to use it only as
|
Everything is in the namespace `ghc::filesystem`, so one way to use it only as
|
||||||
a fallback could be:
|
a fallback could be:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
|
||||||
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
|
||||||
#define GHC_USE_STD_FS
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
|
||||||
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
|
||||||
// and watchOS 6.0.
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Availability.h>
|
|
||||||
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
|
||||||
// released after std::filesystem, where std::filesystem is always available.
|
|
||||||
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
|
||||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
|
||||||
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
|
||||||
#undef GHC_USE_STD_FS
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GHC_USE_STD_FS
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
#else
|
#endif
|
||||||
#include "filesystem.hpp"
|
#endif
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
namespace fs = ghc::filesystem;
|
namespace fs = ghc::filesystem;
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note that this code uses a two-stage preprocessor condition because Visual Studio 2015
|
||||||
|
doesn't like the `(<...>)` syntax, even if it could cut evaluation early before. This code also
|
||||||
|
used the minimum deployment target to detect if std::filesystem really is available on macOS
|
||||||
|
compilation.**
|
||||||
|
|
||||||
|
**Note also, this detection now works on MSVC versions prior to 15.7 on, or without setting
|
||||||
|
the `/Zc:__cplusplus` compile switch that would fix `__cplusplus` on MSVC. (Without the switch
|
||||||
|
the compiler allways reports `199711L`
|
||||||
|
([see](https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/)),
|
||||||
|
but `_MSVC_LANG` works without it.**
|
||||||
|
|
||||||
If you want to also use the `fstream` wrapper with `path` support as fallback,
|
If you want to also use the `fstream` wrapper with `path` support as fallback,
|
||||||
you might use:
|
you might use:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
|
||||||
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
|
||||||
#define GHC_USE_STD_FS
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
|
||||||
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
|
||||||
// and watchOS 6.0.
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Availability.h>
|
|
||||||
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
|
||||||
// released after std::filesystem, where std::filesystem is always available.
|
|
||||||
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
|
||||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
|
||||||
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
|
||||||
#undef GHC_USE_STD_FS
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GHC_USE_STD_FS
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
namespace fs {
|
namespace fs {
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
@ -245,8 +170,10 @@ you might use:
|
|||||||
using ofstream = std::ofstream;
|
using ofstream = std::ofstream;
|
||||||
using fstream = std::fstream;
|
using fstream = std::fstream;
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
#include "filesystem.hpp"
|
#endif
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
namespace fs {
|
namespace fs {
|
||||||
using namespace ghc::filesystem;
|
using namespace ghc::filesystem;
|
||||||
using ifstream = ghc::filesystem::ifstream;
|
using ifstream = ghc::filesystem::ifstream;
|
||||||
@ -259,19 +186,15 @@ you might use:
|
|||||||
Now you have e.g. `fs::ofstream out(somePath);` and it is either the wrapper or
|
Now you have e.g. `fs::ofstream out(somePath);` and it is either the wrapper or
|
||||||
the C++17 `std::ofstream`.
|
the C++17 `std::ofstream`.
|
||||||
|
|
||||||
:information_source: **Be aware, as a header-only library, it is not hiding the fact, that it
|
**Be aware, as a header-only library, it is not hiding the fact, that it
|
||||||
uses system includes, so they "pollute" your global namespace. Use the
|
uses system includes, so they "pollute" your global namespace.**
|
||||||
forwarding-/implementation-header based approach (see below) to avoid this.
|
|
||||||
For Windows it needs `Windows.h` and it might be a good idea to define
|
|
||||||
`WIN32_LEAN_AND_MEAN` or `NOMINMAX` prior to including `filesystem.hpp` or
|
|
||||||
`fs_std.hpp` headers to reduce pollution of your global namespace and compile
|
|
||||||
time. They are not defined by `ghc::filesystem` to allow combination with contexts
|
|
||||||
where the full `Windows.h`is needed, e.g. for UI elements.**
|
|
||||||
|
|
||||||
:information_source: **Hint:** There is an additional header named `ghc/fs_std.hpp` that implements this
|
:information_source: **Hint:** There is an additional header named `ghc/fs_std.hpp` that implements this
|
||||||
dynamic selection of a filesystem implementation, that you can include
|
dynamic selection of a filesystem implementation, that you can include
|
||||||
instead of `ghc/filesystem.hpp` when you want `std::filesystem` where
|
instead of `ghc/filesystem.hpp` when you want std::filesystem where
|
||||||
available and `ghc::filesystem` where not.
|
available and ghc::filesystem where not. It also enables the `wchar_t`
|
||||||
|
support on `ghc::filesystem` on Windows, so the resulting implementation
|
||||||
|
in the `fs` namespace will be compatible.
|
||||||
|
|
||||||
|
|
||||||
### Using it as Forwarding-/Implementation-Header
|
### Using it as Forwarding-/Implementation-Header
|
||||||
@ -279,9 +202,9 @@ available and `ghc::filesystem` where not.
|
|||||||
Alternatively, starting from v1.1.0 `ghc::filesystem` can also be used by
|
Alternatively, starting from v1.1.0 `ghc::filesystem` can also be used by
|
||||||
including one of two additional wrapper headers. These allow to include
|
including one of two additional wrapper headers. These allow to include
|
||||||
a forwarded version in most places (`ghc/fs_fwd.hpp`) while hiding the
|
a forwarded version in most places (`ghc/fs_fwd.hpp`) while hiding the
|
||||||
implementation details in a single cpp file that includes `ghc/fs_impl.hpp` to
|
implementation details in a single cpp that includes `ghc/fs_impl.hpp` to
|
||||||
implement the needed code. Using `ghc::filesystem` this way makes sure
|
implement the needed code. That way system includes are only visible from
|
||||||
system includes are only visible from inside the cpp file, all other places are clean.
|
inside the cpp, all other places are clean.
|
||||||
|
|
||||||
Be aware, that it is currently not supported to hide the implementation
|
Be aware, that it is currently not supported to hide the implementation
|
||||||
into a Windows-DLL, as a DLL interface with C++ standard templates in interfaces
|
into a Windows-DLL, as a DLL interface with C++ standard templates in interfaces
|
||||||
@ -292,31 +215,9 @@ If you use the forwarding/implementation approach, you can still use the dynamic
|
|||||||
switching like this:
|
switching like this:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
|
||||||
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
|
||||||
#define GHC_USE_STD_FS
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
|
||||||
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
|
||||||
// and watchOS 6.0.
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Availability.h>
|
|
||||||
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
|
||||||
// released after std::filesystem, where std::filesystem is always available.
|
|
||||||
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
|
||||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
|
||||||
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
|
||||||
#undef GHC_USE_STD_FS
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GHC_USE_STD_FS
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
namespace fs {
|
namespace fs {
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
@ -324,8 +225,10 @@ switching like this:
|
|||||||
using ofstream = std::ofstream;
|
using ofstream = std::ofstream;
|
||||||
using fstream = std::fstream;
|
using fstream = std::fstream;
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
#include "fs_fwd.hpp"
|
#endif
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
#include <ghc/fs-fwd.hpp>
|
||||||
namespace fs {
|
namespace fs {
|
||||||
using namespace ghc::filesystem;
|
using namespace ghc::filesystem;
|
||||||
using ifstream = ghc::filesystem::ifstream;
|
using ifstream = ghc::filesystem::ifstream;
|
||||||
@ -339,38 +242,22 @@ and in the implementation hiding cpp, you might use (before any include that inc
|
|||||||
to take precedence:
|
to take precedence:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
|
||||||
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
|
||||||
#define GHC_USE_STD_FS
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
|
||||||
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
|
||||||
// and watchOS 6.0.
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Availability.h>
|
|
||||||
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
|
||||||
// released after std::filesystem, where std::filesystem is always available.
|
|
||||||
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
|
||||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
|
||||||
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
|
||||||
#undef GHC_USE_STD_FS
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GHC_USE_STD_FS
|
#ifndef GHC_USE_STD_FS
|
||||||
#include "fs_impl.hpp"
|
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
:information_source: **Hint:** There are additional helper headers, named `ghc/fs_std_fwd.hpp` and
|
:information_source: **Hint:** There are additional helper headers, named `ghc/fs_std_fwd.hpp` and
|
||||||
`ghc/fs_std_impl.hpp` that use this technique, so you can simply include them
|
`ghc/fs_std_impl.hpp` that use this technique, so you can simply include them
|
||||||
if you want to dynamically select the filesystem implementation.
|
if you want to dynamically select the filesystem implementation. they also
|
||||||
|
enable the `wchar_t` support on `ghc::filesystem` on Windows, so the resulting
|
||||||
|
implementation in the `fs` namespace will be compatible.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -382,7 +269,7 @@ as a git submodule, add the directory to your `CMakeLists.txt` with
|
|||||||
to ensure correct include path that allow `#include <ghc/filesystem.hpp>`
|
to ensure correct include path that allow `#include <ghc/filesystem.hpp>`
|
||||||
to work.
|
to work.
|
||||||
|
|
||||||
The `CMakeLists.txt` offers a few options to customize its behavior:
|
The `CMakeLists.txt` offers a few options to customize its behaviour:
|
||||||
|
|
||||||
* `GHC_FILESYSTEM_BUILD_TESTING` - Compile tests, default is `OFF` when used as
|
* `GHC_FILESYSTEM_BUILD_TESTING` - Compile tests, default is `OFF` when used as
|
||||||
a submodule, else `ON`.
|
a submodule, else `ON`.
|
||||||
@ -390,16 +277,6 @@ The `CMakeLists.txt` offers a few options to customize its behavior:
|
|||||||
a submodule, else `ON`.
|
a submodule, else `ON`.
|
||||||
* `GHC_FILESYSTEM_WITH_INSTALL` - Add install target to build, default is `OFF` when used as
|
* `GHC_FILESYSTEM_WITH_INSTALL` - Add install target to build, default is `OFF` when used as
|
||||||
a submodule, else `ON`.
|
a submodule, else `ON`.
|
||||||
* `GHC_FILESYSTEM_BUILD_STD_TESTING` - Compile `std_filesystem_test`, the variant of
|
|
||||||
the test suite running against `std::filesystem`, defaulting to `GHC_FILESYSTEM_BUILD_TESTING`.
|
|
||||||
This is only done if the compiler is detected as being able to do it.
|
|
||||||
* `GHC_FILESYSTEM_TEST_COMPILE_FEATURES` can be set to a list of features to override
|
|
||||||
`CMAKE_CXX_COMPILE_FEATURES` when the detection of C++17 or C++20 for additional tests
|
|
||||||
is not working (e.g. `cxx_std_20` to enforce building a `filesystem_test_cpp20` with C++20).
|
|
||||||
|
|
||||||
### Bazel
|
|
||||||
|
|
||||||
Please use [hedronvision/bazel-cc-filesystem-backport](https://github.com/hedronvision/bazel-cc-filesystem-backport), which will automatically set everything up for you.
|
|
||||||
|
|
||||||
### Versioning
|
### Versioning
|
||||||
|
|
||||||
@ -407,7 +284,7 @@ There is a version macro `GHC_FILESYSTEM_VERSION` defined in case future changes
|
|||||||
might make it needed to react on the version, but I don't plan to break anything.
|
might make it needed to react on the version, but I don't plan to break anything.
|
||||||
It's the version as decimal number `(major * 10000 + minor * 100 + patch)`.
|
It's the version as decimal number `(major * 10000 + minor * 100 + patch)`.
|
||||||
|
|
||||||
:information_source: **Note:** Only even patch versions will be used for releases
|
**Note:** Starting from v1.0.2 only even patch versions will be used for releases
|
||||||
and odd patch version will only be used for in between commits while working on
|
and odd patch version will only be used for in between commits while working on
|
||||||
the next version.
|
the next version.
|
||||||
|
|
||||||
@ -425,8 +302,8 @@ are only supported on C++17. When Compiling with C++20, `ghc::filesysytem`
|
|||||||
defaults to the C++20 API, with the `char8_t` and `std::u8string` interfaces
|
defaults to the C++20 API, with the `char8_t` and `std::u8string` interfaces
|
||||||
and the deprecated `fs::u8path` factory method.
|
and the deprecated `fs::u8path` factory method.
|
||||||
|
|
||||||
:information_source: **Note:** If the C++17 API should be enforced even in C++20 mode,
|
**Note:** If the C++17 API should be enforced even in C++20 mode, use the define
|
||||||
use the define `GHC_FILESYSTEM_ENFORCE_CPP17_API`.
|
`GHC_FILESYSTEM_ENFORCE_CPP17_API`.
|
||||||
Even then it is possible to create `fws::path` from `std::u8string` but
|
Even then it is possible to create `fws::path` from `std::u8string` but
|
||||||
`fs::path::u8string()` and `fs::path::generic_u8string()` return normal
|
`fs::path::u8string()` and `fs::path::generic_u8string()` return normal
|
||||||
UTF-8 encoded `std::string` instances, so code written for C++17 could
|
UTF-8 encoded `std::string` instances, so code written for C++17 could
|
||||||
@ -438,13 +315,13 @@ The only additions to the standard are documented here:
|
|||||||
### `ghc::filesystem::ifstream`, `ghc::filesystem::ofstream`, `ghc::filesystem::fstream`
|
### `ghc::filesystem::ifstream`, `ghc::filesystem::ofstream`, `ghc::filesystem::fstream`
|
||||||
|
|
||||||
These are simple wrappers around `std::ifstream`, `std::ofstream` and `std::fstream`.
|
These are simple wrappers around `std::ifstream`, `std::ofstream` and `std::fstream`.
|
||||||
They simply add an `open()` method and a constructor with an `ghc::filesystem::path`
|
They simply add an `open()` method and a constuctor with an `ghc::filesystem::path`
|
||||||
argument as the `fstream` variants in C++17 have them.
|
argument as the `fstream` variants in C++17 have them.
|
||||||
|
|
||||||
### `ghc::filesystem::u8arguments`
|
### `ghc::filesystem::u8arguments`
|
||||||
|
|
||||||
This is a helper class that currently checks for UTF-8 encoding on non-Windows platforms but on Windows it
|
This is a helper class that currently checks for UTF-8 encoding on non-Windows platforms but on Windows it
|
||||||
fetches the command line arguments as Unicode strings from the OS with
|
fetches the command line arguments als Unicode strings from the OS with
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
::CommandLineToArgvW(::GetCommandLineW(), &argc)
|
::CommandLineToArgvW(::GetCommandLineW(), &argc)
|
||||||
@ -466,7 +343,7 @@ int main(int argc, char* argv[])
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now use argc/argv as usual, they have utf-8 encoding on windows
|
// now use argc/argv as usual, they have utf-8 enconding on windows
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -484,8 +361,8 @@ change anything. I still need to investigate this.
|
|||||||
## Differences
|
## Differences
|
||||||
|
|
||||||
As this implementation is based on existing code from my private helper
|
As this implementation is based on existing code from my private helper
|
||||||
classes, it derived some constraints of it. Starting from v1.5.0 most of the
|
classes, it derived some constraints of it, leading to some differences
|
||||||
differences between this and the standard C++17/C++20 API where removed.
|
between this and the standard C++17/C++20 API.
|
||||||
|
|
||||||
|
|
||||||
### LWG Defects
|
### LWG Defects
|
||||||
@ -504,7 +381,7 @@ where a regular file of the same name prohibits the creation of a directory and
|
|||||||
the user of those functions to double-check via `fs::is_directory` if it really worked.
|
the user of those functions to double-check via `fs::is_directory` if it really worked.
|
||||||
The more intuitive approach to directory creation of treating a file with that name as an
|
The more intuitive approach to directory creation of treating a file with that name as an
|
||||||
error is also advocated by the newer paper
|
error is also advocated by the newer paper
|
||||||
[WG21 P1164R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1164r0.pdf), the revision
|
[WG21 P1164R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1164r0.pdf), the revison
|
||||||
P1161R1 was agreed upon on Kona 2019 meeting [see merge](https://github.com/cplusplus/draft/issues/2703)
|
P1161R1 was agreed upon on Kona 2019 meeting [see merge](https://github.com/cplusplus/draft/issues/2703)
|
||||||
and GCC by now switched to following its proposal
|
and GCC by now switched to following its proposal
|
||||||
([GCC #86910](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86910)).
|
([GCC #86910](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86910)).
|
||||||
@ -521,24 +398,8 @@ These are not implemented under C++11 and C++14, as there is no
|
|||||||
`std::basic_string_view` available and I did want to keep this
|
`std::basic_string_view` available and I did want to keep this
|
||||||
implementation self-contained and not write a full C++17-upgrade for
|
implementation self-contained and not write a full C++17-upgrade for
|
||||||
C++11/14. Starting with v1.1.0 these are supported when compiling
|
C++11/14. Starting with v1.1.0 these are supported when compiling
|
||||||
`ghc::filesystem` under C++17 of C++20.
|
ghc::filesystem under C++17.
|
||||||
|
|
||||||
Starting with v1.5.2 `ghc::filesystem` will try to allow the use of
|
|
||||||
`std::experimental::basic_string_view` where it detects is availability.
|
|
||||||
Additionally if you have a `basic_string_view` compatible c++11
|
|
||||||
implementation it can be used instead of `std::basic_string_view`
|
|
||||||
by defining `GHC_HAS_CUSTOM_STRING_VIEW` and importing the
|
|
||||||
implementation into the `ghc::filesystem` namespace with:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
namespace ghc {
|
|
||||||
namespace filesystem {
|
|
||||||
using my::basic_string_view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
before including the filesystem header.
|
|
||||||
|
|
||||||
### Differences in API
|
### Differences in API
|
||||||
|
|
||||||
@ -546,27 +407,49 @@ To not depend on any external third party libraries and still stay portable and
|
|||||||
compact, this implementation is following the ["UTF-8 Everywhere" philosophy](https://utf8everywhere.org/) in that all
|
compact, this implementation is following the ["UTF-8 Everywhere" philosophy](https://utf8everywhere.org/) in that all
|
||||||
`std::string` instances will be interpreted the same as `std::u8string` encoding
|
`std::string` instances will be interpreted the same as `std::u8string` encoding
|
||||||
wise and as being in UTF-8. The `std::u16string` will be seen as UTF-16 and `std::u32string` will be
|
wise and as being in UTF-8. The `std::u16string` will be seen as UTF-16 and `std::u32string` will be
|
||||||
seen as Unicode codepoints. Depending on the size of `std::wstring` characters, it will handle
|
seen as unicode codepoints. Depending on the size of `std::wstring` characters, it will handle
|
||||||
`std::wstring` as being UTF-16 (e.g. Windows) or `char32_t` Unicode codepoints
|
`std::wstring` as being UTF-16 (e.g. Windows) or `char32_t` unicode codepoints
|
||||||
(currently all other platforms).
|
(currently all other platforms).
|
||||||
|
|
||||||
#### Differences of Specific Interfaces
|
#### Differences of Specific Interfaces
|
||||||
|
|
||||||
Starting with v1.5.0 `ghc::filesystem` is following the C++17 standard in
|
```cpp
|
||||||
using `wchar_t` and `std::wstring` on Windows as the types internally used
|
filesystem::path::string_type
|
||||||
for path representation. It is still possible to get the old behavior by defining
|
filesystem::path::value_type
|
||||||
`GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE` and get `filesystem::path::string_type` as
|
```
|
||||||
`std::string` and `filesystem::path::value_type` as `wchar_t`.
|
|
||||||
|
|
||||||
If you need to call some Windows API, with v1.5.0 and above, simply
|
In Windows, an implementation should use `std::wstring` and `wchar_t` as types used
|
||||||
use the W-variant of the Windows-API call (e.g. `GetFileAttributesW(p.c_str())`).
|
for the native representation, but as I'm a big fan of the
|
||||||
|
["UTF-8 Everywhere" philosophy](https://utf8everywhere.org/), I decided
|
||||||
:information_source: **Note:** _When using the old behavior by defining
|
agains it for now. If you need to call some Windows API, use the W-variant
|
||||||
`GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE`, use the `path::wstring()` member
|
with the `path::wstring()` member
|
||||||
(e.g. `GetFileAttributesW(p.wstring().c_str())`). This gives you the
|
(e.g. `GetFileAttributesW(p.wstring().c_str())`). This gives you the
|
||||||
Unicode variant independent of the `UNICODE` macro and makes sharing code
|
Unicode variant independant of the `UNICODE` macro and makes sharing code
|
||||||
between Windows, Linux and macOS easier and works with `std::filesystem` and
|
between Windows, Linux and macOS easier.
|
||||||
`ghc::filesystem`._
|
|
||||||
|
Starting with v1.2.0 `ghc::filesystem` has the option to select the more
|
||||||
|
standard conforming APi with `wchar_t` and `std::wstring` on Windows by
|
||||||
|
defining `GHC_WIN_WSTRING_STRING_TYPE`. This define has no effect on other
|
||||||
|
platforms and will be set by the helping headers `ghc/fs_std.hpp` and
|
||||||
|
the pair `ghc/fs_std_fwd.hpp`/`ghc/fs_std_impl.hpp` to enhance compatibility.
|
||||||
|
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
const path::string_type& path::native() const /*noexcept*/;
|
||||||
|
const path::value_type *path::c_str() const /*noexcept*/;
|
||||||
|
```
|
||||||
|
|
||||||
|
These two can not be `noexcept` with the current implementation. This due
|
||||||
|
to the fact, that internally path is working on the generic path version
|
||||||
|
only, and the getters need to do a conversion to native path format.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
const path::string_type& path::generic_string() const;
|
||||||
|
```
|
||||||
|
|
||||||
|
This returns a const reference, instead of a value, because it can. This
|
||||||
|
implementation uses the generic representation for internal workings, so
|
||||||
|
it's "free" to return that.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
std::string path::u8string() const;
|
std::string path::u8string() const;
|
||||||
@ -593,22 +476,20 @@ Any additional observations are welcome!
|
|||||||
|
|
||||||
#### fs.path ([ref](https://en.cppreference.com/w/cpp/filesystem/path))
|
#### fs.path ([ref](https://en.cppreference.com/w/cpp/filesystem/path))
|
||||||
|
|
||||||
Since v1.5.0 the complete inner mechanics of this implementations `fs::path`
|
As the complete inner mechanics of this implementation `fs::path` are working
|
||||||
where changed to the _native_ format as the internal representation.
|
on the generic format, it is the internal representation. So creating any mixed
|
||||||
Creating any mixed slash `fs::path` object under Windows (e.g. with `"C:\foo/bar"`)
|
slash `fs::path` object under Windows (e.g. with `"C:\foo/bar"`) will lead to a
|
||||||
will lead clean path with `"C:\foo\bar"` via `native()` and `"C:/foo/bar"` via
|
unified path with `"C:\foo\bar"` via `native()` and `"C:/foo/bar"` via
|
||||||
`generic_string()` API. On all platforms redundant additional separators are
|
`generic_string()` API.
|
||||||
removed, even if this is not enforced by the standard and other implementations
|
|
||||||
mostly not do this.
|
|
||||||
|
|
||||||
Additionally this implementation follows the standards suggestion to handle
|
Additionally this implementation follows the standards suggestion to handle
|
||||||
posix paths of the form `"//host/path"` and USC path on windows also as having
|
posix paths of the form `"//host/path"` and USC path on windows also as having
|
||||||
a root-name (e.g. `"//host"`). The GCC implementation didn't choose to do that
|
a root-name (e.g. `"//host"`). The GCC implementation didn't choose to do that
|
||||||
while testing on Ubuntu 18.04 and macOS with GCC 8.1.0 or Clang 7.0.0. This difference
|
while testing on Ubuntu 18.04 and macOS with GCC 8.1.0 or Clang 7.0.0. This difference
|
||||||
will show as warnings under `std::filesystem`. This leads to a change in the
|
will show as warnings under std::filesystem. This leads to a change in the
|
||||||
algorithm described in the standard for `operator/=(path& p)` where any path
|
algorithm described in the standard for `operator/=(path& p)` where any path
|
||||||
`p` with `p.is_absolute()` will degrade to an assignment, while this implementation
|
`p` with `p.is_absolute()` will degrade to an assignment, while this implementation
|
||||||
has the exception where `*this == *this.root_name()` and `p == preferred_separator`
|
has the exception where `*this == *this.root_name()` and `p == preferred_seperator`
|
||||||
a normal append will be done, to allow:
|
a normal append will be done, to allow:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@ -618,12 +499,37 @@ for (auto p : p1) p2 /= p;
|
|||||||
ASSERT(p1 == p2);
|
ASSERT(p1 == p2);
|
||||||
```
|
```
|
||||||
|
|
||||||
For all non-host-leading paths the behavior will match the one described by
|
For all non-host-leading paths the behaviour will match the one described by
|
||||||
the standard.
|
the standard.
|
||||||
|
|
||||||
|
#### fs.op.copy ([ref](https://en.cppreference.com/w/cpp/filesystem/copy))
|
||||||
|
|
||||||
|
Then there is `fs::copy`. The tests in the suite fail partially with C++17 `std::filesystem`
|
||||||
|
on GCC/Clang. They complain about a copy call with `fs::copy_options::recursive` combined
|
||||||
|
with `fs::copy_options::create_symlinks` or `fs::copy_options::create_hard_links` if the
|
||||||
|
source is a directory. There is nothing in the standard that forbids this combination
|
||||||
|
and it is the only way to deep-copy a tree while only create links for the files.
|
||||||
|
There is [LWG #2682](https://wg21.cmeerw.net/lwg/issue2682) that supports this
|
||||||
|
interpretation, but the issue ignores the usefulness of the combination with recursive
|
||||||
|
and part of the justification for the proposed solution is "we did it so for almost two years".
|
||||||
|
But this makes `fs::copy` with `fs::copy_options::create_symlinks` or `fs::copy_options::create_hard_links`
|
||||||
|
just a more complicated syntax for the `fs::create_symlink` or `fs::create_hardlink` operation
|
||||||
|
and I don't want to believe, that this was the intention of the original writing.
|
||||||
|
As there is another issue related to copy, with a different take on the description.
|
||||||
|
|
||||||
|
**Note:** With v1.1.2 I decided to integrate a behavior switch for this and make the LWG #2682
|
||||||
|
the default.
|
||||||
|
|
||||||
## Open Issues
|
## Open Issues
|
||||||
|
|
||||||
|
### General Known Issues
|
||||||
|
|
||||||
|
There are still some methods that break the `noexcept` clause, some
|
||||||
|
are related to LWG defects, some are due to my implementation. I
|
||||||
|
work on fixing the later ones, and might in cases where there is no
|
||||||
|
way of implementing the feature without risk of an exception, break
|
||||||
|
conformance and remove the `noexcept`.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
#### Symbolic Links on Windows
|
#### Symbolic Links on Windows
|
||||||
@ -631,7 +537,7 @@ the standard.
|
|||||||
As symbolic links on Windows, while being supported more or less since
|
As symbolic links on Windows, while being supported more or less since
|
||||||
Windows Vista (with some strict security constraints) and fully since some earlier
|
Windows Vista (with some strict security constraints) and fully since some earlier
|
||||||
build of Windows 10, when "Developer Mode" is activated, are at time of writing
|
build of Windows 10, when "Developer Mode" is activated, are at time of writing
|
||||||
(2018) rarely used, still they are supported wiit th this implementation.
|
(2018) rarely used, still they are supported with this implementation.
|
||||||
|
|
||||||
#### Permissions
|
#### Permissions
|
||||||
|
|
||||||
@ -646,206 +552,6 @@ to the expected behavior.
|
|||||||
|
|
||||||
## Release Notes
|
## Release Notes
|
||||||
|
|
||||||
### v1.5.15 (wip)
|
|
||||||
|
|
||||||
* Fix for [#166](https://github.com/gulrak/filesystem/issues/166),
|
|
||||||
`extension()` did return non empty result for the directory name
|
|
||||||
`".."`
|
|
||||||
|
|
||||||
### [v1.5.14](https://github.com/gulrak/filesystem/releases/tag/v1.5.14)
|
|
||||||
|
|
||||||
* Pull request [#163](https://github.com/gulrak/filesystem/pull/163), build
|
|
||||||
support for Haiku (also fixes [#159](https://github.com/gulrak/filesystem/issues/159))
|
|
||||||
* Pull request [#162](https://github.com/gulrak/filesystem/pull/162), fix for
|
|
||||||
directory iterator treating all files subsequent to a symlink as symlink
|
|
||||||
on Windows
|
|
||||||
* Pull request [#161](https://github.com/gulrak/filesystem/pull/161), the
|
|
||||||
CMake alias `ghcFilesystem::ghc_filesystem` is now set unconditionally
|
|
||||||
* Fix for [#160](https://github.com/gulrak/filesystem/issues/160), the cmake
|
|
||||||
config now only sets install targets by default if the project is no
|
|
||||||
subproject, as documented
|
|
||||||
* Fix for [#157](https://github.com/gulrak/filesystem/issues/157), suppress
|
|
||||||
C4191 warning on MSVC for GetProcAddress casts
|
|
||||||
* Fix for [#156](https://github.com/gulrak/filesystem/issues/156), on POSIX
|
|
||||||
`stem()`, `filename()` and `extension()` of `fs::path` would return wrong
|
|
||||||
result if a colon was in the filename
|
|
||||||
* Pull request [#154](https://github.com/gulrak/filesystem/pull/145), build
|
|
||||||
support for GNU/Hurd
|
|
||||||
* Pull request [#153](https://github.com/gulrak/filesystem/pull/153), fixed
|
|
||||||
`fs::last_write_time(path, time, ec)` setter on iOS, tvOS and watchOS
|
|
||||||
* Fix for [#151](https://github.com/gulrak/filesystem/issues/156),
|
|
||||||
`fs::directory_entry::refresh()` now, consistently with `status()` will not
|
|
||||||
throw on symlinks to non-existing targets, but make the entry have
|
|
||||||
`file_type::not_found` as the type
|
|
||||||
* Pull request [#149](https://github.com/gulrak/filesystem/pull/149), add
|
|
||||||
version to CMake project and export it
|
|
||||||
* Fix for [#146](https://github.com/gulrak/filesystem/issues/146), handle `EINTR`
|
|
||||||
on POSIX directory iteration and file copy to avoid errors on network
|
|
||||||
filesystems
|
|
||||||
* Pull request [#145](https://github.com/gulrak/filesystem/pull/145), fix for
|
|
||||||
Y2038 bug in timeToFILETIME on Windows
|
|
||||||
* Pull request [#144](https://github.com/gulrak/filesystem/pull/144), `fs::copy_file()`
|
|
||||||
now also copies the permissions
|
|
||||||
* Pull request [#143](https://github.com/gulrak/filesystem/pull/143), fix
|
|
||||||
for `fs::copy_file()` ignoring the `skip_existing` option.
|
|
||||||
|
|
||||||
### [v1.5.12](https://github.com/gulrak/filesystem/releases/tag/v1.5.12)
|
|
||||||
|
|
||||||
* Fix for [#142](https://github.com/gulrak/filesystem/issues/142), removed need
|
|
||||||
for `GHC_NO_DIRENT_D_TYPE` on systems that don't support `dirent::d_type` and
|
|
||||||
fixed build configuration and tests to support Solaris as new platform.
|
|
||||||
* Pull request [#138](https://github.com/gulrak/filesystem/pull/138), if the
|
|
||||||
platform uses the POSIX backend and has no `PATH_MAX`, one is defined.
|
|
||||||
* Pull request [#137](https://github.com/gulrak/filesystem/pull/137), update
|
|
||||||
of Catch2 to version v2.13.7
|
|
||||||
* Added macOS 11 to the automatically tested platforms.
|
|
||||||
|
|
||||||
### [v1.5.10](https://github.com/gulrak/filesystem/releases/tag/v1.5.10)
|
|
||||||
|
|
||||||
* Pull request [#136](https://github.com/gulrak/filesystem/pull/136), the Windows
|
|
||||||
implementation used some unnecessary expensive shared pointer for resource
|
|
||||||
management and these where replaced by a dedicated code.
|
|
||||||
* Fix for [#132](https://github.com/gulrak/filesystem/issues/132), pull request
|
|
||||||
[#135](https://github.com/gulrak/filesystem/pull/135), `fs::remove_all` now
|
|
||||||
just deletes symbolic links instead of following them.
|
|
||||||
* Pull request [#133](https://github.com/gulrak/filesystem/pull/133), fix for
|
|
||||||
`fs::space` where a numerical overflow could happen in a multiplication.
|
|
||||||
* Replaced _travis-ci.org_ with GitHub Workflow for the configurations:
|
|
||||||
Ubuntu 20.04: GCC 9.3, Ubuntu 18.04: GCC 7.5, GCC 8.4, macOS 10.15: Xcode 12.4,
|
|
||||||
Windows 10: Visual Studio 2019
|
|
||||||
|
|
||||||
### [v1.5.8](https://github.com/gulrak/filesystem/releases/tag/v1.5.8)
|
|
||||||
|
|
||||||
* Fix for [#125](https://github.com/gulrak/filesystem/issues/124), where
|
|
||||||
`fs::create_directories` on Windows no longer breaks on long filenames.
|
|
||||||
|
|
||||||
### [v1.5.6](https://github.com/gulrak/filesystem/releases/tag/v1.5.6)
|
|
||||||
|
|
||||||
* Fix for [#124](https://github.com/gulrak/filesystem/issues/124),
|
|
||||||
`ghc::filesystem` treated mounted folder/volumes erroneously as symlinks,
|
|
||||||
leading `fs::canonical` to fail on paths containing those.
|
|
||||||
* Fix for [#122](https://github.com/gulrak/filesystem/issues/122), incrementing
|
|
||||||
the `recursive_directory_iterator` will not try to enter dead symlinks.
|
|
||||||
* Fix for [#121](https://github.com/gulrak/filesystem/issues/121), on Windows
|
|
||||||
backend the `fs::remove` failed when the path pointed to a read-only entry,
|
|
||||||
see also ([microsoft/STL#1511](https://github.com/microsoft/STL/issues/1511))
|
|
||||||
for the corresponding issue in `std::fs` on windows.
|
|
||||||
* Fix for [#119](https://github.com/gulrak/filesystem/issues/119), added missing
|
|
||||||
support for char16_t and char32_t and on C++20 char8_t literals.
|
|
||||||
* Pull request [#118](https://github.com/gulrak/filesystem/pull/118), when
|
|
||||||
running tests as root, disable tests that would not work.
|
|
||||||
* Pull request [#117](https://github.com/gulrak/filesystem/pull/117), added
|
|
||||||
checks to tests to detect the clang/libstdc++ combination.
|
|
||||||
* Fix for [#116](https://github.com/gulrak/filesystem/issues/116), internal
|
|
||||||
macro `GHC_NO_DIRENT_D_TYPE` allows os detection to support systems without
|
|
||||||
the `dirent.d_type` member, experimental first QNX compile support as
|
|
||||||
initial use case, fixed issue with filesystems returning DT_UNKNOWN
|
|
||||||
(e.g. reiserfs).
|
|
||||||
* Pull request [#115](https://github.com/gulrak/filesystem/pull/115), added
|
|
||||||
`string_view` support when clang with libstdc++ is detected.
|
|
||||||
* Fix for [#114](https://github.com/gulrak/filesystem/issues/114), for macOS
|
|
||||||
the pre-Catalina deployment target detection worked only if `<Availability.h>`
|
|
||||||
was included before `<ghc/fs_std.hpp>` or `<ghc/fs_std_fwd.hpp>`/`<ghc/fs_std_impl.hpp>`.
|
|
||||||
* Fix for [#113](https://github.com/gulrak/filesystem/issues/113), the use of
|
|
||||||
standard chapter numbers was misleading since C++17 and C++20 `std::filesystem`
|
|
||||||
features are supported, and was replaced by the tag-like chapter names that
|
|
||||||
stay (mostly) consistent over the versions.
|
|
||||||
|
|
||||||
### [v1.5.4](https://github.com/gulrak/filesystem/releases/tag/v1.5.4)
|
|
||||||
|
|
||||||
* Pull request [#112](https://github.com/gulrak/filesystem/pull/112), lots
|
|
||||||
of cleanup work on the readme, thanks!
|
|
||||||
* Enhancement for [#111](https://github.com/gulrak/filesystem/issues/111),
|
|
||||||
further optimization of directory iteration, performance for
|
|
||||||
`recursive_directory_iterator` over large trees now somewhere between
|
|
||||||
libc++ and libstdc++.
|
|
||||||
* Enhancement for [#110](https://github.com/gulrak/filesystem/issues/110),
|
|
||||||
`ghc::filesystem` now has preliminary support for Cygwin. Changes where
|
|
||||||
made to allow the tests to compile and run successfully (tested with GCC
|
|
||||||
10.2.0), feedback and additional PRs welcome as it is currently not
|
|
||||||
part of the CI configuration.
|
|
||||||
* Pull request [#109](https://github.com/gulrak/filesystem/pull/109), various
|
|
||||||
spelling errors in error messages and comments fixed.
|
|
||||||
* Pull request [#108](https://github.com/gulrak/filesystem/pull/108), old
|
|
||||||
style casts removed.
|
|
||||||
* Fix for [#107](https://github.com/gulrak/filesystem/issues/107), the error
|
|
||||||
handling for status calls was suppressing errors on symlink targets.
|
|
||||||
* Pull request [#106](https://github.com/gulrak/filesystem/pull/106), fixed
|
|
||||||
detection of AppleClang for compile options.
|
|
||||||
* Pull request [#105](https://github.com/gulrak/filesystem/pull/105), added
|
|
||||||
option `GHC_FILESYSTEM_BUILD_STD_TESTING` to override additional build of
|
|
||||||
`std::filesystem` versions of the tests for comparison and the possibility
|
|
||||||
to use `GHC_FILESYSTEM_TEST_COMPILE_FEATURES` to prefill the used compile
|
|
||||||
features defaulting to `CMAKE_CXX_COMPILE_FEATURES` when not given.
|
|
||||||
|
|
||||||
### [v1.5.2](https://github.com/gulrak/filesystem/releases/tag/v1.5.2)
|
|
||||||
|
|
||||||
* Enhancement [#104](https://github.com/gulrak/filesystem/issues/104),
|
|
||||||
on POSIX backend: optimized reuse of status information and reduced
|
|
||||||
`directory_entry` creation leads to about 20%-25% in tests with
|
|
||||||
`recursive_directory_iterator` over a larger directory tree.
|
|
||||||
* Pull request [#103](https://github.com/gulrak/filesystem/pull/103), `wchar_t`
|
|
||||||
was not in the list of supported char types on non-Windows backends.
|
|
||||||
* Pull request [#102](https://github.com/gulrak/filesystem/pull/102), improved
|
|
||||||
`string_view` support makes use of `<string_view>` or `<experimental/string_view>`
|
|
||||||
when available, and allows use of custom `basic_string_view` implementation
|
|
||||||
when defining `GHC_HAS_CUSTOM_STRING_VIEW` and importing the string view
|
|
||||||
into the `ghc::filesystem` namespace before including filesystem header.
|
|
||||||
* Pull request [#101](https://github.com/gulrak/filesystem/pull/101), fix for
|
|
||||||
[#100](https://github.com/gulrak/filesystem/issues/100), append and concat
|
|
||||||
type of operations on path called redundant conversions.
|
|
||||||
* Pull request [#98](https://github.com/gulrak/filesystem/pull/98), on older
|
|
||||||
linux variants (GCC 7/8), the comparison `std::filesystem` tests now link
|
|
||||||
with `-lrt` to avoid issues.
|
|
||||||
* Fix for [#97](https://github.com/gulrak/filesystem/issues/97), on BTRFS the
|
|
||||||
test case for `fs::hard_link_count` failed due to the filesystems behavior,
|
|
||||||
the test case was adapted to take that into account.
|
|
||||||
* Pull request [#96](https://github.com/gulrak/filesystem/pull/96), the export
|
|
||||||
attribute defines `GHC_FS_API` and `GHC_FS_API_CLASS` are now honored when when
|
|
||||||
set from outside to allow override of behavior.
|
|
||||||
* Fix for [#95](https://github.com/gulrak/filesystem/issues/95), the syntax for
|
|
||||||
disabling the deprecated warning in tests in MSVC was wrong.
|
|
||||||
* Pull request [#93](https://github.com/gulrak/filesystem/pull/93), now the
|
|
||||||
CMake configuration file is configured and part of the `make install` files.
|
|
||||||
|
|
||||||
### [v1.5.0](https://github.com/gulrak/filesystem/releases/tag/v1.5.0)
|
|
||||||
|
|
||||||
* Fix for [#91](https://github.com/gulrak/filesystem/issues/91), the way
|
|
||||||
the CMake build options `GHC_FILESYSTEM_BUILD_TESTING`, `GHC_FILESYSTEM_BUILD_EXAMPLES`
|
|
||||||
and `GHC_FILESYSTEM_WITH_INSTALL` where implemented, prohibited setting them
|
|
||||||
from a parent project when using this via `add_subdirectory`, this fix
|
|
||||||
allows to set them again.
|
|
||||||
* Major refactoring for [#90](https://github.com/gulrak/filesystem/issues/90),
|
|
||||||
the way, the Windows version of `fs::path` was originally created from the
|
|
||||||
POSIX based implementation was, by adaption of the incoming and outgoing
|
|
||||||
strings. This resulted in a mutable cache inside `fs::path`on Windows, that
|
|
||||||
was inherently not thread-safe, even for `const` methods.
|
|
||||||
To not add additional patches to a suboptimal solution, this time I reworked
|
|
||||||
the `path` code to now store _native_ path-representation. This changed a
|
|
||||||
lot of code, but when combined with `wchar_t` as `value_type` helped to avoid
|
|
||||||
lots of conversion for calls to Win-API.<br>
|
|
||||||
As interfaces where changed, it had to be released in a new minor version.
|
|
||||||
The set of refactorings resulted in the following changes:
|
|
||||||
* `fs::path::native()` and `fs::path::c_str()` can now be `noexcept` as the
|
|
||||||
standard mandates
|
|
||||||
* On Windows `wchar_t` is now the default for `fs::path::value_type` and
|
|
||||||
`std::wstring` is the default for `fs::path::string_type`.
|
|
||||||
* This allows the implementation to call Win-API without allocating
|
|
||||||
conversions
|
|
||||||
* Thread-safety on `const` methods of `fs::path` is no longer an issue
|
|
||||||
* Some code could be simplified during this refactoring
|
|
||||||
* Automatic prefixing of long path on Windows can now be disabled with
|
|
||||||
defining `GHC_WIN_DISABLE_AUTO_PREFIXES`, for all other types of prefixes
|
|
||||||
or namespaces the behavior follows that of MSVC `std::filesystem::path`
|
|
||||||
* In case the old `char`/`std::string` based approach for Windows is still
|
|
||||||
needed, it can be activated with `GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE`
|
|
||||||
* Enhancement for [#89](https://github.com/gulrak/filesystem/issues/89), `fs::file_status`
|
|
||||||
now supports `operator==` introduced in `std::filesystem` with C++20.
|
|
||||||
* Refactoring for [#88](https://github.com/gulrak/filesystem/issues/88), `fs::path::parent_path()`
|
|
||||||
had a performance issue, as it was still using a loop based approach to recreate
|
|
||||||
the parent from elements. This created lots of temporaries and was too slow
|
|
||||||
especially on long paths.
|
|
||||||
|
|
||||||
### [v1.4.0](https://github.com/gulrak/filesystem/releases/tag/v1.4.0)
|
### [v1.4.0](https://github.com/gulrak/filesystem/releases/tag/v1.4.0)
|
||||||
|
|
||||||
* Enhancements for [#71](https://github.com/gulrak/filesystem/issues/71), when compiled with C++20:
|
* Enhancements for [#71](https://github.com/gulrak/filesystem/issues/71), when compiled with C++20:
|
||||||
@ -895,8 +601,8 @@ to the expected behavior.
|
|||||||
`filesystem_test.cpp` was completed to fulfill the requirements to build on CentOS 7 with
|
`filesystem_test.cpp` was completed to fulfill the requirements to build on CentOS 7 with
|
||||||
`devtoolset-9`. CentOS 7 and CentOS 8 are now part of the CI builds.
|
`devtoolset-9`. CentOS 7 and CentOS 8 are now part of the CI builds.
|
||||||
* Bugfix for [#70](https://github.com/gulrak/filesystem/issues/70), root names are now case
|
* Bugfix for [#70](https://github.com/gulrak/filesystem/issues/70), root names are now case
|
||||||
insensitive on Windows. This fix also adds the new behavior switch `LWG_2936_BEHAVIOUR`
|
insensitive on Windows. This fix also adds the new behaviour switch `LWG_2936_BEHAVIOUR`
|
||||||
that allows to enable post C++17 `fs::path::compare` behavior, where the comparison is as
|
that allows to enable post C++17 `fs::path::compare` behaviour, where the comparison is as
|
||||||
if it was an element wise path comparison as described in
|
if it was an element wise path comparison as described in
|
||||||
[LWG 2936](https://cplusplus.github.io/LWG/issue2936) and C++20 `[fs.path.compare]`.
|
[LWG 2936](https://cplusplus.github.io/LWG/issue2936) and C++20 `[fs.path.compare]`.
|
||||||
It is default off in v1.3.6 and will be default starting from v1.4.0 as it changes ordering.
|
It is default off in v1.3.6 and will be default starting from v1.4.0 as it changes ordering.
|
||||||
@ -937,7 +643,7 @@ to the expected behavior.
|
|||||||
* Pull request [#52](https://github.com/gulrak/filesystem/pull/52), an ARM Linux
|
* Pull request [#52](https://github.com/gulrak/filesystem/pull/52), an ARM Linux
|
||||||
target is now part of the CI infrastructure with the service of Drone CI.
|
target is now part of the CI infrastructure with the service of Drone CI.
|
||||||
* Pull request [#51](https://github.com/gulrak/filesystem/pull/51), FreeBSD is now
|
* Pull request [#51](https://github.com/gulrak/filesystem/pull/51), FreeBSD is now
|
||||||
part of the CI infrastructure with the service of Cirrus CI.
|
part of the CI infrastucture with the service of Cirrus CI.
|
||||||
* Pull request [#50](https://github.com/gulrak/filesystem/pull/50), adaptive cast to
|
* Pull request [#50](https://github.com/gulrak/filesystem/pull/50), adaptive cast to
|
||||||
`timespec` fields to avoid warnings.
|
`timespec` fields to avoid warnings.
|
||||||
|
|
||||||
@ -955,10 +661,10 @@ to the expected behavior.
|
|||||||
* The Visual Studio 2019 compiler, GCC 9.2 and Clang 9.0 where added to the
|
* The Visual Studio 2019 compiler, GCC 9.2 and Clang 9.0 where added to the
|
||||||
CI configuration.
|
CI configuration.
|
||||||
* Bugfix for [#41](https://github.com/gulrak/filesystem/issues/41), `fs::rename`
|
* Bugfix for [#41](https://github.com/gulrak/filesystem/issues/41), `fs::rename`
|
||||||
on Windows didn't replace an existing regular file as required by the standard,
|
on Windows didn't replace an axisting regular file as required by the standard,
|
||||||
but gave an error. New tests and a fix as provided in the issue was implemented.
|
but gave an error. New tests and a fix as provided in the issue was implemented.
|
||||||
* Bugfix for [#39](https://github.com/gulrak/filesystem/issues/39), for the
|
* Bugfix for [#39](https://github.com/gulrak/filesystem/issues/39), for the
|
||||||
forwarding use via `fs_fwd.hpp` or `fs_std_fwd.hpp` there was a use of
|
forwarding use via `fs_fwd.hpp` or `fs_std_fwd.hpp` der was a use of
|
||||||
`DWORD` in the forwarding part leading to an error if `Windows.h` was not
|
`DWORD` in the forwarding part leading to an error if `Windows.h` was not
|
||||||
included before the header. The tests were changed to give an error in that
|
included before the header. The tests were changed to give an error in that
|
||||||
case too and the useage of `DWORD` was removed.
|
case too and the useage of `DWORD` was removed.
|
||||||
@ -990,20 +696,20 @@ to the expected behavior.
|
|||||||
* Bugfix for [#33](https://github.com/gulrak/filesystem/issues/33), fixes
|
* Bugfix for [#33](https://github.com/gulrak/filesystem/issues/33), fixes
|
||||||
an issue with `fs::path::lexically_normal()` that leaves a trailing separator
|
an issue with `fs::path::lexically_normal()` that leaves a trailing separator
|
||||||
in case of a resulting path ending with `..` as last element.
|
in case of a resulting path ending with `..` as last element.
|
||||||
* Bugfix for [#36](https://github.com/gulrak/filesystem/issues/36), warnings
|
* Bugfix for [#36](https://github.com/gulrak/filesystem/issues/36), warings
|
||||||
on Xcode 11.2 due to unhelpful references in path element iteration.
|
on Xcode 11.2 due to unhelpfull references in path element iteration.
|
||||||
|
|
||||||
### [v1.2.6](https://github.com/gulrak/filesystem/releases/tag/v1.2.6)
|
### [v1.2.6](https://github.com/gulrak/filesystem/releases/tag/v1.2.6)
|
||||||
|
|
||||||
* Pull request [#23](https://github.com/gulrak/filesystem/pull/23), tests and
|
* Pull request [#23](https://github.com/gulrak/filesystem/pull/23), tests and
|
||||||
examples can now be disabled in CMake via setting `BUILD_TESTING` and
|
examples can now be disabled in CMake via seting `BUILD_TESTING` and
|
||||||
`BUILD_EXAMPLES` to `NO`, `OFF` or `FALSE`.
|
`BUILD_EXAMPLES` to `NO`, `OFF` or `FALSE`.
|
||||||
* Pull request [#25](https://github.com/gulrak/filesystem/pull/25),
|
* Pull request [#25](https://github.com/gulrak/filesystem/pull/25),
|
||||||
missing specialization for construction from `std::string_view` when
|
missing specialization for construction from `std::string_view` when
|
||||||
available was added.
|
available was added.
|
||||||
* Additional test case when `std::string_view` is available.
|
* Additional test case when `std::string_view` is available.
|
||||||
* Bugfix for [#27](https://github.com/gulrak/filesystem/issues/27), the
|
* Bugfix for [#27](https://github.com/gulrak/filesystem/issues/27), the
|
||||||
`fs::path::preferred_separator` declaration was not compiling on pre
|
`fs::path::preferred_seperator` declaration was not compiling on pre
|
||||||
C++17 compilers and no test accessed it, to show the problem. Fixed
|
C++17 compilers and no test accessed it, to show the problem. Fixed
|
||||||
it to an construction C++11 compiler should accept and added a test that
|
it to an construction C++11 compiler should accept and added a test that
|
||||||
is successful on all combinations tested.
|
is successful on all combinations tested.
|
||||||
@ -1042,7 +748,7 @@ to the expected behavior.
|
|||||||
compiling on Windows with defined `GHC_WIN_WSTRING_STRING_TYPE`, this is
|
compiling on Windows with defined `GHC_WIN_WSTRING_STRING_TYPE`, this is
|
||||||
default when using the `ghc/fs_std*.hpp` header, to enhance compatibility.
|
default when using the `ghc/fs_std*.hpp` header, to enhance compatibility.
|
||||||
* New feature ([#18](https://github.com/gulrak/filesystem/issues/18)), optional
|
* New feature ([#18](https://github.com/gulrak/filesystem/issues/18)), optional
|
||||||
filesystem exceptions/errors on Unicode errors with defined
|
filesystem exceptions/errors on unicode errors with defined
|
||||||
`GHC_RAISE_UNICODE_ERRORS` (instead of replacing invalid code points or
|
`GHC_RAISE_UNICODE_ERRORS` (instead of replacing invalid code points or
|
||||||
UTF-8 encoding errors with the replacement character `U+FFFD`).
|
UTF-8 encoding errors with the replacement character `U+FFFD`).
|
||||||
* Pull request ([#20](https://github.com/gulrak/filesystem/pull/20)), fix for
|
* Pull request ([#20](https://github.com/gulrak/filesystem/pull/20)), fix for
|
||||||
@ -1053,9 +759,9 @@ to the expected behavior.
|
|||||||
|
|
||||||
* Additional Bugfix for ([#12](https://github.com/gulrak/filesystem/issues/12)),
|
* Additional Bugfix for ([#12](https://github.com/gulrak/filesystem/issues/12)),
|
||||||
error in old unified `readdir/readdir_r` code of `fs::directory_iterator`;
|
error in old unified `readdir/readdir_r` code of `fs::directory_iterator`;
|
||||||
as `readdir_r` is now deprecated, I decided to drop it and the resulting
|
as `readdir_r` is now depricated, I decided to drop it and the resulting
|
||||||
code is much easier, shorter and due to more refactoring faster
|
code is much easier, shorter and due to more refactoring faster
|
||||||
* Fix for crashing unit tests against MSVC C++17 `std::filesystem`
|
* Fix for crashing unit tests against MSVC C++17 std::filesystem
|
||||||
* Travis-CI now additionally test with Xcode 10.2 on macOS
|
* Travis-CI now additionally test with Xcode 10.2 on macOS
|
||||||
* Some minor refactorings
|
* Some minor refactorings
|
||||||
|
|
||||||
@ -1065,10 +771,10 @@ to the expected behavior.
|
|||||||
`fs::path::lexically_normal()` had some issues with `".."`-sequences.
|
`fs::path::lexically_normal()` had some issues with `".."`-sequences.
|
||||||
* Bugfix for ([#12](https://github.com/gulrak/filesystem/issues/12)),
|
* Bugfix for ([#12](https://github.com/gulrak/filesystem/issues/12)),
|
||||||
`fs::recursive_directory_iterator` could run into endless loops,
|
`fs::recursive_directory_iterator` could run into endless loops,
|
||||||
the methods depth() and pop() had issues and the copy behavior and
|
the methods depth() and pop() had issues and the copy behaviour and
|
||||||
`input_iterator_tag` conformance was broken, added tests
|
`input_iterator_tag` conformance was broken, added tests
|
||||||
* Restructured some CMake code into a macro to ease the support for
|
* Restructured some CMake code into a macro to ease the support for
|
||||||
C++17 `std::filesystem` builds of tests and examples for interoperability
|
C++17 std::filesystem builds of tests and examples for interoperability
|
||||||
checks.
|
checks.
|
||||||
* Some fixes on Windows tests to ease interoperability test runs.
|
* Some fixes on Windows tests to ease interoperability test runs.
|
||||||
* Reduced noise on `fs::weakly_canonical()` tests against `std::fs`
|
* Reduced noise on `fs::weakly_canonical()` tests against `std::fs`
|
||||||
@ -1153,7 +859,7 @@ to the expected behavior.
|
|||||||
available.
|
available.
|
||||||
* Starting with this version, only even patch level versions will be tagged and
|
* Starting with this version, only even patch level versions will be tagged and
|
||||||
odd patch levels mark in-between non-stable wip states.
|
odd patch levels mark in-between non-stable wip states.
|
||||||
* Tests can now also be run against MS version of `std::filesystem` for comparison.
|
* Tests can now also be run against MS version of std::filesystem for comparison.
|
||||||
* Added missing `fstream` include.
|
* Added missing `fstream` include.
|
||||||
* Removed non-conforming C99 `timespec`/`timeval` usage.
|
* Removed non-conforming C99 `timespec`/`timeval` usage.
|
||||||
* Fixed some integer type mismatches that could lead to warnings.
|
* Fixed some integer type mismatches that could lead to warnings.
|
||||||
@ -1166,7 +872,7 @@ to the expected behavior.
|
|||||||
paths for non-existant argument paths. ([#1](https://github.com/gulrak/filesystem/issues/1))
|
paths for non-existant argument paths. ([#1](https://github.com/gulrak/filesystem/issues/1))
|
||||||
* Bugfix: `ghc::filesystem::remove_all` now also counts directories removed ([#2](https://github.com/gulrak/filesystem/issues/2))
|
* Bugfix: `ghc::filesystem::remove_all` now also counts directories removed ([#2](https://github.com/gulrak/filesystem/issues/2))
|
||||||
* Bugfix: `recursive_directory_iterator` tests didn't respect equality domain issues
|
* Bugfix: `recursive_directory_iterator` tests didn't respect equality domain issues
|
||||||
and dereferencapable constraints, leading to fails on `std::filesystem` tests.
|
and dereferencable constraints, leading to fails on `std::filesystem` tests.
|
||||||
* Bugfix: Some `noexcept` tagged methods and functions could indirectly throw exceptions
|
* Bugfix: Some `noexcept` tagged methods and functions could indirectly throw exceptions
|
||||||
due to UFT-8 decoding issues.
|
due to UFT-8 decoding issues.
|
||||||
* `std_filesystem_test` is now also generated if LLVM/clang 7.0.0 is found.
|
* `std_filesystem_test` is now also generated if LLVM/clang 7.0.0 is found.
|
||||||
@ -1175,5 +881,5 @@ to the expected behavior.
|
|||||||
### [v1.0.0](https://github.com/gulrak/filesystem/releases/tag/v1.0.0)
|
### [v1.0.0](https://github.com/gulrak/filesystem/releases/tag/v1.0.0)
|
||||||
|
|
||||||
This was the first public release version. It implements the full range of
|
This was the first public release version. It implements the full range of
|
||||||
C++17 `std::filesystem`, as far as possible without other C++17 dependencies.
|
C++17 std::filesystem, as far as possible without other C++17 dependencies.
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
macro(AddExecutableWithStdFS targetName)
|
macro(AddExecutableWithStdFS targetName)
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0))
|
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0))
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
include_directories(/usr/local/opt/llvm/include)
|
include_directories(/usr/local/opt/llvm/include)
|
||||||
link_directories(/usr/local/opt/llvm/lib)
|
link_directories(/usr/local/opt/llvm/lib)
|
||||||
@ -11,7 +12,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION V
|
|||||||
target_link_libraries(${targetName} -lc++fs)
|
target_link_libraries(${targetName} -lc++fs)
|
||||||
else()
|
else()
|
||||||
target_compile_options(${targetName} PRIVATE "-stdlib=libc++")
|
target_compile_options(${targetName} PRIVATE "-stdlib=libc++")
|
||||||
target_link_libraries(${targetName} -stdlib=libc++ -lc++fs $<$<PLATFORM_ID:Linux>:rt>)
|
target_link_libraries(${targetName} -stdlib=libc++ -lc++fs)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
if(NOT APPLE)
|
if(NOT APPLE)
|
||||||
@ -19,12 +20,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION V
|
|||||||
target_link_libraries(${targetName} -stdlib=libc++)
|
target_link_libraries(${targetName} -stdlib=libc++)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
|
|
||||||
target_link_libraries(filesystem_test xnet)
|
|
||||||
endif()
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
|
||||||
target_link_libraries(filesystem_test network)
|
|
||||||
endif()
|
|
||||||
target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
|
target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -34,13 +29,6 @@ if (CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0 O
|
|||||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
|
||||||
target_link_libraries(${targetName} -lstdc++fs)
|
target_link_libraries(${targetName} -lstdc++fs)
|
||||||
endif()
|
endif()
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
|
|
||||||
target_link_libraries(${targetName} xnet)
|
|
||||||
endif()
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
|
||||||
target_link_libraries(${targetName} network)
|
|
||||||
endif()
|
|
||||||
target_compile_options(${targetName} PRIVATE $<$<BOOL:${CYGWIN}>:-Wa,-mbig-obj>)
|
|
||||||
target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
|
target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -58,19 +46,11 @@ macro(AddTestExecutableWithStdCpp cppStd)
|
|||||||
add_executable(filesystem_test_cpp${cppStd} ${ARGN})
|
add_executable(filesystem_test_cpp${cppStd} ${ARGN})
|
||||||
set_property(TARGET filesystem_test_cpp${cppStd} PROPERTY CXX_STANDARD ${cppStd})
|
set_property(TARGET filesystem_test_cpp${cppStd} PROPERTY CXX_STANDARD ${cppStd})
|
||||||
target_link_libraries(filesystem_test_cpp${cppStd} ghc_filesystem)
|
target_link_libraries(filesystem_test_cpp${cppStd} ghc_filesystem)
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
|
|
||||||
target_link_libraries(filesystem_test_cpp${cppStd} xnet)
|
|
||||||
endif()
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
|
||||||
target_link_libraries(filesystem_test_cpp${cppStd} network)
|
|
||||||
endif()
|
|
||||||
target_compile_options(filesystem_test_cpp${cppStd} PRIVATE
|
target_compile_options(filesystem_test_cpp${cppStd} PRIVATE
|
||||||
$<$<BOOL:${EMSCRIPTEN}>:-s DISABLE_EXCEPTION_CATCHING=0>
|
$<$<BOOL:${EMSCRIPTEN}>:-s DISABLE_EXCEPTION_CATCHING=0>
|
||||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror -Wno-error=deprecated-declarations>
|
$<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror -Wno-error=deprecated-declarations>
|
||||||
$<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Wno-psabi -Werror -Wno-error=deprecated-declarations>
|
$<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Wno-psabi -Werror -Wno-error=deprecated-declarations>
|
||||||
$<$<CXX_COMPILER_ID:MSVC>:/WX /wd4996>
|
$<$<CXX_COMPILER_ID:MSVC>:/WX /wd"4996">)
|
||||||
$<$<BOOL:${CYGWIN}>:-Wa,-mbig-obj>
|
|
||||||
$<$<BOOL:${GHC_COVERAGE}>:--coverage>)
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||||
target_compile_definitions(filesystem_test_cpp${cppStd} PRIVATE _CRT_SECURE_NO_WARNINGS)
|
target_compile_definitions(filesystem_test_cpp${cppStd} PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
@PACKAGE_INIT@
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
# import targets
|
set_and_check(ghcfilesystem_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@")
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/ghc_filesystem-targets.cmake")
|
|
||||||
|
|
||||||
check_required_components(ghcfilesystem)
|
check_required_components(ghcfilesystem)
|
||||||
@ -10,8 +10,3 @@ add_executable(fs_du du.cpp)
|
|||||||
target_link_libraries(fs_du ghc_filesystem)
|
target_link_libraries(fs_du ghc_filesystem)
|
||||||
AddExecutableWithStdFS(std_fs_du du.cpp)
|
AddExecutableWithStdFS(std_fs_du du.cpp)
|
||||||
|
|
||||||
if(EXISTS "${PROJECT_SOURCE_DIR}/examples/benchmark.cpp")
|
|
||||||
add_executable(fs_benchmark benchmark.cpp)
|
|
||||||
set_property(TARGET fs_benchmark PROPERTY CXX_STANDARD 17)
|
|
||||||
target_link_libraries(fs_benchmark ghc_filesystem)
|
|
||||||
endif()
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,7 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
// fs_fwd.hpp - The forwarding header for the header/implementation separated usage of
|
// fs_fwd.hpp - The forwarding header for the header/implementation seperated usage of
|
||||||
// ghc::filesystem.
|
// ghc::filesystem.
|
||||||
// This file can be include at any place, where ghc::filesystem api is needed while
|
// This file can be include at any place, where ghc::filesystem api is needed while
|
||||||
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||||
@ -34,5 +34,5 @@
|
|||||||
#ifndef GHC_FILESYSTEM_FWD_H
|
#ifndef GHC_FILESYSTEM_FWD_H
|
||||||
#define GHC_FILESYSTEM_FWD_H
|
#define GHC_FILESYSTEM_FWD_H
|
||||||
#define GHC_FILESYSTEM_FWD
|
#define GHC_FILESYSTEM_FWD
|
||||||
#include "filesystem.hpp"
|
#include <ghc/filesystem.hpp>
|
||||||
#endif // GHC_FILESYSTEM_FWD_H
|
#endif // GHC_FILESYSTEM_FWD_H
|
||||||
|
|||||||
@ -25,11 +25,11 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
// fs_impl.hpp - The implementation header for the header/implementation separated usage of
|
// fs_impl.hpp - The implementation header for the header/implementation seperated usage of
|
||||||
// ghc::filesystem.
|
// ghc::filesystem.
|
||||||
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||||
// The cpp has to include this before including fs_fwd.hpp directly or via a different
|
// The cpp has to include this before including fs_fwd.hpp directly or via a different
|
||||||
// header to work.
|
// header to work.
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
#define GHC_FILESYSTEM_IMPLEMENTATION
|
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||||
#include "filesystem.hpp"
|
#include <ghc/filesystem.hpp>
|
||||||
|
|||||||
@ -30,33 +30,9 @@
|
|||||||
// namespace fs.
|
// namespace fs.
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
#ifndef GHC_FILESYSTEM_STD_H
|
#ifndef GHC_FILESYSTEM_STD_H
|
||||||
#define GHC_FILESYSTEM_STD_H
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
|
||||||
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
|
||||||
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
|
||||||
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
|
||||||
#define GHC_USE_STD_FS
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
|
||||||
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
|
||||||
// and watchOS 6.0.
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Availability.h>
|
|
||||||
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
|
||||||
// released after std::filesystem, where std::filesystem is always available.
|
|
||||||
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
|
||||||
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
|
||||||
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
|
||||||
#undef GHC_USE_STD_FS
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GHC_USE_STD_FS
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
namespace fs {
|
namespace fs {
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
@ -64,8 +40,11 @@
|
|||||||
using ofstream = std::ofstream;
|
using ofstream = std::ofstream;
|
||||||
using fstream = std::fstream;
|
using fstream = std::fstream;
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
#include "filesystem.hpp"
|
#endif
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
#define GHC_WIN_WSTRING_STRING_TYPE
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
namespace fs {
|
namespace fs {
|
||||||
using namespace ghc::filesystem;
|
using namespace ghc::filesystem;
|
||||||
using ifstream = ghc::filesystem::ifstream;
|
using ifstream = ghc::filesystem::ifstream;
|
||||||
@ -73,5 +52,5 @@
|
|||||||
using fstream = ghc::filesystem::fstream;
|
using fstream = ghc::filesystem::fstream;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // GHC_FILESYSTEM_STD_H
|
#endif // GHC_FILESYSTEM_STD_H
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
// fs_std_fwd.hpp - The forwarding header for the header/implementation separated usage of
|
// fs_std_fwd.hpp - The forwarding header for the header/implementation seperated usage of
|
||||||
// ghc::filesystem that uses std::filesystem if it detects it.
|
// ghc::filesystem that uses std::filesystem if it detects it.
|
||||||
// This file can be include at any place, where fs::filesystem api is needed while
|
// This file can be include at any place, where fs::filesystem api is needed while
|
||||||
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||||
@ -33,32 +33,9 @@
|
|||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
#ifndef GHC_FILESYSTEM_STD_FWD_H
|
#ifndef GHC_FILESYSTEM_STD_FWD_H
|
||||||
#define GHC_FILESYSTEM_STD_FWD_H
|
#define GHC_FILESYSTEM_STD_FWD_H
|
||||||
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
|
||||||
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
|
||||||
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
|
||||||
#define GHC_USE_STD_FS
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
|
||||||
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
|
||||||
// and watchOS 6.0.
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Availability.h>
|
|
||||||
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
|
||||||
// released after std::filesystem, where std::filesystem is always available.
|
|
||||||
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
|
||||||
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
|
||||||
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
|
||||||
#undef GHC_USE_STD_FS
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GHC_USE_STD_FS
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
namespace fs {
|
namespace fs {
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
@ -66,8 +43,12 @@
|
|||||||
using ofstream = std::ofstream;
|
using ofstream = std::ofstream;
|
||||||
using fstream = std::fstream;
|
using fstream = std::fstream;
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
#include "fs_fwd.hpp"
|
#endif
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
#define GHC_WIN_WSTRING_STRING_TYPE
|
||||||
|
#define GHC_FILESYSTEM_FWD
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
namespace fs {
|
namespace fs {
|
||||||
using namespace ghc::filesystem;
|
using namespace ghc::filesystem;
|
||||||
using ifstream = ghc::filesystem::ifstream;
|
using ifstream = ghc::filesystem::ifstream;
|
||||||
@ -75,5 +56,5 @@
|
|||||||
using fstream = ghc::filesystem::fstream;
|
using fstream = ghc::filesystem::fstream;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // GHC_FILESYSTEM_STD_FWD_H
|
#endif // GHC_FILESYSTEM_STD_FWD_H
|
||||||
|
|
||||||
|
|||||||
@ -25,36 +25,19 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
// fs_std_impl.hpp - The implementation header for the header/implementation separated usage of
|
// fs_std_impl.hpp - The implementation header for the header/implementation seperated usage of
|
||||||
// ghc::filesystem that does nothing if std::filesystem is detected.
|
// ghc::filesystem that does nothing if std::filesystem is detected.
|
||||||
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||||
// The cpp has to include this before including fs_std_fwd.hpp directly or via a different
|
// The cpp has to include this before including fs_std_fwd.hpp directly or via a different
|
||||||
// header to work.
|
// header to work.
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
|
||||||
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
|
||||||
#define GHC_USE_STD_FS
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
|
||||||
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
|
||||||
// and watchOS 6.0.
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Availability.h>
|
|
||||||
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
|
||||||
// released after std::filesystem, where std::filesystem is always available.
|
|
||||||
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
|
||||||
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
|
||||||
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
|
||||||
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
|
||||||
#undef GHC_USE_STD_FS
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GHC_USE_STD_FS
|
#ifndef GHC_USE_STD_FS
|
||||||
#include "fs_impl.hpp"
|
#define GHC_WIN_WSTRING_STRING_TYPE
|
||||||
|
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -3,20 +3,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
|||||||
set(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS ON)
|
set(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS ON)
|
||||||
include(ParseAndAddCatchTests)
|
include(ParseAndAddCatchTests)
|
||||||
|
|
||||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND UNIX AND NOT APPLE AND NOT BSD)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "-lc++abi")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
function(SetTestCompileOptions target_name)
|
|
||||||
target_compile_options(${target_name} PRIVATE
|
|
||||||
$<$<BOOL:${EMSCRIPTEN}>:-s DISABLE_EXCEPTION_CATCHING=0>
|
|
||||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror -Wno-deprecated-declarations>
|
|
||||||
$<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Wno-psabi -Werror -Wno-deprecated-declarations>
|
|
||||||
$<$<CXX_COMPILER_ID:MSVC>:/WX /wd4996>
|
|
||||||
$<$<BOOL:${CYGWIN}>:-Wa,-mbig-obj>)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
if(GHC_COVERAGE)
|
if(GHC_COVERAGE)
|
||||||
message("Generating test runner for coverage run...")
|
message("Generating test runner for coverage run...")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMCMAKE_EXE_LINKER_FLAGS} --coverage")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMCMAKE_EXE_LINKER_FLAGS} --coverage")
|
||||||
@ -27,54 +13,41 @@ if(GHC_COVERAGE)
|
|||||||
target_compile_options(filesystem_test PUBLIC --coverage)
|
target_compile_options(filesystem_test PUBLIC --coverage)
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(filesystem_test PUBLIC ghc_filesystem --coverage)
|
target_link_libraries(filesystem_test PUBLIC ghc_filesystem --coverage)
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
|
|
||||||
target_link_libraries(filesystem_test PUBLIC xnet)
|
|
||||||
endif()
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
|
||||||
target_link_libraries(filesystem_test PUBLIC network)
|
|
||||||
endif()
|
|
||||||
if("cxx_std_17" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES)
|
|
||||||
AddTestExecutableWithStdCpp(17 filesystem_test.cpp catch.hpp)
|
|
||||||
endif()
|
|
||||||
if("cxx_std_20" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES)
|
|
||||||
AddTestExecutableWithStdCpp(20 filesystem_test.cpp catch.hpp)
|
|
||||||
endif()
|
|
||||||
else()
|
else()
|
||||||
message("Generating test runner for normal test...")
|
message("Generating test runner for normal test...")
|
||||||
add_executable(filesystem_test filesystem_test.cpp catch.hpp)
|
add_executable(filesystem_test filesystem_test.cpp catch.hpp)
|
||||||
target_link_libraries(filesystem_test ghc_filesystem)
|
target_link_libraries(filesystem_test ghc_filesystem)
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
|
target_compile_options(filesystem_test PRIVATE
|
||||||
target_link_libraries(filesystem_test xnet)
|
$<$<BOOL:${EMSCRIPTEN}>:-s DISABLE_EXCEPTION_CATCHING=0>
|
||||||
endif()
|
$<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror>
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
$<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Wno-psabi -Werror>
|
||||||
target_link_libraries(filesystem_test network)
|
$<$<CXX_COMPILER_ID:MSVC>:/WX>)
|
||||||
endif()
|
|
||||||
SetTestCompileOptions(filesystem_test)
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||||
target_compile_definitions(filesystem_test PRIVATE _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN NOMINMAX)
|
target_compile_definitions(filesystem_test PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||||
endif()
|
endif()
|
||||||
if(EMSCRIPTEN)
|
if(EMSCRIPTEN)
|
||||||
set_target_properties(filesystem_test PROPERTIES LINK_FLAGS "-g4 -s DISABLE_EXCEPTION_CATCHING=0 -s ALLOW_MEMORY_GROWTH=1")
|
set_target_properties(filesystem_test PROPERTIES LINK_FLAGS "-g4 -s DISABLE_EXCEPTION_CATCHING=0 -s ALLOW_MEMORY_GROWTH=1")
|
||||||
endif()
|
endif()
|
||||||
ParseAndAddCatchTests(filesystem_test)
|
ParseAndAddCatchTests(filesystem_test)
|
||||||
if(GHC_FILESYSTEM_BUILD_STD_TESTING)
|
|
||||||
AddExecutableWithStdFS(std_filesystem_test filesystem_test.cpp catch.hpp)
|
AddExecutableWithStdFS(std_filesystem_test filesystem_test.cpp catch.hpp)
|
||||||
endif()
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_executable(filesystem_test_char filesystem_test.cpp catch.hpp)
|
add_executable(filesystem_test_wchar filesystem_test.cpp catch.hpp)
|
||||||
target_link_libraries(filesystem_test_char ghc_filesystem)
|
target_link_libraries(filesystem_test_wchar ghc_filesystem)
|
||||||
SetTestCompileOptions(filesystem_test_char)
|
target_compile_options(filesystem_test_wchar PRIVATE
|
||||||
|
$<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Werror>
|
||||||
|
$<$<CXX_COMPILER_ID:GNU>:-Wall -Werror>
|
||||||
|
$<$<CXX_COMPILER_ID:MSVC>:/WX>)
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||||
target_compile_definitions(filesystem_test_char PRIVATE _CRT_SECURE_NO_WARNINGS GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE)
|
target_compile_definitions(filesystem_test_wchar PRIVATE _CRT_SECURE_NO_WARNINGS GHC_WIN_WSTRING_STRING_TYPE)
|
||||||
else()
|
else()
|
||||||
target_compile_definitions(filesystem_test_char PRIVATE GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE)
|
target_compile_definitions(filesystem_test_wchar PRIVATE GHC_WIN_WSTRING_STRING_TYPE)
|
||||||
endif()
|
endif()
|
||||||
ParseAndAddCatchTests(filesystem_test_char)
|
ParseAndAddCatchTests(filesystem_test_wchar)
|
||||||
endif()
|
endif()
|
||||||
if("cxx_std_17" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES)
|
if("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||||
AddTestExecutableWithStdCpp(17 filesystem_test.cpp catch.hpp)
|
AddTestExecutableWithStdCpp(17 filesystem_test.cpp catch.hpp)
|
||||||
endif()
|
endif()
|
||||||
if("cxx_std_20" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES)
|
if("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||||
AddTestExecutableWithStdCpp(20 filesystem_test.cpp catch.hpp)
|
AddTestExecutableWithStdCpp(20 filesystem_test.cpp catch.hpp)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@ -85,15 +58,8 @@ add_test(multifile_test multifile_test)
|
|||||||
|
|
||||||
add_executable(fwd_impl_test fwd_test.cpp impl_test.cpp)
|
add_executable(fwd_impl_test fwd_test.cpp impl_test.cpp)
|
||||||
target_link_libraries(fwd_impl_test ghc_filesystem)
|
target_link_libraries(fwd_impl_test ghc_filesystem)
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
|
|
||||||
target_link_libraries(fwd_impl_test xnet)
|
|
||||||
endif()
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
|
||||||
target_link_libraries(fwd_impl_test network)
|
|
||||||
endif()
|
|
||||||
SetTestCompileOptions(fwd_impl_test)
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||||
target_compile_definitions(fwd_impl_test PRIVATE _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN NOMINMAX)
|
target_compile_definitions(fwd_impl_test PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||||
endif()
|
endif()
|
||||||
add_test(fwd_impl_test fwd_impl_test)
|
add_test(fwd_impl_test fwd_impl_test)
|
||||||
|
|
||||||
@ -102,4 +68,3 @@ if(NOT MSVC)
|
|||||||
target_compile_options(exception PRIVATE -fno-exceptions)
|
target_compile_options(exception PRIVATE -fno-exceptions)
|
||||||
endif()
|
endif()
|
||||||
target_include_directories(exception PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
target_include_directories(exception PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
||||||
SetTestCompileOptions(exception)
|
|
||||||
|
|||||||
7189
test/catch.hpp
7189
test/catch.hpp
File diff suppressed because it is too large
Load Diff
@ -76,7 +76,6 @@ using fstream = ghc::filesystem::fstream;
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GHC_FILESYSTEM_FWD_TEST
|
#ifndef GHC_FILESYSTEM_FWD_TEST
|
||||||
@ -99,7 +98,7 @@ using fstream = ghc::filesystem::fstream;
|
|||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
template <typename TP>
|
template <typename TP>
|
||||||
static std::time_t to_time_t(TP tp)
|
std::time_t to_time_t(TP tp)
|
||||||
{
|
{
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
|
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
|
||||||
@ -107,7 +106,7 @@ static std::time_t to_time_t(TP tp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename TP>
|
template <typename TP>
|
||||||
static TP from_time_t(std::time_t t)
|
TP from_time_t(std::time_t t)
|
||||||
{
|
{
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
auto sctp = system_clock::from_time_t(t);
|
auto sctp = system_clock::from_time_t(t);
|
||||||
@ -128,14 +127,6 @@ struct StringMaker<fs::perms>
|
|||||||
static std::string convert(fs::perms const& value) { return std::to_string(static_cast<unsigned int>(value)); }
|
static std::string convert(fs::perms const& value) { return std::to_string(static_cast<unsigned int>(value)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
struct StringMaker<fs::file_status>
|
|
||||||
{
|
|
||||||
static std::string convert(fs::file_status const& value) {
|
|
||||||
return std::string("[") + std::to_string(static_cast<unsigned int>(value.type())) + "," + std::to_string(static_cast<unsigned int>(value.permissions())) + "]";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cpp_lib_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
template <>
|
template <>
|
||||||
struct StringMaker<char8_t>
|
struct StringMaker<char8_t>
|
||||||
@ -214,8 +205,7 @@ static void generateFile(const fs::path& pathname, int withSize = -1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
#if !defined(_WIN64) && defined(KEY_WOW64_64KEY)
|
inline bool isWow64Proc()
|
||||||
static bool isWow64Proc()
|
|
||||||
{
|
{
|
||||||
typedef BOOL(WINAPI * IsWow64Process_t)(HANDLE, PBOOL);
|
typedef BOOL(WINAPI * IsWow64Process_t)(HANDLE, PBOOL);
|
||||||
BOOL bIsWow64 = FALSE;
|
BOOL bIsWow64 = FALSE;
|
||||||
@ -227,7 +217,6 @@ static bool isWow64Proc()
|
|||||||
}
|
}
|
||||||
return bIsWow64 == TRUE;
|
return bIsWow64 == TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool is_symlink_creation_supported()
|
static bool is_symlink_creation_supported()
|
||||||
{
|
{
|
||||||
@ -305,13 +294,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
static bool operator==(TestAllocator<T> const&, TestAllocator<U> const&) noexcept
|
bool operator==(TestAllocator<T> const&, TestAllocator<U> const&) noexcept
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
static bool operator!=(TestAllocator<T> const& x, TestAllocator<U> const& y) noexcept
|
bool operator!=(TestAllocator<T> const& x, TestAllocator<U> const& y) noexcept
|
||||||
{
|
{
|
||||||
return !(x == y);
|
return !(x == y);
|
||||||
}
|
}
|
||||||
@ -365,7 +354,7 @@ TEST_CASE("fs::detail::toUtf8", "[filesystem][fs.detail.utf8]")
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("fs.path.generic - path::preferred_separator", "[filesystem][path][fs.path.generic]")
|
TEST_CASE("30.10.8.1 path::preferred_separator", "[filesystem][path][fs.path.generic]")
|
||||||
{
|
{
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
CHECK(fs::path::preferred_separator == '\\');
|
CHECK(fs::path::preferred_separator == '\\');
|
||||||
@ -375,7 +364,7 @@ TEST_CASE("fs.path.generic - path::preferred_separator", "[filesystem][path][fs.
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GHC_OS_WINDOWS
|
#ifndef GHC_OS_WINDOWS
|
||||||
TEST_CASE("fs.path.generic - path(\"//host\").has_root_name()", "[filesystem][path][fs.path.generic]")
|
TEST_CASE("30.10.8.1 path(\"//host\").has_root_name()", "[filesystem][path][fs.path.generic]")
|
||||||
{
|
{
|
||||||
if (!has_host_root_name_support()) {
|
if (!has_host_root_name_support()) {
|
||||||
WARN("This implementation doesn't support path(\"//host\").has_root_name() == true [C++17 30.12.8.1 par. 4] on this platform, tests based on this are skipped. (Should be okay.)");
|
WARN("This implementation doesn't support path(\"//host\").has_root_name() == true [C++17 30.12.8.1 par. 4] on this platform, tests based on this are skipped. (Should be okay.)");
|
||||||
@ -383,26 +372,15 @@ TEST_CASE("fs.path.generic - path(\"//host\").has_root_name()", "[filesystem][pa
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("fs.path.construct - path constructors and destructor", "[filesystem][path][fs.path.construct]")
|
TEST_CASE("30.10.8.4.1 path constructors and destructor", "[filesystem][path][fs.path.construct]")
|
||||||
{
|
{
|
||||||
CHECK("/usr/local/bin" == fs::path("/usr/local/bin").generic_string());
|
CHECK("/usr/local/bin" == fs::path("/usr/local/bin").generic_string());
|
||||||
std::string str = "/usr/local/bin";
|
std::string str = "/usr/local/bin";
|
||||||
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
|
|
||||||
std::u8string u8str = u8"/usr/local/bin";
|
|
||||||
#endif
|
|
||||||
std::u16string u16str = u"/usr/local/bin";
|
std::u16string u16str = u"/usr/local/bin";
|
||||||
std::u32string u32str = U"/usr/local/bin";
|
std::u32string u32str = U"/usr/local/bin";
|
||||||
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
|
|
||||||
CHECK(u8str == fs::path(u8str).generic_u8string());
|
|
||||||
#endif
|
|
||||||
CHECK(u16str == fs::path(u16str).generic_u16string());
|
|
||||||
CHECK(u32str == fs::path(u32str).generic_u32string());
|
|
||||||
CHECK(str == fs::path(str, fs::path::format::generic_format));
|
CHECK(str == fs::path(str, fs::path::format::generic_format));
|
||||||
CHECK(str == fs::path(str.begin(), str.end()));
|
CHECK(str == fs::path(str.begin(), str.end()));
|
||||||
CHECK(fs::path(std::wstring(3, 67)) == "CCC");
|
CHECK(fs::path(std::wstring(3, 67)) == "CCC");
|
||||||
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
|
|
||||||
CHECK(str == fs::path(u8str.begin(), u8str.end()));
|
|
||||||
#endif
|
|
||||||
CHECK(str == fs::path(u16str.begin(), u16str.end()));
|
CHECK(str == fs::path(u16str.begin(), u16str.end()));
|
||||||
CHECK(str == fs::path(u32str.begin(), u32str.end()));
|
CHECK(str == fs::path(u32str.begin(), u32str.end()));
|
||||||
#ifdef GHC_FILESYSTEM_VERSION
|
#ifdef GHC_FILESYSTEM_VERSION
|
||||||
@ -419,7 +397,7 @@ TEST_CASE("fs.path.construct - path constructors and destructor", "[filesystem][
|
|||||||
CHECK("//host/foo/bar" == fs::path("//host/foo/bar"));
|
CHECK("//host/foo/bar" == fs::path("//host/foo/bar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(GHC_OS_WINDOWS) && !(defined(__GLIBCXX__) && !(defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE >= 8))) && !defined(USE_STD_FS)
|
#if !defined(GHC_OS_WINDOWS) && !(defined(GCC_VERSION) && GCC_VERSION < 80100) && !defined(USE_STD_FS)
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
bool testUTF8Locale = false;
|
bool testUTF8Locale = false;
|
||||||
try {
|
try {
|
||||||
@ -446,7 +424,7 @@ TEST_CASE("fs.path.construct - path constructors and destructor", "[filesystem][
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.assign - path assignments", "[filesystem][path][fs.path.assign]")
|
TEST_CASE("30.10.8.4.2 path assignments", "[filesystem][path][fs.path.assign]")
|
||||||
{
|
{
|
||||||
fs::path p1{"/foo/bar"};
|
fs::path p1{"/foo/bar"};
|
||||||
fs::path p2{"/usr/local"};
|
fs::path p2{"/usr/local"};
|
||||||
@ -455,10 +433,6 @@ TEST_CASE("fs.path.assign - path assignments", "[filesystem][path][fs.path.assig
|
|||||||
REQUIRE(p1 == p3);
|
REQUIRE(p1 == p3);
|
||||||
p3 = fs::path{"/usr/local"};
|
p3 = fs::path{"/usr/local"};
|
||||||
REQUIRE(p2 == p3);
|
REQUIRE(p2 == p3);
|
||||||
p3 = fs::path{L"/usr/local"};
|
|
||||||
REQUIRE(p2 == p3);
|
|
||||||
p3.assign(L"/usr/local");
|
|
||||||
REQUIRE(p2 == p3);
|
|
||||||
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
|
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
|
||||||
p3 = fs::path::string_type{L"/foo/bar"};
|
p3 = fs::path::string_type{L"/foo/bar"};
|
||||||
REQUIRE(p1 == p3);
|
REQUIRE(p1 == p3);
|
||||||
@ -481,7 +455,7 @@ TEST_CASE("fs.path.assign - path assignments", "[filesystem][path][fs.path.assig
|
|||||||
REQUIRE(p2 == p3);
|
REQUIRE(p2 == p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.append - path appends", "[filesystem][path][fs.path.append]")
|
TEST_CASE("30.10.8.4.3 path appends", "[filesystem][path][fs.path.append]")
|
||||||
{
|
{
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
CHECK(fs::path("foo") / "c:/bar" == "c:/bar");
|
CHECK(fs::path("foo") / "c:/bar" == "c:/bar");
|
||||||
@ -507,7 +481,7 @@ TEST_CASE("fs.path.append - path appends", "[filesystem][path][fs.path.append]")
|
|||||||
// TODO: append(first, last)
|
// TODO: append(first, last)
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.concat - path concatenation", "[filesystem][path][fs.path.concat]")
|
TEST_CASE("30.10.8.4.4 path concatenation", "[filesystem][path][fs.path.concat]")
|
||||||
{
|
{
|
||||||
CHECK((fs::path("foo") += fs::path("bar")) == "foobar");
|
CHECK((fs::path("foo") += fs::path("bar")) == "foobar");
|
||||||
CHECK((fs::path("foo") += fs::path("/bar")) == "foo/bar");
|
CHECK((fs::path("foo") += fs::path("/bar")) == "foo/bar");
|
||||||
@ -517,13 +491,9 @@ TEST_CASE("fs.path.concat - path concatenation", "[filesystem][path][fs.path.con
|
|||||||
|
|
||||||
CHECK((fs::path("foo") += "bar") == "foobar");
|
CHECK((fs::path("foo") += "bar") == "foobar");
|
||||||
CHECK((fs::path("foo") += "/bar") == "foo/bar");
|
CHECK((fs::path("foo") += "/bar") == "foo/bar");
|
||||||
CHECK((fs::path("foo") += L"bar") == "foobar");
|
|
||||||
CHECK((fs::path("foo") += L"/bar") == "foo/bar");
|
|
||||||
|
|
||||||
CHECK((fs::path("foo") += 'b') == "foob");
|
CHECK((fs::path("foo") += 'b') == "foob");
|
||||||
CHECK((fs::path("foo") += '/') == "foo/");
|
CHECK((fs::path("foo") += '/') == "foo/");
|
||||||
CHECK((fs::path("foo") += L'b') == "foob");
|
|
||||||
CHECK((fs::path("foo") += L'/') == "foo/");
|
|
||||||
|
|
||||||
CHECK((fs::path("foo") += std::string("bar")) == "foobar");
|
CHECK((fs::path("foo") += std::string("bar")) == "foobar");
|
||||||
CHECK((fs::path("foo") += std::string("/bar")) == "foo/bar");
|
CHECK((fs::path("foo") += std::string("/bar")) == "foo/bar");
|
||||||
@ -536,8 +506,6 @@ TEST_CASE("fs.path.concat - path concatenation", "[filesystem][path][fs.path.con
|
|||||||
|
|
||||||
CHECK(fs::path("foo").concat("bar") == "foobar");
|
CHECK(fs::path("foo").concat("bar") == "foobar");
|
||||||
CHECK(fs::path("foo").concat("/bar") == "foo/bar");
|
CHECK(fs::path("foo").concat("/bar") == "foo/bar");
|
||||||
CHECK(fs::path("foo").concat(L"bar") == "foobar");
|
|
||||||
CHECK(fs::path("foo").concat(L"/bar") == "foo/bar");
|
|
||||||
std::string bar = "bar";
|
std::string bar = "bar";
|
||||||
CHECK(fs::path("foo").concat(bar.begin(), bar.end()) == "foobar");
|
CHECK(fs::path("foo").concat(bar.begin(), bar.end()) == "foobar");
|
||||||
#ifndef USE_STD_FS
|
#ifndef USE_STD_FS
|
||||||
@ -546,7 +514,7 @@ TEST_CASE("fs.path.concat - path concatenation", "[filesystem][path][fs.path.con
|
|||||||
// TODO: contat(first, last)
|
// TODO: contat(first, last)
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.modifiers - path modifiers", "[filesystem][path][fs.path.modifiers]")
|
TEST_CASE("30.10.8.4.5 path modifiers", "[filesystem][path][fs.path.modifiers]")
|
||||||
{
|
{
|
||||||
fs::path p = fs::path("/foo/bar");
|
fs::path p = fs::path("/foo/bar");
|
||||||
p.clear();
|
p.clear();
|
||||||
@ -585,7 +553,7 @@ TEST_CASE("fs.path.modifiers - path modifiers", "[filesystem][path][fs.path.modi
|
|||||||
CHECK(p2 == "foo");
|
CHECK(p2 == "foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.native.obs - path native format observers", "[filesystem][path][fs.path.native.obs]")
|
TEST_CASE("30.10.8.4.6 path native format observers", "[filesystem][path][fs.path.native.obs]")
|
||||||
{
|
{
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
|
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
|
||||||
@ -623,7 +591,7 @@ TEST_CASE("fs.path.native.obs - path native format observers", "[filesystem][pat
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.generic.obs - path generic format observers", "[filesystem][path][fs.path.generic.obs]")
|
TEST_CASE("30.10.8.4.7 path generic format observers", "[filesystem][path][fs.path.generic.obs]")
|
||||||
{
|
{
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
#ifndef IS_WCHAR_PATH
|
#ifndef IS_WCHAR_PATH
|
||||||
@ -658,7 +626,7 @@ TEST_CASE("fs.path.generic.obs - path generic format observers", "[filesystem][p
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.compare - path compare", "[filesystem][path][fs.path.compare]")
|
TEST_CASE("30.10.8.4.8 path compare", "[filesystem][path][fs.path.compare]")
|
||||||
{
|
{
|
||||||
CHECK(fs::path("/foo/b").compare("/foo/a") > 0);
|
CHECK(fs::path("/foo/b").compare("/foo/a") > 0);
|
||||||
CHECK(fs::path("/foo/b").compare("/foo/b") == 0);
|
CHECK(fs::path("/foo/b").compare("/foo/b") == 0);
|
||||||
@ -684,7 +652,7 @@ TEST_CASE("fs.path.compare - path compare", "[filesystem][path][fs.path.compare]
|
|||||||
#endif // LWG_2936_BEHAVIOUR
|
#endif // LWG_2936_BEHAVIOUR
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.decompose]")
|
TEST_CASE("30.10.8.4.9 path decomposition", "[filesystem][path][fs.path.decompose]")
|
||||||
{
|
{
|
||||||
// root_name()
|
// root_name()
|
||||||
CHECK(fs::path("").root_name() == "");
|
CHECK(fs::path("").root_name() == "");
|
||||||
@ -792,9 +760,6 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.
|
|||||||
CHECK(fs::path("C:/foo").filename() == "foo");
|
CHECK(fs::path("C:/foo").filename() == "foo");
|
||||||
CHECK(fs::path("C:\\foo").filename() == "foo");
|
CHECK(fs::path("C:\\foo").filename() == "foo");
|
||||||
CHECK(fs::path("C:foo").filename() == "foo");
|
CHECK(fs::path("C:foo").filename() == "foo");
|
||||||
CHECK(fs::path("t:est.txt").filename() == "est.txt");
|
|
||||||
#else
|
|
||||||
CHECK(fs::path("t:est.txt").filename() == "t:est.txt");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// stem()
|
// stem()
|
||||||
@ -812,13 +777,6 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.
|
|||||||
CHECK(fs::path("/foo/.profile").stem() == ".profile");
|
CHECK(fs::path("/foo/.profile").stem() == ".profile");
|
||||||
CHECK(fs::path(".bar").stem() == ".bar");
|
CHECK(fs::path(".bar").stem() == ".bar");
|
||||||
CHECK(fs::path("..bar").stem() == ".");
|
CHECK(fs::path("..bar").stem() == ".");
|
||||||
#ifdef GHC_OS_WINDOWS
|
|
||||||
CHECK(fs::path("t:est.txt").stem() == "est");
|
|
||||||
#else
|
|
||||||
CHECK(fs::path("t:est.txt").stem() == "t:est");
|
|
||||||
#endif
|
|
||||||
CHECK(fs::path("/foo/.").stem() == ".");
|
|
||||||
CHECK(fs::path("/foo/..").stem() == "..");
|
|
||||||
|
|
||||||
// extension()
|
// extension()
|
||||||
CHECK(fs::path("/foo/bar.txt").extension() == ".txt");
|
CHECK(fs::path("/foo/bar.txt").extension() == ".txt");
|
||||||
@ -826,9 +784,6 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.
|
|||||||
CHECK(fs::path("/foo/.profile").extension() == "");
|
CHECK(fs::path("/foo/.profile").extension() == "");
|
||||||
CHECK(fs::path(".bar").extension() == "");
|
CHECK(fs::path(".bar").extension() == "");
|
||||||
CHECK(fs::path("..bar").extension() == ".bar");
|
CHECK(fs::path("..bar").extension() == ".bar");
|
||||||
CHECK(fs::path("t:est.txt").extension() == ".txt");
|
|
||||||
CHECK(fs::path("/foo/.").extension() == "");
|
|
||||||
CHECK(fs::path("/foo/..").extension() == "");
|
|
||||||
|
|
||||||
if (has_host_root_name_support()) {
|
if (has_host_root_name_support()) {
|
||||||
// //host-based root-names
|
// //host-based root-names
|
||||||
@ -847,7 +802,7 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.query - path query", "[fielsystem][path][fs.path.query]")
|
TEST_CASE("30.10.8.4.10 path query", "[fielsystem][path][fs.path.query]")
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
CHECK(fs::path("").empty());
|
CHECK(fs::path("").empty());
|
||||||
@ -945,7 +900,7 @@ TEST_CASE("fs.path.query - path query", "[fielsystem][path][fs.path.query]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.gen - path generation", "[filesystem][path][fs.path.gen]")
|
TEST_CASE("30.10.8.4.11 path generation", "[filesystem][path][fs.path.gen]")
|
||||||
{
|
{
|
||||||
// lexically_normal()
|
// lexically_normal()
|
||||||
CHECK(fs::path("foo/./bar/..").lexically_normal() == "foo/");
|
CHECK(fs::path("foo/./bar/..").lexically_normal() == "foo/");
|
||||||
@ -965,10 +920,6 @@ TEST_CASE("fs.path.gen - path generation", "[filesystem][path][fs.path.gen]")
|
|||||||
// lexically_relative()
|
// lexically_relative()
|
||||||
CHECK(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d");
|
CHECK(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d");
|
||||||
CHECK(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c");
|
CHECK(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c");
|
||||||
CHECK(fs::path("/a/b/c").lexically_relative("/a/b/c/d/..") == ".");
|
|
||||||
CHECK(fs::path("/a/b/c/").lexically_relative("/a/b/c/d/..") == ".");
|
|
||||||
CHECK(fs::path("").lexically_relative("/a/..") == "");
|
|
||||||
CHECK(fs::path("").lexically_relative("a/..") == ".");
|
|
||||||
CHECK(fs::path("a/b/c").lexically_relative("a") == "b/c");
|
CHECK(fs::path("a/b/c").lexically_relative("a") == "b/c");
|
||||||
CHECK(fs::path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
|
CHECK(fs::path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
|
||||||
CHECK(fs::path("a/b/c").lexically_relative("a/b/c") == ".");
|
CHECK(fs::path("a/b/c").lexically_relative("a/b/c") == ".");
|
||||||
@ -1036,7 +987,7 @@ static std::string reverseIterateResult(const fs::path& path)
|
|||||||
return result.str();
|
return result.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.itr - path iterators", "[filesystem][path][fs.path.itr]")
|
TEST_CASE("30.10.8.5 path iterators", "[filesystem][path][fs.path.itr]")
|
||||||
{
|
{
|
||||||
CHECK(iterateResult(fs::path()).empty());
|
CHECK(iterateResult(fs::path()).empty());
|
||||||
CHECK("." == iterateResult(fs::path(".")));
|
CHECK("." == iterateResult(fs::path(".")));
|
||||||
@ -1119,7 +1070,7 @@ TEST_CASE("fs.path.itr - path iterators", "[filesystem][path][fs.path.itr]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.nonmember - path non-member functions", "[filesystem][path][fs.path.nonmember]")
|
TEST_CASE("30.10.8.6 path non-member functions", "[filesystem][path][fs.path.nonmember]")
|
||||||
{
|
{
|
||||||
fs::path p1("foo/bar");
|
fs::path p1("foo/bar");
|
||||||
fs::path p2("some/other");
|
fs::path p2("some/other");
|
||||||
@ -1141,7 +1092,7 @@ TEST_CASE("fs.path.nonmember - path non-member functions", "[filesystem][path][f
|
|||||||
CHECK(p1 / p2 == "some/other/foo/bar");
|
CHECK(p1 / p2 == "some/other/foo/bar");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.io - path inserter and extractor", "[filesystem][path][fs.path.io]")
|
TEST_CASE("30.10.8.6.1 path inserter and extractor", "[filesystem][path][fs.path.io]")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
@ -1191,7 +1142,7 @@ TEST_CASE("fs.path.io - path inserter and extractor", "[filesystem][path][fs.pat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.path.factory - path factory functions", "[filesystem][path][fs.path.factory]")
|
TEST_CASE("30.10.8.6.2 path factory functions", "[filesystem][path][fs.path.factory]")
|
||||||
{
|
{
|
||||||
CHECK(fs::u8path("foo/bar") == fs::path("foo/bar"));
|
CHECK(fs::u8path("foo/bar") == fs::path("foo/bar"));
|
||||||
CHECK(fs::u8path("foo/bar") == fs::path("foo/bar"));
|
CHECK(fs::u8path("foo/bar") == fs::path("foo/bar"));
|
||||||
@ -1199,7 +1150,7 @@ TEST_CASE("fs.path.factory - path factory functions", "[filesystem][path][fs.pat
|
|||||||
CHECK(fs::u8path(str.begin(), str.end()) == str);
|
CHECK(fs::u8path(str.begin(), str.end()) == str);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.class.filesystem_error - class filesystem_error", "[filesystem][filesystem_error][fs.class.filesystem_error]")
|
TEST_CASE("30.10.9 class filesystem_error", "[filesystem][filesystem_error][fs.class.filesystem_error]")
|
||||||
{
|
{
|
||||||
std::error_code ec(1, std::system_category());
|
std::error_code ec(1, std::system_category());
|
||||||
fs::filesystem_error fse("None", std::error_code());
|
fs::filesystem_error fse("None", std::error_code());
|
||||||
@ -1218,12 +1169,12 @@ TEST_CASE("fs.class.filesystem_error - class filesystem_error", "[filesystem][fi
|
|||||||
CHECK(fse.path2() == "some/other");
|
CHECK(fse.path2() == "some/other");
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr fs::perms constExprOwnerAll()
|
constexpr fs::perms constExprOwnerAll()
|
||||||
{
|
{
|
||||||
return fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec;
|
return fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.enum - enum class perms", "[filesystem][enum][fs.enum]")
|
TEST_CASE("30.10.10.4 enum class perms", "[filesystem][enum][fs.enum]")
|
||||||
{
|
{
|
||||||
static_assert(constExprOwnerAll() == fs::perms::owner_all, "constexpr didn't result in owner_all");
|
static_assert(constExprOwnerAll() == fs::perms::owner_all, "constexpr didn't result in owner_all");
|
||||||
CHECK((fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec) == fs::perms::owner_all);
|
CHECK((fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec) == fs::perms::owner_all);
|
||||||
@ -1233,7 +1184,7 @@ TEST_CASE("fs.enum - enum class perms", "[filesystem][enum][fs.enum]")
|
|||||||
CHECK((fs::perms::all | fs::perms::set_uid | fs::perms::set_gid | fs::perms::sticky_bit) == fs::perms::mask);
|
CHECK((fs::perms::all | fs::perms::set_uid | fs::perms::set_gid | fs::perms::sticky_bit) == fs::perms::mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.class.file_status - class file_status", "[filesystem][file_status][fs.class.file_status]")
|
TEST_CASE("30.10.11 class file_status", "[filesystem][file_status][fs.class.file_status]")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
fs::file_status fs;
|
fs::file_status fs;
|
||||||
@ -1268,20 +1219,9 @@ TEST_CASE("fs.class.file_status - class file_status", "[filesystem][file_status]
|
|||||||
CHECK(fs.type() == fs::file_type::regular);
|
CHECK(fs.type() == fs::file_type::regular);
|
||||||
CHECK(fs.permissions() == fs::perms::unknown);
|
CHECK(fs.permissions() == fs::perms::unknown);
|
||||||
}
|
}
|
||||||
#if !defined(USE_STD_FS) || defined(GHC_FILESYSTEM_RUNNING_CPP20)
|
|
||||||
{
|
|
||||||
fs::file_status fs1{fs::file_type::regular, fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec};
|
|
||||||
fs::file_status fs2{fs::file_type::regular, fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec};
|
|
||||||
fs::file_status fs3{fs::file_type::directory, fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec};
|
|
||||||
fs::file_status fs4{fs::file_type::regular, fs::perms::owner_read | fs::perms::owner_write};
|
|
||||||
CHECK(fs1 == fs2);
|
|
||||||
CHECK_FALSE(fs1 == fs3);
|
|
||||||
CHECK_FALSE(fs1 == fs4);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.dir.entry - class directory_entry", "[filesystem][directory_entry][fs.dir.entry]")
|
TEST_CASE("30.10.12 class directory_entry", "[filesystem][directory_entry][fs.dir.entry]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -1396,19 +1336,9 @@ TEST_CASE("fs.dir.entry - class directory_entry", "[filesystem][directory_entry]
|
|||||||
CHECK(!(d2 != d2));
|
CHECK(!(d2 != d2));
|
||||||
CHECK(d1 == d1);
|
CHECK(d1 == d1);
|
||||||
CHECK(!(d1 == d2));
|
CHECK(!(d1 == d2));
|
||||||
if(is_symlink_creation_supported()) {
|
|
||||||
fs::create_symlink(t.path() / "nonexistent", t.path() / "broken");
|
|
||||||
for (auto d3 : fs::directory_iterator(t.path())) {
|
|
||||||
CHECK_NOTHROW(d3.symlink_status());
|
|
||||||
CHECK_NOTHROW(d3.status());
|
|
||||||
CHECK_NOTHROW(d3.refresh());
|
|
||||||
}
|
|
||||||
fs::directory_entry entry(t.path() / "broken");
|
|
||||||
CHECK_NOTHROW(entry.refresh());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.class.directory_iterator - class directory_iterator", "[filesystem][directory_iterator][fs.class.directory_iterator]")
|
TEST_CASE("30.10.13 class directory_iterator", "[filesystem][directory_iterator][fs.class.directory_iterator]")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
@ -1469,7 +1399,7 @@ TEST_CASE("fs.class.directory_iterator - class directory_iterator", "[filesystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesystem][recursive_directory_iterator][fs.class.rec.dir.itr]")
|
TEST_CASE("30.10.14 class recursive_directory_iterator", "[filesystem][recursive_directory_iterator][fs.class.rec.dir.itr]")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
auto iter = fs::recursive_directory_iterator(".");
|
auto iter = fs::recursive_directory_iterator(".");
|
||||||
@ -1625,40 +1555,9 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
|
|||||||
}
|
}
|
||||||
CHECK(os.str() == "[./a,0],[./d1,0],[./d1/d2,1],[./e,0],");
|
CHECK(os.str() == "[./a,0],[./d1,0],[./d1/d2,1],[./e,0],");
|
||||||
}
|
}
|
||||||
if (is_symlink_creation_supported()) {
|
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
|
||||||
fs::create_directory("d1");
|
|
||||||
generateFile("d1/a");
|
|
||||||
fs::create_directory("d2");
|
|
||||||
generateFile("d2/b");
|
|
||||||
fs::create_directory_symlink("../d1", "d2/ds1");
|
|
||||||
fs::create_directory_symlink("d3", "d2/ds2");
|
|
||||||
std::multiset<std::string> result;
|
|
||||||
REQUIRE_NOTHROW([&](){
|
|
||||||
for (const auto& de : fs::recursive_directory_iterator("d2", fs::directory_options::follow_directory_symlink)) {
|
|
||||||
result.insert(de.path().generic_string());
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
std::stringstream os;
|
|
||||||
for(const auto& p : result) {
|
|
||||||
os << p << ",";
|
|
||||||
}
|
|
||||||
CHECK(os.str() == "d2/b,d2/ds1,d2/ds1/a,d2/ds2,");
|
|
||||||
os.str("");
|
|
||||||
result.clear();
|
|
||||||
REQUIRE_NOTHROW([&](){
|
|
||||||
for (const auto& de : fs::recursive_directory_iterator("d2")) {
|
|
||||||
result.insert(de.path().generic_string());
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
for(const auto& p : result) {
|
|
||||||
os << p << ",";
|
|
||||||
}
|
|
||||||
CHECK(os.str() == "d2/b,d2/ds1,d2/ds2,");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.absolute - absolute", "[filesystem][operations][fs.op.absolute]")
|
TEST_CASE("30.10.15.1 absolute", "[filesystem][operations][fs.op.absolute]")
|
||||||
{
|
{
|
||||||
CHECK(fs::absolute("") == fs::current_path() / "");
|
CHECK(fs::absolute("") == fs::current_path() / "");
|
||||||
CHECK(fs::absolute(fs::current_path()) == fs::current_path());
|
CHECK(fs::absolute(fs::current_path()) == fs::current_path());
|
||||||
@ -1672,7 +1571,7 @@ TEST_CASE("fs.op.absolute - absolute", "[filesystem][operations][fs.op.absolute]
|
|||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.canonical - canonical", "[filesystem][operations][fs.op.canonical]")
|
TEST_CASE("30.10.15.2 canonical", "[filesystem][operations][fs.op.canonical]")
|
||||||
{
|
{
|
||||||
CHECK_THROWS_AS(fs::canonical(""), fs::filesystem_error);
|
CHECK_THROWS_AS(fs::canonical(""), fs::filesystem_error);
|
||||||
{
|
{
|
||||||
@ -1715,7 +1614,7 @@ TEST_CASE("fs.op.canonical - canonical", "[filesystem][operations][fs.op.canonic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.copy - copy", "[filesystem][operations][fs.op.copy]")
|
TEST_CASE("30.10.15.3 copy", "[filesystem][operations][fs.op.copy]")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
@ -1784,7 +1683,7 @@ TEST_CASE("fs.op.copy - copy", "[filesystem][operations][fs.op.copy]")
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.copy_file - copy_file", "[filesystem][operations][fs.op.copy_file]")
|
TEST_CASE("30.10.15.4 copy_file", "[filesystem][operations][fs.op.copy_file]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -1807,22 +1706,9 @@ TEST_CASE("fs.op.copy_file - copy_file", "[filesystem][operations][fs.op.copy_fi
|
|||||||
CHECK_NOTHROW(fs::copy_file("foobar", "foobar2", ec));
|
CHECK_NOTHROW(fs::copy_file("foobar", "foobar2", ec));
|
||||||
CHECK(ec);
|
CHECK(ec);
|
||||||
CHECK(!fs::exists("foobar"));
|
CHECK(!fs::exists("foobar"));
|
||||||
fs::path file1("temp1.txt");
|
|
||||||
fs::path file2("temp2.txt");
|
|
||||||
generateFile(file1, 200);
|
|
||||||
generateFile(file2, 200);
|
|
||||||
auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write;
|
|
||||||
CHECK_NOTHROW(fs::permissions(file1, allWrite, fs::perm_options::remove));
|
|
||||||
CHECK((fs::status(file1).permissions() & fs::perms::owner_write) != fs::perms::owner_write);
|
|
||||||
CHECK_NOTHROW(fs::permissions(file2, allWrite, fs::perm_options::add));
|
|
||||||
CHECK((fs::status(file2).permissions() & fs::perms::owner_write) == fs::perms::owner_write);
|
|
||||||
fs::copy_file(file1, file2, fs::copy_options::overwrite_existing);
|
|
||||||
CHECK((fs::status(file2).permissions() & fs::perms::owner_write) != fs::perms::owner_write);
|
|
||||||
CHECK_NOTHROW(fs::permissions(file1, allWrite, fs::perm_options::add));
|
|
||||||
CHECK_NOTHROW(fs::permissions(file2, allWrite, fs::perm_options::add));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.copy_symlink - copy_symlink", "[filesystem][operations][fs.op.copy_symlink]")
|
TEST_CASE("30.10.15.5 copy_symlink", "[filesystem][operations][fs.op.copy_symlink]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -1847,7 +1733,7 @@ TEST_CASE("fs.op.copy_symlink - copy_symlink", "[filesystem][operations][fs.op.c
|
|||||||
CHECK(ec);
|
CHECK(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.create_directories - create_directories", "[filesystem][operations][fs.op.create_directories]")
|
TEST_CASE("30.10.15.6 create_directories", "[filesystem][operations][fs.op.create_directories]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
fs::path p = t.path() / "testdir";
|
fs::path p = t.path() / "testdir";
|
||||||
@ -1894,7 +1780,7 @@ TEST_CASE("fs.op.create_directories - create_directories", "[filesystem][operati
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.create_directory - create_directory", "[filesystem][operations][fs.op.create_directory]")
|
TEST_CASE("30.10.15.7 create_directory", "[filesystem][operations][fs.op.create_directory]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
fs::path p = t.path() / "testdir";
|
fs::path p = t.path() / "testdir";
|
||||||
@ -1941,7 +1827,7 @@ TEST_CASE("fs.op.create_directory - create_directory", "[filesystem][operations]
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.create_directory_symlink - create_directory_symlink", "[filesystem][operations][fs.op.create_directory_symlink]")
|
TEST_CASE("30.10.15.8 create_directory_symlink", "[filesystem][operations][fs.op.create_directory_symlink]")
|
||||||
{
|
{
|
||||||
if (is_symlink_creation_supported()) {
|
if (is_symlink_creation_supported()) {
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
@ -1960,7 +1846,7 @@ TEST_CASE("fs.op.create_directory_symlink - create_directory_symlink", "[filesys
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.create_hard_link - create_hard_link", "[filesystem][operations][fs.op.create_hard_link]")
|
TEST_CASE("30.10.15.9 create_hard_link", "[filesystem][operations][fs.op.create_hard_link]")
|
||||||
{
|
{
|
||||||
#ifndef GHC_OS_WEB
|
#ifndef GHC_OS_WEB
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
@ -1979,7 +1865,7 @@ TEST_CASE("fs.op.create_hard_link - create_hard_link", "[filesystem][operations]
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.create_symlink - create_symlink", "[filesystem][operations][fs.op.create_symlink]")
|
TEST_CASE("30.10.15.10 create_symlink", "[filesystem][operations][fs.op.create_symlink]")
|
||||||
{
|
{
|
||||||
if (is_symlink_creation_supported()) {
|
if (is_symlink_creation_supported()) {
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
@ -1998,7 +1884,7 @@ TEST_CASE("fs.op.create_symlink - create_symlink", "[filesystem][operations][fs.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.current_path - current_path", "[filesystem][operations][fs.op.current_path]")
|
TEST_CASE("30.10.15.11 current_path", "[filesystem][operations][fs.op.current_path]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2013,7 +1899,7 @@ TEST_CASE("fs.op.current_path - current_path", "[filesystem][operations][fs.op.c
|
|||||||
CHECK(ec);
|
CHECK(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.equivalent - equivalent", "[filesystem][operations][fs.op.equivalent]")
|
TEST_CASE("30.10.15.12 equivalent", "[filesystem][operations][fs.op.equivalent]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
generateFile("foo", 1234);
|
generateFile("foo", 1234);
|
||||||
@ -2067,7 +1953,7 @@ TEST_CASE("fs.op.equivalent - equivalent", "[filesystem][operations][fs.op.equiv
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.exists - exists", "[filesystem][operations][fs.op.exists]")
|
TEST_CASE("30.10.15.13 exists", "[filesystem][operations][fs.op.exists]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2077,9 +1963,6 @@ TEST_CASE("fs.op.exists - exists", "[filesystem][operations][fs.op.exists]")
|
|||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
ec = std::error_code(42, std::system_category());
|
ec = std::error_code(42, std::system_category());
|
||||||
CHECK(!fs::exists("foo", ec));
|
CHECK(!fs::exists("foo", ec));
|
||||||
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
|
|
||||||
CHECK(!fs::exists(u8"foo"));
|
|
||||||
#endif
|
|
||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
ec.clear();
|
ec.clear();
|
||||||
CHECK(fs::exists(t.path()));
|
CHECK(fs::exists(t.path()));
|
||||||
@ -2095,7 +1978,7 @@ TEST_CASE("fs.op.exists - exists", "[filesystem][operations][fs.op.exists]")
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.file_size - file_size", "[filesystem][operations][fs.op.file_size]")
|
TEST_CASE("30.10.15.14 file_size", "[filesystem][operations][fs.op.file_size]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2117,16 +2000,7 @@ TEST_CASE("fs.op.file_size - file_size", "[filesystem][operations][fs.op.file_si
|
|||||||
ec.clear();
|
ec.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GHC_OS_WINDOWS
|
TEST_CASE("30.10.15.15 hard_link_count", "[filesystem][operations][fs.op.hard_link_count]")
|
||||||
static uintmax_t getHardlinkCount(const fs::path& p)
|
|
||||||
{
|
|
||||||
struct stat st = {};
|
|
||||||
auto rc = ::lstat(p.c_str(), &st);
|
|
||||||
return rc == 0 ? st.st_nlink : ~0u;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TEST_CASE("fs.op.hard_link_count - hard_link_count", "[filesystem][operations][fs.op.hard_link_count]")
|
|
||||||
{
|
{
|
||||||
#ifndef GHC_OS_WEB
|
#ifndef GHC_OS_WEB
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
@ -2141,9 +2015,9 @@ TEST_CASE("fs.op.hard_link_count - hard_link_count", "[filesystem][operations][f
|
|||||||
// unix/bsd/linux typically implements "."/".." as hardlinks
|
// unix/bsd/linux typically implements "."/".." as hardlinks
|
||||||
// so an empty dir has 2 (from parent and the ".") and
|
// so an empty dir has 2 (from parent and the ".") and
|
||||||
// adding a subdirectory adds one due to its ".."
|
// adding a subdirectory adds one due to its ".."
|
||||||
CHECK(fs::hard_link_count(t.path()) == getHardlinkCount(t.path()));
|
CHECK(fs::hard_link_count(t.path()) == 2);
|
||||||
fs::create_directory("dir");
|
fs::create_directory("dir");
|
||||||
CHECK(fs::hard_link_count(t.path()) == getHardlinkCount(t.path()));
|
CHECK(fs::hard_link_count(t.path()) == 3);
|
||||||
#endif
|
#endif
|
||||||
generateFile("foo");
|
generateFile("foo");
|
||||||
CHECK(fs::hard_link_count(t.path() / "foo") == 1);
|
CHECK(fs::hard_link_count(t.path() / "foo") == 1);
|
||||||
@ -2205,7 +2079,6 @@ public:
|
|||||||
|
|
||||||
fs::path character_path() const
|
fs::path character_path() const
|
||||||
{
|
{
|
||||||
#ifndef GHC_OS_SOLARIS
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
if (fs::exists("/dev/null", ec)) {
|
if (fs::exists("/dev/null", ec)) {
|
||||||
return "/dev/null";
|
return "/dev/null";
|
||||||
@ -2213,7 +2086,6 @@ public:
|
|||||||
else if (fs::exists("NUL", ec)) {
|
else if (fs::exists("NUL", ec)) {
|
||||||
return "NUL";
|
return "NUL";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return fs::path();
|
return fs::path();
|
||||||
}
|
}
|
||||||
fs::path temp_path() const { return _t.path(); }
|
fs::path temp_path() const { return _t.path(); }
|
||||||
@ -2224,7 +2096,7 @@ private:
|
|||||||
bool _hasSocket;
|
bool _hasSocket;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_block_file - is_block_file", "[filesystem][operations][fs.op.is_block_file]")
|
TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.16 is_block_file", "[filesystem][operations][fs.op.is_block_file]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(!fs::is_block_file("directory"));
|
CHECK(!fs::is_block_file("directory"));
|
||||||
@ -2253,7 +2125,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_block_file - is_block_file", "[fi
|
|||||||
CHECK(!fs::is_block_file(fs::file_status(fs::file_type::unknown)));
|
CHECK(!fs::is_block_file(fs::file_status(fs::file_type::unknown)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_character_file - is_character_file", "[filesystem][operations][fs.op.is_character_file]")
|
TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.17 is_character_file", "[filesystem][operations][fs.op.is_character_file]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(!fs::is_character_file("directory"));
|
CHECK(!fs::is_character_file("directory"));
|
||||||
@ -2282,7 +2154,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_character_file - is_character_fil
|
|||||||
CHECK(!fs::is_character_file(fs::file_status(fs::file_type::unknown)));
|
CHECK(!fs::is_character_file(fs::file_status(fs::file_type::unknown)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_directory - is_directory", "[filesystem][operations][fs.op.is_directory]")
|
TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.18 is_directory", "[filesystem][operations][fs.op.is_directory]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(fs::is_directory("directory"));
|
CHECK(fs::is_directory("directory"));
|
||||||
@ -2311,7 +2183,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_directory - is_directory", "[file
|
|||||||
CHECK(!fs::is_directory(fs::file_status(fs::file_type::unknown)));
|
CHECK(!fs::is_directory(fs::file_status(fs::file_type::unknown)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.is_empty - is_empty", "[filesystem][operations][fs.op.is_empty]")
|
TEST_CASE("30.10.15.19 is_empty", "[filesystem][operations][fs.op.is_empty]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2333,7 +2205,7 @@ TEST_CASE("fs.op.is_empty - is_empty", "[filesystem][operations][fs.op.is_empty]
|
|||||||
CHECK(ec);
|
CHECK(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_fifo - is_fifo", "[filesystem][operations][fs.op.is_fifo]")
|
TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.20 is_fifo", "[filesystem][operations][fs.op.is_fifo]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(!fs::is_fifo("directory"));
|
CHECK(!fs::is_fifo("directory"));
|
||||||
@ -2362,7 +2234,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_fifo - is_fifo", "[filesystem][op
|
|||||||
CHECK(!fs::is_fifo(fs::file_status(fs::file_type::unknown)));
|
CHECK(!fs::is_fifo(fs::file_status(fs::file_type::unknown)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_other - is_other", "[filesystem][operations][fs.op.is_other]")
|
TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.21 is_other", "[filesystem][operations][fs.op.is_other]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(!fs::is_other("directory"));
|
CHECK(!fs::is_other("directory"));
|
||||||
@ -2391,7 +2263,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_other - is_other", "[filesystem][
|
|||||||
CHECK(fs::is_other(fs::file_status(fs::file_type::unknown)));
|
CHECK(fs::is_other(fs::file_status(fs::file_type::unknown)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_regular_file - is_regular_file", "[filesystem][operations][fs.op.is_regular_file]")
|
TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.22 is_regular_file", "[filesystem][operations][fs.op.is_regular_file]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(!fs::is_regular_file("directory"));
|
CHECK(!fs::is_regular_file("directory"));
|
||||||
@ -2420,7 +2292,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_regular_file - is_regular_file",
|
|||||||
CHECK(!fs::is_regular_file(fs::file_status(fs::file_type::unknown)));
|
CHECK(!fs::is_regular_file(fs::file_status(fs::file_type::unknown)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_socket - is_socket", "[filesystem][operations][fs.op.is_socket]")
|
TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.23 is_socket", "[filesystem][operations][fs.op.is_socket]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(!fs::is_socket("directory"));
|
CHECK(!fs::is_socket("directory"));
|
||||||
@ -2449,7 +2321,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_socket - is_socket", "[filesystem
|
|||||||
CHECK(!fs::is_socket(fs::file_status(fs::file_type::unknown)));
|
CHECK(!fs::is_socket(fs::file_status(fs::file_type::unknown)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_symlink - is_symlink", "[filesystem][operations][fs.op.is_symlink]")
|
TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.24 is_symlink", "[filesystem][operations][fs.op.is_symlink]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(!fs::is_symlink("directory"));
|
CHECK(!fs::is_symlink("directory"));
|
||||||
@ -2492,7 +2364,7 @@ static fs::file_time_type timeFromString(const std::string& str)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("fs.op.last_write_time - last_write_time", "[filesystem][operations][fs.op.last_write_time]")
|
TEST_CASE("30.10.15.25 last_write_time", "[filesystem][operations][fs.op.last_write_time]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2527,7 +2399,7 @@ TEST_CASE("fs.op.last_write_time - last_write_time", "[filesystem][operations][f
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.permissions - permissions", "[filesystem][operations][fs.op.permissions]")
|
TEST_CASE("30.10.15.26 permissions", "[filesystem][operations][fs.op.permissions]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2535,13 +2407,8 @@ TEST_CASE("fs.op.permissions - permissions", "[filesystem][operations][fs.op.per
|
|||||||
auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write;
|
auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write;
|
||||||
CHECK_NOTHROW(fs::permissions("foo", allWrite, fs::perm_options::remove));
|
CHECK_NOTHROW(fs::permissions("foo", allWrite, fs::perm_options::remove));
|
||||||
CHECK((fs::status("foo").permissions() & fs::perms::owner_write) != fs::perms::owner_write);
|
CHECK((fs::status("foo").permissions() & fs::perms::owner_write) != fs::perms::owner_write);
|
||||||
#if !defined(GHC_OS_WINDOWS)
|
|
||||||
if (geteuid() != 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
CHECK_THROWS_AS(fs::resize_file("foo", 1024), fs::filesystem_error);
|
CHECK_THROWS_AS(fs::resize_file("foo", 1024), fs::filesystem_error);
|
||||||
CHECK(fs::file_size("foo") == 512);
|
CHECK(fs::file_size("foo") == 512);
|
||||||
}
|
|
||||||
CHECK_NOTHROW(fs::permissions("foo", fs::perms::owner_write, fs::perm_options::add));
|
CHECK_NOTHROW(fs::permissions("foo", fs::perms::owner_write, fs::perm_options::add));
|
||||||
CHECK((fs::status("foo").permissions() & fs::perms::owner_write) == fs::perms::owner_write);
|
CHECK((fs::status("foo").permissions() & fs::perms::owner_write) == fs::perms::owner_write);
|
||||||
CHECK_NOTHROW(fs::resize_file("foo", 2048));
|
CHECK_NOTHROW(fs::resize_file("foo", 2048));
|
||||||
@ -2552,7 +2419,7 @@ TEST_CASE("fs.op.permissions - permissions", "[filesystem][operations][fs.op.per
|
|||||||
CHECK_THROWS_AS(fs::permissions("bar", fs::perms::owner_write, static_cast<fs::perm_options>(0)), fs::filesystem_error);
|
CHECK_THROWS_AS(fs::permissions("bar", fs::perms::owner_write, static_cast<fs::perm_options>(0)), fs::filesystem_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.proximate - proximate", "[filesystem][operations][fs.op.proximate]")
|
TEST_CASE("30.10.15.27 proximate", "[filesystem][operations][fs.op.proximate]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK(fs::proximate("/a/d", "/a/b/c") == "../../d");
|
CHECK(fs::proximate("/a/d", "/a/b/c") == "../../d");
|
||||||
@ -2582,7 +2449,7 @@ TEST_CASE("fs.op.proximate - proximate", "[filesystem][operations][fs.op.proxima
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.read_symlink - read_symlink", "[filesystem][operations][fs.op.read_symlink]")
|
TEST_CASE("30.10.15.28 read_symlink", "[filesystem][operations][fs.op.read_symlink]")
|
||||||
{
|
{
|
||||||
if (is_symlink_creation_supported()) {
|
if (is_symlink_creation_supported()) {
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
@ -2598,7 +2465,7 @@ TEST_CASE("fs.op.read_symlink - read_symlink", "[filesystem][operations][fs.op.r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.relative - relative", "[filesystem][operations][fs.op.relative]")
|
TEST_CASE("30.10.15.29 relative", "[filesystem][operations][fs.op.relative]")
|
||||||
{
|
{
|
||||||
CHECK(fs::relative("/a/d", "/a/b/c") == "../../d");
|
CHECK(fs::relative("/a/d", "/a/b/c") == "../../d");
|
||||||
CHECK(fs::relative("/a/b/c", "/a/d") == "../b/c");
|
CHECK(fs::relative("/a/b/c", "/a/d") == "../b/c");
|
||||||
@ -2611,7 +2478,7 @@ TEST_CASE("fs.op.relative - relative", "[filesystem][operations][fs.op.relative]
|
|||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.remove - remove", "[filesystem][operations][fs.op.remove]")
|
TEST_CASE("30.10.15.30 remove", "[filesystem][operations][fs.op.remove]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2635,7 +2502,7 @@ TEST_CASE("fs.op.remove - remove", "[filesystem][operations][fs.op.remove]")
|
|||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.remove_all - remove_all", "[filesystem][operations][fs.op.remove_all]")
|
TEST_CASE("30.10.15.31 remove_all", "[filesystem][operations][fs.op.remove_all]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2651,15 +2518,11 @@ TEST_CASE("fs.op.remove_all - remove_all", "[filesystem][operations][fs.op.remov
|
|||||||
CHECK_NOTHROW(fs::remove_all("dir1/non-existing", ec));
|
CHECK_NOTHROW(fs::remove_all("dir1/non-existing", ec));
|
||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
CHECK(fs::remove_all("dir1/non-existing", ec) == 0);
|
CHECK(fs::remove_all("dir1/non-existing", ec) == 0);
|
||||||
if (is_symlink_creation_supported()) {
|
|
||||||
fs::create_directory_symlink("dir1", "dir1link");
|
|
||||||
CHECK(fs::remove_all("dir1link") == 1);
|
|
||||||
}
|
|
||||||
CHECK(fs::remove_all("dir1") == 5);
|
CHECK(fs::remove_all("dir1") == 5);
|
||||||
CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator());
|
CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.rename - rename", "[filesystem][operations][fs.op.rename]")
|
TEST_CASE("30.10.15.32 rename", "[filesystem][operations][fs.op.rename]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2683,7 +2546,7 @@ TEST_CASE("fs.op.rename - rename", "[filesystem][operations][fs.op.rename]")
|
|||||||
CHECK(!fs::exists("barfoo"));
|
CHECK(!fs::exists("barfoo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.resize_file - resize_file", "[filesystem][operations][fs.op.resize_file]")
|
TEST_CASE("30.10.15.33 resize_file", "[filesystem][operations][fs.op.resize_file]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2701,7 +2564,7 @@ TEST_CASE("fs.op.resize_file - resize_file", "[filesystem][operations][fs.op.res
|
|||||||
CHECK(!fs::exists("bar"));
|
CHECK(!fs::exists("bar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.space - space", "[filesystem][operations][fs.op.space]")
|
TEST_CASE("30.10.15.34 space", "[filesystem][operations][fs.op.space]")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
fs::space_info si;
|
fs::space_info si;
|
||||||
@ -2733,7 +2596,7 @@ TEST_CASE("fs.op.space - space", "[filesystem][operations][fs.op.space]")
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.status - status", "[filesystem][operations][fs.op.status]")
|
TEST_CASE("30.10.15.35 status", "[filesystem][operations][fs.op.status]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2761,7 +2624,7 @@ TEST_CASE("fs.op.status - status", "[filesystem][operations][fs.op.status]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.status_known - status_known", "[filesystem][operations][fs.op.status_known]")
|
TEST_CASE("30.10.15.36 status_known", "[filesystem][operations][fs.op.status_known]")
|
||||||
{
|
{
|
||||||
CHECK(!fs::status_known(fs::file_status()));
|
CHECK(!fs::status_known(fs::file_status()));
|
||||||
CHECK(fs::status_known(fs::file_status(fs::file_type::not_found)));
|
CHECK(fs::status_known(fs::file_status(fs::file_type::not_found)));
|
||||||
@ -2774,7 +2637,7 @@ TEST_CASE("fs.op.status_known - status_known", "[filesystem][operations][fs.op.s
|
|||||||
CHECK(fs::status_known(fs::file_status(fs::file_type::unknown)));
|
CHECK(fs::status_known(fs::file_status(fs::file_type::unknown)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.symlink_status - symlink_status", "[filesystem][operations][fs.op.symlink_status]")
|
TEST_CASE("30.10.15.37 symlink_status", "[filesystem][operations][fs.op.symlink_status]")
|
||||||
{
|
{
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -2801,7 +2664,7 @@ TEST_CASE("fs.op.symlink_status - symlink_status", "[filesystem][operations][fs.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.temp_dir_path - temporary_directory_path", "[filesystem][operations][fs.op.temp_dir_path]")
|
TEST_CASE("30.10.15.38 temporary_directory_path", "[filesystem][operations][fs.op.temp_dir_path]")
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
CHECK_NOTHROW(fs::exists(fs::temp_directory_path()));
|
CHECK_NOTHROW(fs::exists(fs::temp_directory_path()));
|
||||||
@ -2810,7 +2673,7 @@ TEST_CASE("fs.op.temp_dir_path - temporary_directory_path", "[filesystem][operat
|
|||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("fs.op.weakly_canonical - weakly_canonical", "[filesystem][operations][fs.op.weakly_canonical]")
|
TEST_CASE("30.10.15.39 weakly_canonical", "[filesystem][operations][fs.op.weakly_canonical]")
|
||||||
{
|
{
|
||||||
INFO("This might fail on std::implementations that return fs::current_path() for fs::canonical(\"\")");
|
INFO("This might fail on std::implementations that return fs::current_path() for fs::canonical(\"\")");
|
||||||
CHECK(fs::weakly_canonical("") == ".");
|
CHECK(fs::weakly_canonical("") == ".");
|
||||||
@ -2849,40 +2712,33 @@ TEST_CASE("fs.op.weakly_canonical - weakly_canonical", "[filesystem][operations]
|
|||||||
|
|
||||||
TEST_CASE("std::string_view support", "[filesystem][fs.string_view]")
|
TEST_CASE("std::string_view support", "[filesystem][fs.string_view]")
|
||||||
{
|
{
|
||||||
#if defined(GHC_HAS_STD_STRING_VIEW) || defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
|
#if __cpp_lib_string_view
|
||||||
|
|
||||||
#if defined(GHC_HAS_STD_STRING_VIEW)
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
using string_view = std::string_view;
|
|
||||||
using wstring_view = std::wstring_view;
|
|
||||||
#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
|
|
||||||
using string_view = std::experimental::string_view;
|
|
||||||
using wstring_view = std::experimental::wstring_view;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string p("foo/bar");
|
std::string p("foo/bar");
|
||||||
string_view sv(p);
|
std::string_view sv(p);
|
||||||
CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar");
|
CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar");
|
||||||
fs::path p2("fo");
|
fs::path p2("fo");
|
||||||
p2 += string_view("o");
|
p2 += std::string_view("o");
|
||||||
CHECK(p2 == "foo");
|
CHECK(p2 == "foo");
|
||||||
CHECK(p2.compare(string_view("foo")) == 0);
|
CHECK(p2.compare(std::string_view("foo")) == 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto p = fs::path{"XYZ"};
|
auto p = fs::path{"XYZ"};
|
||||||
p /= string_view("Appendix");
|
p /= std::string_view("Appendix");
|
||||||
CHECK(p == "XYZ/Appendix");
|
CHECK(p == "XYZ/Appendix");
|
||||||
}
|
}
|
||||||
|
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
|
||||||
{
|
{
|
||||||
std::wstring p(L"foo/bar");
|
std::wstring p(L"foo/bar");
|
||||||
wstring_view sv(p);
|
std::wstring_view sv(p);
|
||||||
CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar");
|
CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar");
|
||||||
fs::path p2(L"fo");
|
fs::path p2(L"fo");
|
||||||
p2 += wstring_view(L"o");
|
p2 += std::wstring_view(L"o");
|
||||||
CHECK(p2 == "foo");
|
CHECK(p2 == "foo");
|
||||||
CHECK(p2.compare(wstring_view(L"foo")) == 0);
|
CHECK(p2.compare(std::wstring_view(L"foo")) == 0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
WARN("std::string_view specific tests are empty without std::string_view.");
|
WARN("std::string_view specific tests are empty without std::string_view.");
|
||||||
@ -2902,15 +2758,13 @@ TEST_CASE("Windows: Long filename support", "[filesystem][path][fs.path.win.long
|
|||||||
CHECK_NOTHROW(fs::create_directory(dir));
|
CHECK_NOTHROW(fs::create_directory(dir));
|
||||||
CHECK(fs::exists(dir));
|
CHECK(fs::exists(dir));
|
||||||
generateFile(dir / "f0");
|
generateFile(dir / "f0");
|
||||||
REQUIRE(fs::exists(dir / "f0"));
|
|
||||||
}
|
|
||||||
CHECK(c > 'Z');
|
|
||||||
fs::remove_all(fs::current_path() / std::string(16, 'A'));
|
|
||||||
CHECK(!fs::exists(fs::current_path() / std::string(16, 'A')));
|
|
||||||
CHECK_NOTHROW(fs::create_directories(dir));
|
|
||||||
CHECK(fs::exists(dir));
|
|
||||||
generateFile(dir / "f0");
|
|
||||||
CHECK(fs::exists(dir / "f0"));
|
CHECK(fs::exists(dir / "f0"));
|
||||||
|
auto native = dir.u8string();
|
||||||
|
if (native.substr(0, 4) == u8"\\\\?\\") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECK(c <= 'Z');
|
||||||
#else
|
#else
|
||||||
WARN("Windows specific tests are empty on non-Windows systems.");
|
WARN("Windows specific tests are empty on non-Windows systems.");
|
||||||
#endif
|
#endif
|
||||||
@ -2943,8 +2797,8 @@ TEST_CASE("Windows: path namespace handling", "[filesystem][path][fs.path.win.na
|
|||||||
{R"(\\?\C:\Windows\notepad.exe)", R"(\\?\C:\Windows\notepad.exe)", "\\\\?", "\\\\?\\", "//?,/,C:,Windows,notepad.exe"},
|
{R"(\\?\C:\Windows\notepad.exe)", R"(\\?\C:\Windows\notepad.exe)", "\\\\?", "\\\\?\\", "//?,/,C:,Windows,notepad.exe"},
|
||||||
{R"(\??\C:\Windows\notepad.exe)", R"(\??\C:\Windows\notepad.exe)", "\\??", "\\??\\", "/??,/,C:,Windows,notepad.exe"},
|
{R"(\??\C:\Windows\notepad.exe)", R"(\??\C:\Windows\notepad.exe)", "\\??", "\\??\\", "/??,/,C:,Windows,notepad.exe"},
|
||||||
#else
|
#else
|
||||||
{R"(\\?\C:\Windows\notepad.exe)", R"(\\?\C:\Windows\notepad.exe)", "C:", "C:\\", "//?/,C:,/,Windows,notepad.exe"},
|
{R"(\\?\C:\Windows\notepad.exe)", R"(C:\Windows\notepad.exe)", "C:", "C:\\", "C:,/,Windows,notepad.exe"},
|
||||||
{R"(\??\C:\Windows\notepad.exe)", R"(\??\C:\Windows\notepad.exe)", "C:", "C:\\", "/?\?/,C:,/,Windows,notepad.exe"},
|
{R"(\??\C:\Windows\notepad.exe)", R"(C:\Windows\notepad.exe)", "C:", "C:\\", "C:,/,Windows,notepad.exe"},
|
||||||
#endif
|
#endif
|
||||||
{R"(\\.\C:\Windows\notepad.exe)", R"(\\.\C:\Windows\notepad.exe)", "\\\\.", "\\\\.\\", "//.,/,C:,Windows,notepad.exe"},
|
{R"(\\.\C:\Windows\notepad.exe)", R"(\\.\C:\Windows\notepad.exe)", "\\\\.", "\\\\.\\", "//.,/,C:,Windows,notepad.exe"},
|
||||||
{R"(\\?\HarddiskVolume1\Windows\notepad.exe)", R"(\\?\HarddiskVolume1\Windows\notepad.exe)", "\\\\?", "\\\\?\\", "//?,/,HarddiskVolume1,Windows,notepad.exe"},
|
{R"(\\?\HarddiskVolume1\Windows\notepad.exe)", R"(\\?\HarddiskVolume1\Windows\notepad.exe)", "\\\\?", "\\\\?\\", "//?,/,HarddiskVolume1,Windows,notepad.exe"},
|
||||||
@ -2961,7 +2815,6 @@ TEST_CASE("Windows: path namespace handling", "[filesystem][path][fs.path.win.na
|
|||||||
INFO("Used path: " + ti._path);
|
INFO("Used path: " + ti._path);
|
||||||
auto p = fs::path(ti._path);
|
auto p = fs::path(ti._path);
|
||||||
CHECK(p.string() == ti._string);
|
CHECK(p.string() == ti._string);
|
||||||
CHECK(p.is_absolute());
|
|
||||||
CHECK(p.root_name().string() == ti._rootName);
|
CHECK(p.root_name().string() == ti._rootName);
|
||||||
CHECK(p.root_path().string() == ti._rootPath);
|
CHECK(p.root_path().string() == ti._rootPath);
|
||||||
CHECK(iterateResult(p) == ti._iterateResult);
|
CHECK(iterateResult(p) == ti._iterateResult);
|
||||||
@ -2970,31 +2823,3 @@ TEST_CASE("Windows: path namespace handling", "[filesystem][path][fs.path.win.na
|
|||||||
WARN("Windows specific tests are empty on non-Windows systems.");
|
WARN("Windows specific tests are empty on non-Windows systems.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Windows: Mapped folders handling ", "[filesystem][fs.win][fs.win.mapped]")
|
|
||||||
{
|
|
||||||
#ifdef GHC_OS_WINDOWS
|
|
||||||
// this test expects a mapped volume on C:\\fs-test as is the case on the development test system
|
|
||||||
// does nothing on other systems
|
|
||||||
if (fs::exists("C:\\fs-test")) {
|
|
||||||
CHECK(fs::canonical("C:\\fs-test\\Test.txt").string() == "C:\\fs-test\\Test.txt");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
WARN("Windows specific tests are empty on non-Windows systems.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Windows: Deletion of Read-only Files", "[filesystem][fs.win][fs.win.remove]")
|
|
||||||
{
|
|
||||||
#ifdef GHC_OS_WINDOWS
|
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
|
||||||
std::error_code ec;
|
|
||||||
generateFile("foo", 512);
|
|
||||||
auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write;
|
|
||||||
CHECK_NOTHROW(fs::permissions("foo", allWrite, fs::perm_options::remove));
|
|
||||||
CHECK_NOTHROW(fs::remove("foo"));
|
|
||||||
CHECK(!fs::exists("foo"));
|
|
||||||
#else
|
|
||||||
WARN("Windows specific tests are empty on non-Windows systems.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
// where exactly one cpp includes fs_impl.hpp and all others use
|
// where exactly one cpp includes fs_impl.hpp and all others use
|
||||||
// fs_fwd.hpp (to test this with maximum functionality, the unit tests
|
// fs_fwd.hpp (to test this with maximum functionality, the unit tests
|
||||||
// are included here, signaling they should only include the fs_fwd.hpp)
|
// are included here, signaling they should only include the fs_fwd.hpp)
|
||||||
|
#define NOMINMAX
|
||||||
#include <ghc/fs_impl.hpp>
|
#include <ghc/fs_impl.hpp>
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
#include <ghc/filesystem.hpp>
|
#include <ghc/filesystem.hpp>
|
||||||
namespace fs = ghc::filesystem;
|
namespace fs = ghc::filesystem;
|
||||||
|
|
||||||
// This test and the one in multi2.cpp doesn't actually test relevant functionality,
|
// This test and the one in multi2.cpp doesn't actualy test relevant functionality,
|
||||||
// it is just used to check that it is possible to include filesystem.h in multiple
|
// it is just used to check that it is possible to include filesystem.h in multiple
|
||||||
// source files.
|
// source files.
|
||||||
TEST_CASE("Multifile-test 1", "[multi]")
|
TEST_CASE("Multifile-test 1", "[multi]")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user