Skip to content

Commit

Permalink
Bump min C++ standard for LLFIO to C++ 17. Before anyone complains,
Browse files Browse the repository at this point in the history
this has been advertised for a couple of years now in compiler
diagnostics that support for non-17 `<filesystem>` was deprecated
and would be going away. It has now gone away. Please use a LLFIO
from before year 2025 if you want `<filesystem>` or
`<memory_resource>` polyfill support.
  • Loading branch information
ned14 committed Feb 5, 2025
1 parent 6e6029e commit 9ba669e
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 310 deletions.
3 changes: 1 addition & 2 deletions Build.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ These compilers and OSs are regularly tested by CI:
- Visual Studio on Windows

Other compilers, architectures and OSs may work, but are not tested regularly.
You will need a working [Filesystem TS](https://en.cppreference.com/w/cpp/experimental/fs)
implementation in your STL, and at least C++ 14.
You will need a working Filesystem implementation in your STL, and at least C++ 17.

LLFIO has your choice of header-only, static library, and shared library build modes.
Note that on Microsoft Windows, the default header only configuration is unsafe
Expand Down
153 changes: 18 additions & 135 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -183,33 +183,13 @@ endif()
include(QuickCppLibApplyDefaultDefinitions)

# Set the C++ features this library requires
all_compile_features(PUBLIC
# cxx_exceptions ## Annoyingly not supported by cmake 3.6
cxx_alias_templates
cxx_variadic_templates
cxx_noexcept
cxx_constexpr
cxx_lambda_init_captures
cxx_attributes
cxx_generic_lambdas
)
if(NOT MSVC OR CMAKE_VERSION VERSION_GREATER 3.59)
all_compile_features(PUBLIC
cxx_variable_templates
)
endif()
all_compile_features(PUBLIC cxx_std_17)
set(check_cxx_source_linkage_flags)
# If on VS2019 16.3 or later, or on Apple, we require C++ 17
if((MSVC AND MSVC_VERSION VERSION_GREATER_EQUAL 1923) OR APPLE)
all_compile_features(PUBLIC
cxx_std_17
)
if(NOT CMAKE_CXX_STANDARD)
if(MSVC)
set(check_cxx_source_linkage_flags /std:c++17)
else()
set(check_cxx_source_linkage_flags -std=c++17)
endif()
if(NOT CMAKE_CXX_STANDARD)
if(MSVC)
set(check_cxx_source_linkage_flags /std:c++17)
else()
set(check_cxx_source_linkage_flags -std=c++17)
endif()
endif()
# Set the library dependencies this library has
Expand Down Expand Up @@ -264,93 +244,7 @@ int main() {
}
" CXX_HAS_CXX17_FILESYSTEM)
if(NOT CXX_HAS_CXX17_FILESYSTEM)
check_cxx_source_linkage("
#include <experimental/filesystem>
int main() {
try { return std::experimental::filesystem::path(\"hi\").empty(); } catch(std::experimental::filesystem::filesystem_error) { return 1; }
}
" CXX_HAS_CXX_EXPERIMENTAL_FILESYSTEM)
endif()
if(NOT CXX_HAS_CXX17_FILESYSTEM AND NOT CXX_HAS_CXX_EXPERIMENTAL_FILESYSTEM)
indented_message(STATUS "NOTE: Standard <filesystem> not found in the current compiler configuration (try forcing C++ 17 or later?), attempting to figure out what <experimental/filesystem> linker flags to use for this STL ...")
# Are we on libstdc++ or libc++?
check_cxx_source_compiles("
#include <iostream>
int main() {
#ifdef __GLIBCXX__
std::cout << \"hi\";
return 0;
#else
return i am not a number;
#endif
}
" CXX_IS_USING_LIBSTDCXX)
check_cxx_source_compiles("
#include <iostream>
int main() {
#ifdef _LIBCPP_VERSION
std::cout << \"hi\";
return 0;
#else
return i am not a number;
#endif
}
" CXX_IS_USING_LIBCXX)
if(NOT CXX_IS_USING_LIBSTDCXX AND NOT CXX_IS_USING_LIBCXX)
indented_message(FATAL_ERROR "FATAL: <filesystem> is not available, and neither libstdc++ nor libc++ STLs will link a program")
endif()
set(stl_filesystem_link_flags)
# If on libstdc++, we need to link in stdc++fs for experimental filesystem
if(CXX_IS_USING_LIBSTDCXX)
find_library(libstdcxx_stdcxxfs stdc++fs)
if(libstdcxx_stdcxxfs MATCHES "NOTFOUND")
set(libstdcxx_stdcxxfs -lstdc++fs)
endif()
all_link_libraries(PUBLIC ${libstdcxx_stdcxxfs})
list(APPEND stl_filesystem_link_flags ${libstdcxx_stdcxxfs})
endif()
# If on libc++, we may need to link in c++fs or c++experimental for experimental filesystem
if(CXX_IS_USING_LIBCXX)
find_library(libcxx_cxxfs c++fs)
find_library(libcxx_cxxexperimental c++experimental)
if(libcxx_cxxfs MATCHES "NOTFOUND" AND libcxx_cxxexperimental MATCHES "NOTFOUND")
# I guess default to forcing libc++experimental?
set(libcxx_cxxexperimental -lc++experimental)
endif()
if(NOT libcxx_cxxfs MATCHES "NOTFOUND")
all_link_libraries(PUBLIC ${libcxx_cxxfs})
list(APPEND stl_filesystem_link_flags ${libcxx_cxxfs})
endif()
if(NOT libcxx_cxxexperimental MATCHES "NOTFOUND")
all_link_libraries(PUBLIC ${libcxx_cxxexperimental})
list(APPEND stl_filesystem_link_flags ${libcxx_cxxexperimental})
endif()
# Disable the irritating warnings
all_compile_definitions(PUBLIC _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_FILESYSTEM=1)
endif()
function(check_stl_filesystem_link_flags)
indented_message(STATUS "NOTE: Using STL link flags '${ARGN}'")
set(CMAKE_REQUIRED_LIBRARIES ${ARGN})
check_cxx_source_linkage("
#include <filesystem>
int main() {
try { return std::filesystem::path(\"hi\").empty(); } catch(std::filesystem::filesystem_error) { return 1; }
}
" CXX_HAS_CXX_FILESYSTEM_AFTER_FLAGS)
check_cxx_source_linkage("
#include <experimental/filesystem>
int main() {
try { return std::experimental::filesystem::path(\"hi\").empty(); } catch(std::experimental::filesystem::filesystem_error) { return 1; }
}
" CXX_HAS_CXX_EXPERIMENTAL_FILESYSTEM_AFTER_FLAGS)
if(NOT CXX_HAS_CXX_FILESYSTEM_AFTER_FLAGS AND NOT CXX_HAS_CXX_EXPERIMENTAL_FILESYSTEM_AFTER_FLAGS)
indented_message(FATAL_ERROR "FATAL: After probing multiple configurations, still cannot compile and link a <filesystem> or <experimental/filesystem> based program! Please adjust the configuration and/or install missing dependencies.")
endif()
endfunction()
check_stl_filesystem_link_flags(${stl_filesystem_link_flags})
if(NOT CXX_HAS_CXX_FILESYSTEM_AFTER_FLAGS AND CXX_HAS_CXX_EXPERIMENTAL_FILESYSTEM_AFTER_FLAGS)
all_compile_definitions(PUBLIC LLFIO_FORCE_EXPERIMENTAL_FILESYSTEM=1 KERNELTEST_FORCE_EXPERIMENTAL_FILESYSTEM=1)
endif()
indented_message(FATAL_ERROR "FATAL: C++ 17 <filesystem> is not available, use a LLFIO from before year 2025 if you want legacy <filesystem> polyfill support")
endif()
if(LLFIO_FORCE_DYNAMIC_THREAD_POOL_GROUP_OFF)
all_compile_definitions(PUBLIC LLFIO_EXCLUDE_DYNAMIC_THREAD_POOL_GROUP=1)
Expand Down Expand Up @@ -424,18 +318,7 @@ foreach(special ${SPECIAL_BUILDS})
target_compile_definitions(llfio_dl-${special} PRIVATE LLFIO_SOURCE=1 LLFIO_DYN_LINK=1)
endforeach()
if(TARGET llfio-example_single-header)
set(compiler_has_cxx_17 0)
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
if(feature STREQUAL "cxx_std_17")
set(compiler_has_cxx_17 1)
endif()
endforeach()
# The single header test requires C++ 17
if(compiler_has_cxx_17)
target_compile_features(llfio-example_single-header PRIVATE cxx_std_17)
else()
set_target_properties(llfio-example_single-header PROPERTIES EXCLUDE_FROM_ALL ON EXCLUDE_FROM_DEFAULT_BUILD ON)
endif()
target_compile_features(llfio-example_single-header PRIVATE cxx_std_17)
endif()

if(NOT llfio_IS_DEPENDENCY AND (NOT DEFINED BUILD_TESTING OR BUILD_TESTING))
Expand Down Expand Up @@ -546,29 +429,29 @@ if(NOT llfio_IS_DEPENDENCY AND (NOT DEFINED BUILD_TESTING OR BUILD_TESTING))
if(UNIT_TESTS_CXX_VERSION STREQUAL "latest")
set(LATEST_CXX_FEATURE)
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
if(feature STREQUAL "cxx_std_23")
if(feature STREQUAL "cxx_std_26")
if(NOT MSVC OR MSVC_VERSION VERSION_GREATER_EQUAL 1930)
set(LATEST_CXX_FEATURE "cxx_std_23")
indented_message(STATUS "NOTE: This compiler claims to support C++ 23, enabling for header-only unit test suite")
set(LATEST_CXX_FEATURE "cxx_std_26")
indented_message(STATUS "NOTE: This compiler claims to support C++ 26, enabling for header-only unit test suite")
endif()
endif()
endforeach()
if(NOT LATEST_CXX_FEATURE)
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
if(feature STREQUAL "cxx_std_20")
if(feature STREQUAL "cxx_std_23")
if(NOT MSVC OR MSVC_VERSION VERSION_GREATER_EQUAL 1930)
set(LATEST_CXX_FEATURE "cxx_std_20")
indented_message(STATUS "NOTE: This compiler claims to support C++ 20, enabling for header-only unit test suite")
set(LATEST_CXX_FEATURE "cxx_std_23")
indented_message(STATUS "NOTE: This compiler claims to support C++ 23, enabling for header-only unit test suite")
endif()
endif()
endforeach()
endif()
if(NOT LATEST_CXX_FEATURE)
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
if(feature STREQUAL "cxx_std_17")
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0")
set(LATEST_CXX_FEATURE "cxx_std_17")
indented_message(STATUS "NOTE: This compiler claims to support C++ 17, enabling for header-only unit test suite")
if(feature STREQUAL "cxx_std_20")
if(NOT MSVC OR MSVC_VERSION VERSION_GREATER_EQUAL 1930)
set(LATEST_CXX_FEATURE "cxx_std_20")
indented_message(STATUS "NOTE: This compiler claims to support C++ 20, enabling for header-only unit test suite")
endif()
endif()
endforeach()
Expand Down
9 changes: 3 additions & 6 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,12 @@ as Intel Optane.

It is a complete rewrite after a Boost peer review in August 2015. LLFIO is the
reference implementation for these C++ standardisations:
- `llfio::path_view` is expected to enter the C++ 26 standard ([P1030](https://wg21.link/p1030)).
- `llfio::file_handle` and `llfio::mapped_file_handle` are on track for entering the C++ 26 standard ([P1883](https://wg21.link/p1883)).
- `llfio::path_view` is expected to enter the C++ 29 standard ([P1030](https://wg21.link/p1030)).

Other characteristics:
- Portable to any conforming C++ 14 compiler with a working Filesystem TS in its STL.
- Note that VS2019 16.3 and libc++ 11 dropped support for Filesystem in C++ 14, so for those LLFIO's cmake forces on C++ 17.
- Portable to any conforming C++ 17 compiler with a working Filesystem in its STL.
- Fully clean with C++ 20.
- Will make use of any Coroutines, Concepts, Span, Byte etc if you have them, otherwise swaps in C++ 14 compatible alternatives.
- NOTE that Ubuntu 18.04's libstdc++ 9 does not currently provide symbols for `<codecvt>` if you are building in C++ 20, so linking LLFIO programs on libstdc++ on that Linux if in C++ 20 will fail. Either use a different STL, manually rebuild libstdc++, or use C++ 17.
- Will make use of any Coroutines, Concepts, Span, Byte etc if you have them, otherwise swaps in C++ 17 compatible alternatives.
- Aims to support Microsoft Windows, Linux, Android, iOS, Mac OS and FreeBSD.
- Best effort to support older kernels up to their EOL (as of July 2020: >= Windows 8.1, >= Linux 2.6.32 (RHEL EOL), >= Mac OS 10.13, >= FreeBSD 11).
- Original error code is always preserved, even down to the original NT kernel error code if a NT kernel API was used.
Expand Down
2 changes: 1 addition & 1 deletion example/wg21_path_view_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Traversal test for path_view (longer paths) ...
#include "../include/llfio.hpp"
#include "llfio/v2.0/directory_handle.hpp"

#if !defined(_WIN32) && (__cplusplus >= 201700L || _HAS_CXX17)
#if !defined(_WIN32)

#include <atomic>
#include <chrono>
Expand Down
95 changes: 15 additions & 80 deletions include/llfio/v2.0/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,32 +135,15 @@ Distributed under the Boost Software License, Version 1.0.
#include "quickcpplib/cpp_feature.h"

#ifndef STANDARDESE_IS_IN_THE_HOUSE
#ifndef __cpp_alias_templates
#error LLFIO needs template alias support in the compiler
#endif
#ifndef __cpp_variadic_templates
#error LLFIO needs variadic template support in the compiler
#endif
#if __cpp_constexpr < 201304L && !defined(_MSC_VER)
#error LLFIO needs relaxed constexpr (C++ 14) support in the compiler
#endif
#ifndef __cpp_init_captures
#error LLFIO needs lambda init captures support in the compiler (C++ 14)
#endif
#ifndef __cpp_attributes
#error LLFIO needs attributes support in the compiler
#endif
#ifndef __cpp_variable_templates
#error LLFIO needs variable template support in the compiler
#endif
#ifndef __cpp_generic_lambdas
#error LLFIO needs generic lambda support in the compiler
#if !(_HAS_CXX17 || __cplusplus >= 201700)
#error "LLFIO needs a minimum of C++ 17 support in the compiler"
#endif
#ifdef __has_include
// clang-format off
#if !__has_include(<filesystem>) && !__has_include(<experimental/filesystem>)
// clang-format on
#error LLFIO needs an implementation of the Filesystem TS in the standard library
#if !__has_include(<filesystem>)
#error "LLFIO needs an implementation of C++ 17 <filesystem> in the standard library"
#endif
#if !__has_include(<memory_resource>)
#error "LLFIO needs an implementation of C++ 17 <memory_resource> in the standard library"
#endif
#endif
#endif
Expand Down Expand Up @@ -242,60 +225,11 @@ LLFIO_V2_NAMESPACE_END
#endif
#include "quickcpplib/utils/thread.hpp"
// Bring in filesystem
#if defined(__has_include)
// clang-format off
#if !LLFIO_FORCE_EXPERIMENTAL_FILESYSTEM && __has_include(<filesystem>) && (__cplusplus >= 201700 || _HAS_CXX17)
#define LLFIO_USING_STD_FILESYSTEM 1
#include <filesystem>
LLFIO_V2_NAMESPACE_BEGIN
namespace filesystem = std::filesystem;
LLFIO_V2_NAMESPACE_END
// C++ 14 filesystem support was dropped in VS2019 16.3
// C++ 14 filesystem support was dropped in LLVM 11
#elif __has_include(<experimental/filesystem>) && (!defined(_MSC_VER) || _MSC_VER < 1923) && (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION < 11000)
#define LLFIO_USING_EXPERIMENTAL_FILESYSTEM 1
#include <experimental/filesystem>
LLFIO_V2_NAMESPACE_BEGIN
namespace filesystem = std::experimental::filesystem;
LLFIO_V2_NAMESPACE_END
#elif !LLFIO_FORCE_EXPERIMENTAL_FILESYSTEM && __has_include(<filesystem>)
#if defined(_MSC_VER) && _MSC_VER >= 1923
#error MSVC dropped support for C++ 14 <filesystem> from VS2019 16.3 onwards. Please enable C++ 17 or later.
#endif
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 11000
#error libc++ dropped support for C++ 14 <filesystem> from LLVM 11 onwards. Please enable C++ 17 or later.
#endif
#define LLFIO_USING_STD_FILESYSTEM 1
#include <filesystem>
LLFIO_V2_NAMESPACE_BEGIN
namespace filesystem = std::filesystem;
LLFIO_V2_NAMESPACE_END
#endif
#elif __PCPP_ALWAYS_TRUE__
#define LLFIO_USING_STD_FILESYSTEM 1
#include <filesystem>
LLFIO_V2_NAMESPACE_BEGIN
namespace filesystem = std::filesystem;
LLFIO_V2_NAMESPACE_END
// clang-format on
#elif defined(_MSC_VER)
#define LLFIO_USING_STD_FILESYSTEM 1
#include <filesystem>
LLFIO_V2_NAMESPACE_BEGIN
namespace filesystem = std::experimental::filesystem;
LLFIO_V2_NAMESPACE_END
#else
#error No <filesystem> implementation found
#endif
#if LLFIO_USING_EXPERIMENTAL_FILESYSTEM && !LLFIO_DISABLE_USING_EXPERIMENTAL_FILESYSTEM_WARNING
#ifdef _MSC_VER
#pragma message( \
"WARNING: LLFIO is using the experimental Filesystem TS instead of the standard Filesystem, there are many corner case surprises in the former! Support for the Experimental Filesystem TS is expected to be deprecated at some point, and C++ 17 shall become the minimum required for LLFIO.")
#else
#warning WARNING: LLFIO is using the experimental Filesystem TS instead of the standard Filesystem, there are many corner case surprises in the former! Support for the Experimental Filesystem TS is expected to be deprecated at some point, and C++ 17 shall become the minimum required for LLFIO.
#endif
#endif
LLFIO_V2_NAMESPACE_BEGIN

struct path_hasher
{
size_t operator()(const filesystem::path &p) const { return std::hash<filesystem::path::string_type>()(p.native()); }
Expand Down Expand Up @@ -370,9 +304,9 @@ LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::span;
LLFIO_V2_NAMESPACE_END
// Bring in an optional implementation
#include "quickcpplib/optional.hpp"
#include <optional>
LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::optional;
template <class T> using optional = std::optional<T>;
LLFIO_V2_NAMESPACE_END
// Bring in a byte implementation
#include "quickcpplib/byte.hpp"
Expand All @@ -381,9 +315,10 @@ using QUICKCPPLIB_NAMESPACE::byte::byte;
using QUICKCPPLIB_NAMESPACE::byte::to_byte;
LLFIO_V2_NAMESPACE_END
// Bring in a string_view implementation
#include "quickcpplib/string_view.hpp"
#include <string_view>
LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::string_view;
template <class CharT, class Traits = std::char_traits<CharT>> using basic_string_view = std::basic_string_view<CharT, Traits>;
using std::string_view;
LLFIO_V2_NAMESPACE_END
// Bring in a function_ptr implementation
#include "quickcpplib/function_ptr.hpp"
Expand Down Expand Up @@ -424,9 +359,9 @@ using spinlock = QUICKCPPLIB_NAMESPACE::configurable_spinlock::spinlock<uintptr_
using QUICKCPPLIB_NAMESPACE::configurable_spinlock::lock_guard;
LLFIO_V2_NAMESPACE_END
// Bring in a memory resource implementation
#include "quickcpplib/memory_resource.hpp"
#include <memory_resource>
LLFIO_V2_NAMESPACE_BEGIN
namespace pmr = QUICKCPPLIB_NAMESPACE::pmr;
namespace pmr = std::pmr;
LLFIO_V2_NAMESPACE_END


Expand Down
2 changes: 1 addition & 1 deletion include/llfio/v2.0/detail/impl/windows/fs_handle.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ LLFIO_HEADERS_ONLY_FUNC_SPEC result<filesystem::path> to_win32_path(const fs_han
{
// Are any segments of the filename a reserved name?
static
#if(_HAS_CXX17 || __cplusplus >= 201700) && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20170519) // libstdc++'s string_view is missing constexpr
#if(!defined(__GLIBCXX__) || __GLIBCXX__ > 20170519) // libstdc++'s string_view is missing constexpr
constexpr
#endif
const wstring_view reserved_names[] = {L"\\CON\\", L"\\PRN\\", L"\\AUX\\", L"\\NUL\\", L"\\COM1\\", L"\\COM2\\", L"\\COM3\\", L"\\COM4\\",
Expand Down
Loading

0 comments on commit 9ba669e

Please sign in to comment.