Allow iteration while exceptions are disabled and reactivate proximate(...) for that case

This commit is contained in:
Steffen Schümann 2026-07-10 17:01:36 +02:00
parent 0e72911ba0
commit 8741115872
4 changed files with 81 additions and 20 deletions

View File

@ -1,8 +1,5 @@
cmake_minimum_required(VERSION 3.7.2)
project(
ghcfilesystem,
VERSION 1.5.15
)
project(ghcfilesystem VERSION 1.5.15)
if (POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)

View File

@ -181,6 +181,7 @@
#include <clocale>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <fstream>
#include <functional>
#include <memory>
@ -932,20 +933,16 @@ public:
directory_iterator& operator=(directory_iterator&& rhs) noexcept;
const directory_entry& operator*() const;
const directory_entry* operator->() const;
#ifdef GHC_WITH_EXCEPTIONS
directory_iterator& operator++();
#endif
directory_iterator& increment(std::error_code& ec) noexcept;
// other members as required by [input.iterators]
#ifdef GHC_WITH_EXCEPTIONS
proxy operator++(int)
{
proxy p{**this};
++*this;
return p;
}
#endif
bool operator==(const directory_iterator& rhs) const;
bool operator!=(const directory_iterator& rhs) const;
@ -992,9 +989,7 @@ public:
// [fs.rec.dir.itr.members] modifiers recursive_directory_iterator&
recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs);
recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept;
#ifdef GHC_WITH_EXCEPTIONS
recursive_directory_iterator& operator++();
#endif
recursive_directory_iterator& increment(std::error_code& ec) noexcept;
#ifdef GHC_WITH_EXCEPTIONS
@ -1004,14 +999,12 @@ public:
void disable_recursion_pending();
// other members as required by [input.iterators]
#ifdef GHC_WITH_EXCEPTIONS
directory_iterator::proxy operator++(int)
{
directory_iterator::proxy proxy{**this};
++*this;
return proxy;
}
#endif
bool operator==(const recursive_directory_iterator& rhs) const;
bool operator!=(const recursive_directory_iterator& rhs) const;
@ -4751,7 +4744,6 @@ GHC_INLINE void permissions(const path& p, perms prms, perm_options opts, std::e
#endif
}
#ifdef GHC_WITH_EXCEPTIONS
GHC_INLINE path proximate(const path& p, std::error_code& ec)
{
auto cp = current_path(ec);
@ -4760,7 +4752,6 @@ GHC_INLINE path proximate(const path& p, std::error_code& ec)
}
return path();
}
#endif
#ifdef GHC_WITH_EXCEPTIONS
GHC_INLINE path proximate(const path& p, const path& base)
@ -5860,17 +5851,19 @@ GHC_INLINE const directory_entry* directory_iterator::operator->() const
return &_impl->_dir_entry;
}
#ifdef GHC_WITH_EXCEPTIONS
GHC_INLINE directory_iterator& directory_iterator::operator++()
{
std::error_code ec;
_impl->increment(ec);
if (ec) {
#ifdef GHC_WITH_EXCEPTIONS
throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_entry._path, ec);
#else
std::terminate();
#endif
}
return *this;
}
#endif
GHC_INLINE directory_iterator& directory_iterator::increment(std::error_code& ec) noexcept
{
@ -5986,17 +5979,19 @@ GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator=
return *this;
}
#ifdef GHC_WITH_EXCEPTIONS
GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator++()
{
std::error_code ec;
increment(ec);
if (ec) {
#ifdef GHC_WITH_EXCEPTIONS
throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_iter_stack.empty() ? path() : _impl->_dir_iter_stack.top()->path(), ec);
#else
std::terminate();
#endif
}
return *this;
}
#endif
GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::increment(std::error_code& ec) noexcept
{

View File

@ -98,8 +98,12 @@ endif()
add_test(fwd_impl_test fwd_impl_test)
add_executable(exception exception.cpp)
if(NOT MSVC)
if(MSVC)
target_compile_options(exception PRIVATE /EHs-c-)
target_compile_definitions(exception PRIVATE _HAS_EXCEPTIONS=0)
else()
target_compile_options(exception PRIVATE -fno-exceptions)
endif()
target_include_directories(exception PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include)
SetTestCompileOptions(exception)
add_test(NAME no_exception_test COMMAND exception "${CMAKE_CURRENT_SOURCE_DIR}/exception.cpp")

View File

@ -1,5 +1,70 @@
#include <ghc/filesystem.hpp>
int main() {
#ifdef GHC_WITH_EXCEPTIONS
#error "This test must be compiled without exception support"
#endif
int main(int argc, char** argv)
{
namespace fs = ghc::filesystem;
if (argc != 2) {
return 1;
}
const fs::path regular_file(argv[1]);
const fs::path test_directory = regular_file.parent_path();
std::error_code ec;
const fs::path proximate = fs::proximate(test_directory, ec);
if (ec || proximate.empty()) {
return 2;
}
fs::directory_iterator invalid_iter(regular_file, ec);
if (!ec || invalid_iter != fs::directory_iterator()) {
return 3;
}
ec.clear();
fs::recursive_directory_iterator invalid_recursive_iter(regular_file, ec);
if (!ec || invalid_recursive_iter != fs::recursive_directory_iterator()) {
return 4;
}
ec.clear();
fs::directory_iterator iter(test_directory, ec);
if (ec) {
return 5;
}
if (iter != fs::directory_iterator()) {
iter++;
}
for (; iter != fs::directory_iterator(); ++iter) {
}
for (const auto& entry : fs::directory_iterator(test_directory, ec)) {
(void)entry;
}
if (ec) {
return 6;
}
fs::recursive_directory_iterator recursive_iter(test_directory, ec);
if (ec) {
return 7;
}
if (recursive_iter != fs::recursive_directory_iterator()) {
recursive_iter++;
}
for (; recursive_iter != fs::recursive_directory_iterator(); ++recursive_iter) {
}
for (const auto& entry : fs::recursive_directory_iterator(test_directory, ec)) {
(void)entry;
}
if (ec) {
return 8;
}
return 0;
}